diff --git a/rmw/CMakeLists.txt b/rmw/CMakeLists.txt index ef5cb55f..b7a665ed 100644 --- a/rmw/CMakeLists.txt +++ b/rmw/CMakeLists.txt @@ -29,6 +29,7 @@ set(rmw_sources "src/allocators.c" "src/convert_rcutils_ret_to_rmw_ret.c" "src/discovery_options.c" + "src/enclave.c" "src/event.c" "src/init.c" "src/init_options.c" diff --git a/rmw/include/rmw/enclave.h b/rmw/include/rmw/enclave.h new file mode 100644 index 00000000..accdab22 --- /dev/null +++ b/rmw/include/rmw/enclave.h @@ -0,0 +1,69 @@ +// Copyright 2025 Sony Group Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef RMW__ENCLAVE_H_ +#define RMW__ENCLAVE_H_ + +#include "rcutils/allocator.h" + +#include "rmw/macros.h" +#include "rmw/ret_types.h" +#include "rmw/visibility_control.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/// Perform a deep copy of the enclave options from src into dst using the +/// given allocator. +/** + * The dst will be left with an owned copy of the enclave whose + * string values match the src. + * If successful, src and dst will evaluate as equal. + * + * \param[in] src enclave options to be copied. + * \param[in] allocator to use. + * \param[out] dst Destination options to use. + * \return RMW_RET_OK if success. + * \return RMW_RET_INVALID_ARGUMENT if the src, dst or allocator is null. + * \return RMW_RET_BAD_ALLOC if allocation fails. + */ +RMW_PUBLIC +RMW_WARN_UNUSED +rmw_ret_t +rmw_enclave_options_copy( + const char * src, + const rcutils_allocator_t * allocator, + char ** dst); + +/// Destructor for enclave options +/** + * \param[in] enclave_options to destroy + * \param[in] allocator to be used for destruction. + * \return RMW_RET_OK if success. + * \return RMW_RET_INVALID_ARGUMENT if allocator is invalid + * or enclave_options is null. + */ +RMW_PUBLIC +rmw_ret_t +rmw_enclave_options_fini( + char * enclave_options, + const rcutils_allocator_t * allocator +); +#ifdef __cplusplus +} +#endif + +#endif // RMW__ENCLAVE_H_ diff --git a/rmw/include/rmw/init_options.h b/rmw/include/rmw/init_options.h index 1844b8e0..040c3431 100644 --- a/rmw/include/rmw/init_options.h +++ b/rmw/include/rmw/init_options.h @@ -25,6 +25,7 @@ extern "C" #include "rcutils/allocator.h" #include "rmw/discovery_options.h" #include "rmw/domain_id.h" +#include "rmw/enclave.h" #include "rmw/macros.h" #include "rmw/ret_types.h" #include "rmw/security_options.h" diff --git a/rmw/src/enclave.c b/rmw/src/enclave.c new file mode 100644 index 00000000..5457a3d3 --- /dev/null +++ b/rmw/src/enclave.c @@ -0,0 +1,53 @@ +// Copyright 2025 Sony Group Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + +#include "rcutils/allocator.h" +#include "rcutils/strdup.h" + +#include "rmw/enclave.h" +#include "rmw/error_handling.h" + +rmw_ret_t +rmw_enclave_options_copy( + const char * src, + const rcutils_allocator_t * allocator, + char ** dst) +{ + RMW_CHECK_ARGUMENT_FOR_NULL(src, RMW_RET_INVALID_ARGUMENT); + RMW_CHECK_ARGUMENT_FOR_NULL(dst, RMW_RET_INVALID_ARGUMENT); + RCUTILS_CHECK_ALLOCATOR(allocator, return RMW_RET_INVALID_ARGUMENT); + + char * new_enclave = rcutils_strdup(src, *allocator); + if (!new_enclave) { + RMW_SET_ERROR_MSG("failed to copy enclave options"); + return RMW_RET_BAD_ALLOC; + } + *dst = new_enclave; + return RMW_RET_OK; +} + +rmw_ret_t +rmw_enclave_options_fini( + char * enclave_options, + const rcutils_allocator_t * allocator) +{ + RMW_CHECK_ARGUMENT_FOR_NULL(enclave_options, RMW_RET_INVALID_ARGUMENT); + RCUTILS_CHECK_ALLOCATOR(allocator, return RMW_RET_INVALID_ARGUMENT); + + allocator->deallocate(enclave_options, allocator->state); + return RMW_RET_OK; +} diff --git a/rmw/test/CMakeLists.txt b/rmw/test/CMakeLists.txt index 3e4f0b17..d7d08910 100644 --- a/rmw/test/CMakeLists.txt +++ b/rmw/test/CMakeLists.txt @@ -38,6 +38,15 @@ if(TARGET test_event) target_link_libraries(test_event ${PROJECT_NAME}) endif() +ament_add_gmock(test_enclave + test_enclave.cpp + # Append the directory of librmw so it is found at test time. + APPEND_LIBRARY_DIRS "$" +) +if(TARGET test_enclave) + target_link_libraries(test_enclave ${PROJECT_NAME}) +endif() + ament_add_gmock(test_init_options test_init_options.cpp # Append the directory of librmw so it is found at test time. diff --git a/rmw/test/test_enclave.cpp b/rmw/test/test_enclave.cpp new file mode 100644 index 00000000..77b6bc13 --- /dev/null +++ b/rmw/test/test_enclave.cpp @@ -0,0 +1,49 @@ +// Copyright 2025 Sony Group Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gmock/gmock.h" + +#include "./time_bomb_allocator_testing_utils.h" +#include "rmw/enclave.h" +#include "rmw/error_handling.h" + +TEST(rmw_enclave_options, options_copy) { + rcutils_allocator_t allocator = rcutils_get_default_allocator(); + char * dst = nullptr; + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_enclave_options_copy(nullptr, &allocator, &dst)); + rmw_reset_error(); + + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_enclave_options_copy("src", nullptr, &dst)); + rmw_reset_error(); + + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_enclave_options_copy("src", &allocator, nullptr)); + rmw_reset_error(); + + EXPECT_EQ(RMW_RET_OK, rmw_enclave_options_copy("src", &allocator, &dst)); + EXPECT_STREQ(dst, "src"); + EXPECT_EQ(RMW_RET_OK, rmw_enclave_options_fini(dst, &allocator)); +} + +TEST(rmw_enclave_options, options_fini) { + rcutils_allocator_t allocator = rcutils_get_default_allocator(); + char * dst = nullptr; + EXPECT_EQ(RMW_RET_OK, rmw_enclave_options_copy("src", &allocator, &dst)); + EXPECT_STREQ(dst, "src"); + + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_enclave_options_fini(nullptr, &allocator)); + + EXPECT_EQ(RMW_RET_INVALID_ARGUMENT, rmw_enclave_options_fini(dst, nullptr)); + + EXPECT_EQ(RMW_RET_OK, rmw_enclave_options_fini(dst, &allocator)); +}