diff --git a/CMakeLists.txt b/CMakeLists.txt index 01aead30..8f61a09f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,19 @@ else() set(time_impl_c src/time_unix.c) endif() +if(RCUTILS_NO_FILESYSTEM) + add_compile_options(-DRCUTILS_NO_FILESYSTEM=1) +endif() + +if(RCUTILS_AVOID_DYNAMIC_ALLOCATION) + add_compile_options(-DRCUTILS_AVOID_DYNAMIC_ALLOCATION=1) +endif() + +configure_file ( + "${PROJECT_SOURCE_DIR}/include/rcutils/error_handling.h.in" + "${PROJECT_BINARY_DIR}/include/rcutils/error_handling.h" +) + set(rcutils_sources src/allocator.c src/array_list.c @@ -90,7 +103,8 @@ add_custom_command(OUTPUT include/rcutils/logging_macros.h VERBATIM ) list(APPEND rcutils_sources - include/rcutils/logging_macros.h) + include/rcutils/logging_macros.h + include/rcutils/error_handling.h) include_directories("${CMAKE_CURRENT_BINARY_DIR}/include") add_library( diff --git a/include/rcutils/allocator.h b/include/rcutils/allocator.h index 374f4018..bf4289bb 100644 --- a/include/rcutils/allocator.h +++ b/include/rcutils/allocator.h @@ -83,6 +83,21 @@ RCUTILS_WARN_UNUSED rcutils_allocator_t rcutils_get_zero_initialized_allocator(void); +/// Set rcutils default allocators. +/** + *
+ * Attribute | Adherence + * ------------------ | ------------- + * Allocates Memory | No + * Thread-Safe | Yes + * Uses Atomics | No + * Lock-Free | Yes + */ +RCUTILS_PUBLIC +RCUTILS_WARN_UNUSED +bool +rcutils_set_default_allocator(rcutils_allocator_t * allocator); + /// Return a properly initialized rcutils_allocator_t with default values. /** * This defaults to: diff --git a/include/rcutils/error_handling.h b/include/rcutils/error_handling.h.in similarity index 95% rename from include/rcutils/error_handling.h rename to include/rcutils/error_handling.h.in index 610e4f1b..a248a5d3 100644 --- a/include/rcutils/error_handling.h +++ b/include/rcutils/error_handling.h.in @@ -39,14 +39,19 @@ extern "C" #include "rcutils/types/rcutils_ret.h" #include "rcutils/visibility_control.h" -#ifdef __STDC_LIB_EXT1__ +#cmakedefine RCUTILS_NO_FILESYSTEM +#cmakedefine RCUTILS_AVOID_DYNAMIC_ALLOCATION + +#if defined(__STDC_LIB_EXT1__) && !defined(RCUTILS_NO_FILESYSTEM) // Limit the buffer size in the `fwrite` call to give an upper bound to buffer overrun in the case // of non-null terminated `msg`. #define RCUTILS_SAFE_FWRITE_TO_STDERR(msg) \ do {fwrite(msg, sizeof(char), strnlen_s(msg, 4096), stderr);} while (0) -#else +#elif !defined(RCUTILS_NO_FILESYSTEM) #define RCUTILS_SAFE_FWRITE_TO_STDERR(msg) \ do {fwrite(msg, sizeof(char), strlen(msg), stderr);} while (0) +#else + #define RCUTILS_SAFE_FWRITE_TO_STDERR(msg) #endif // fixed constraints @@ -197,8 +202,12 @@ rcutils_set_error_state(const char * error_string, const char * file, size_t lin * * \param[in] msg The error message to be set. */ +#ifdef RCUTILS_AVOID_DYNAMIC_ALLOCATION + #define RCUTILS_SET_ERROR_MSG(msg) +#else #define RCUTILS_SET_ERROR_MSG(msg) \ do {rcutils_set_error_state(msg, __FILE__, __LINE__);} while (0) +#endif // RCUTILS_AVOID_DYNAMIC_ALLOCATION /// Set the error message using a format string and format arguments. /** @@ -209,6 +218,9 @@ rcutils_set_error_state(const char * error_string, const char * file, size_t lin * \param[in] format_string The string to be used as the format of the error message. * \param[in] ... Arguments for the format string. */ +#ifdef RCUTILS_AVOID_DYNAMIC_ALLOCATION + #define RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(format_string, ...) +#else #define RCUTILS_SET_ERROR_MSG_WITH_FORMAT_STRING(format_string, ...) \ do { \ char output_msg[RCUTILS_ERROR_MESSAGE_MAX_LENGTH]; \ @@ -219,6 +231,8 @@ rcutils_set_error_state(const char * error_string, const char * file, size_t lin RCUTILS_SET_ERROR_MSG(output_msg); \ } \ } while (0) +#endif // RCUTILS_AVOID_DYNAMIC_ALLOCATION + /// Return `true` if the error is set, otherwise `false`. RCUTILS_PUBLIC diff --git a/src/allocator.c b/src/allocator.c index 92ef82d0..ab1972c7 100644 --- a/src/allocator.c +++ b/src/allocator.c @@ -69,16 +69,31 @@ rcutils_get_zero_initialized_allocator(void) return zero_allocator; } -rcutils_allocator_t -rcutils_get_default_allocator() -{ - static rcutils_allocator_t default_allocator = { +static rcutils_allocator_t default_allocator = { .allocate = __default_allocate, .deallocate = __default_deallocate, .reallocate = __default_reallocate, .zero_allocate = __default_zero_allocate, .state = NULL, }; + +bool +rcutils_set_default_allocator(rcutils_allocator_t * allocator){ + if (rcutils_allocator_is_valid(allocator)) + { + default_allocator.allocate = allocator->allocate; + default_allocator.deallocate = allocator->deallocate; + default_allocator.reallocate = allocator->reallocate; + default_allocator.zero_allocate = allocator->zero_allocate; + default_allocator.state = NULL; + return true; + } + return false; +} + +rcutils_allocator_t +rcutils_get_default_allocator() +{ return default_allocator; } diff --git a/src/filesystem.c b/src/filesystem.c index 0c360614..dd55e409 100644 --- a/src/filesystem.c +++ b/src/filesystem.c @@ -21,7 +21,9 @@ extern "C" #include #include #include +#ifndef RCUTILS_NO_FILESYSTEM #include +#endif #ifndef _WIN32 #include #else @@ -30,6 +32,7 @@ extern "C" #include "rcutils/format_string.h" #include "rcutils/repl_str.h" +#include "rcutils/error_handling.h" #ifdef _WIN32 # define RCUTILS_PATH_DELIMITER "\\" @@ -40,6 +43,10 @@ extern "C" bool rcutils_get_cwd(char * buffer, size_t max_length) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else if (NULL == buffer) { return false; } @@ -53,11 +60,16 @@ rcutils_get_cwd(char * buffer, size_t max_length) } #endif // _WIN32 return true; +#endif // _RCUTILS_NO_FILESYSTEM } bool rcutils_is_directory(const char * abs_path) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else struct stat buf; if (stat(abs_path, &buf) < 0) { return false; @@ -67,11 +79,16 @@ rcutils_is_directory(const char * abs_path) #else return S_ISDIR(buf.st_mode); #endif // _WIN32 +#endif // _RCUTILS_NO_FILESYSTEM } bool rcutils_is_file(const char * abs_path) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else struct stat buf; if (stat(abs_path, &buf) < 0) { return false; @@ -81,21 +98,31 @@ rcutils_is_file(const char * abs_path) #else return S_ISREG(buf.st_mode); #endif // _WIN32 +#endif // _RCUTILS_NO_FILESYSTEM } bool rcutils_exists(const char * abs_path) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else struct stat buf; if (stat(abs_path, &buf) < 0) { return false; } return true; +#endif // _RCUTILS_NO_FILESYSTEM } bool rcutils_is_readable(const char * abs_path) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else struct stat buf; if (stat(abs_path, &buf) < 0) { return false; @@ -108,11 +135,16 @@ rcutils_is_readable(const char * abs_path) return false; } return true; +#endif // _RCUTILS_NO_FILESYSTEM } bool rcutils_is_writable(const char * abs_path) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else struct stat buf; if (stat(abs_path, &buf) < 0) { return false; @@ -125,11 +157,16 @@ rcutils_is_writable(const char * abs_path) return false; } return true; +#endif // _RCUTILS_NO_FILESYSTEM } bool rcutils_is_readable_and_writable(const char * abs_path) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else struct stat buf; if (stat(abs_path, &buf) < 0) { return false; @@ -144,6 +181,7 @@ rcutils_is_readable_and_writable(const char * abs_path) return false; } return true; +#endif // _RCUTILS_NO_FILESYSTEM } char * diff --git a/src/security_directory.c b/src/security_directory.c index c4208931..4bcba2d7 100644 --- a/src/security_directory.c +++ b/src/security_directory.c @@ -23,7 +23,11 @@ # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wembedded-directive" #endif + +#ifndef RCUTILS_NO_FILESYSTEM #include "tinydir/tinydir.h" +#endif + #ifdef __clang__ # pragma clang diagnostic pop #endif @@ -89,7 +93,11 @@ static bool get_best_matching_directory( const char * node_name, char * matched_name) { - size_t max_match_length = 0; +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else +size_t max_match_length = 0; tinydir_dir dir; if (NULL == base_dir || NULL == node_name || NULL == matched_name) { return false; @@ -119,6 +127,7 @@ static bool get_best_matching_directory( cleanup: tinydir_close(&dir); return max_match_length > 0; +#endif // _RCUTILS_NO_FILESYSTEM } char * exact_match_lookup( @@ -154,6 +163,10 @@ char * prefix_match_lookup( const char * ros_secure_root_env, const rcutils_allocator_t * allocator) { +#ifdef RCUTILS_NO_FILESYSTEM + RCUTILS_SET_ERROR_MSG("not available filesystem"); + return false; +#else // Perform longest prefix match for the node's name in directory /. char * node_secure_root = NULL; char matched_dir[_TINYDIR_FILENAME_MAX] = {0}; @@ -171,6 +184,7 @@ char * prefix_match_lookup( allocator->deallocate(base_lookup_dir, allocator->state); } return node_secure_root; +#endif // _RCUTILS_NO_FILESYSTEM } char * rcutils_get_secure_root(