Skip to content

Commit

Permalink
Merge pull request eclipse-iceoryx#2254 from elBoberido/iox-1616-use-…
Browse files Browse the repository at this point in the history
…thread-safe-strerror_r

iox-eclipse-iceoryx#1616 Handle 'strerror_r' idiosyncrasies in the platform layer
  • Loading branch information
elBoberido authored Apr 14, 2024
2 parents b505025 + 671af92 commit 0795a5c
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 9 deletions.
1 change: 1 addition & 0 deletions doc/website/release-notes/iceoryx-unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
- Activate clang-tidy for all the code in iceoryx_hoofs [#2184](https://github.com/eclipse-iceoryx/iceoryx/issues/2184)
- Split `iceoryx_hoofs` into logical modules [#1391](https://github.com/eclipse-iceoryx/iceoryx/issues/1391)
- Create a flat include structure for `iceoryx_hoofs` [#1593](https://github.com/eclipse-iceoryx/iceoryx/issues/1593)
- Handle 'strerror_r' idiosyncrasies in the platform layer [#1616](https://github.com/eclipse-iceoryx/iceoryx/issues/1616)

**Workflow:**

Expand Down
3 changes: 2 additions & 1 deletion iceoryx_hoofs/posix/design/include/iox/detail/posix_call.inl
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ inline string<POSIX_CALL_ERROR_STRING_SIZE> PosixCallResult<T>::getHumanReadable
/// NOLINTJUSTIFICATION needed by POSIX function which is wrapped here
/// NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays)
char buffer[POSIX_CALL_ERROR_STRING_SIZE];
return detail::errorLiteralToString(strerror_r(errnum, &buffer[0], POSIX_CALL_ERROR_STRING_SIZE), &buffer[0]);
return string<POSIX_CALL_ERROR_STRING_SIZE>(TruncateToCapacity,
iox_gnu_strerror_r(errnum, &buffer[0], POSIX_CALL_ERROR_STRING_SIZE));
}

template <typename ReturnType, typename... FunctionArguments>
Expand Down
8 changes: 4 additions & 4 deletions iceoryx_hoofs/posix/design/include/iox/posix_call.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
#ifndef IOX_HOOFS_POSIX_DESIGN_POSIX_CALL_HPP
#define IOX_HOOFS_POSIX_DESIGN_POSIX_CALL_HPP

#include "iceoryx_platform/string.hpp"
#include "iox/algorithm.hpp"
#include "iox/attributes.hpp"
#include "iox/expected.hpp"
#include "iox/string.hpp"

#include <cstdint>
#include <cstring>

namespace iox
{
Expand All @@ -40,7 +40,7 @@ struct PosixCallResult
{
PosixCallResult() noexcept = default;

/// @brief returns the result of std::strerror(errnum) which acquires a
/// @brief returns the result of strerror_r(errnum, ...) which acquires a
/// human readable error string
string<POSIX_CALL_ERROR_STRING_SIZE> getHumanReadableErrnum() const noexcept;

Expand Down Expand Up @@ -194,12 +194,12 @@ class [[nodiscard]] PosixCallBuilder
/// .and_then([](auto & result){
/// IOX_LOG(INFO, result.value); // return value of sem_timedwait
/// IOX_LOG(INFO, result.errno); // errno which was set by sem_timedwait
/// IOX_LOG(INFO, result.getHumanReadableErrnum()); // get string returned by strerror(errno)
/// IOX_LOG(INFO, result.getHumanReadableErrnum()); // get string returned by strerror_r(errno, ...)
/// })
/// .or_else([](auto & result){
/// IOX_LOG(INFO, result.value); // return value of sem_timedwait
/// IOX_LOG(INFO, result.errno); // errno which was set by sem_timedwait
/// IOX_LOG(INFO, result.getHumanReadableErrnum()); // get string returned by strerror(errno)
/// IOX_LOG(INFO, result.getHumanReadableErrnum()); // get string returned by strerror_r(errno, ...)
/// })
///
/// // when your posix call signals failure with one specific return value use
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2024 by ekxide IO GmbH. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_PLATFORM_GENERIC_STRING_HPP
#define IOX_PLATFORM_GENERIC_STRING_HPP

#include <cstring>

/// @brief Implements the GNU version of 'strerror_r'
/// @param[in] errnum the error code to be converted to a string
/// @param[out] buf the buffer to store the error message in case there is no static error message available for the
/// given error code
/// @param[in] buflen the length of the buffer to store the error message
/// @return a pointer to a string containing the error message; this is either a pointer to an immutable static string
/// or the provided buffer
char* iox_gnu_strerror_r(int errnum, char* buf, size_t buflen);

#endif // IOX_PLATFORM_GENERIC_STRING_HPP
26 changes: 26 additions & 0 deletions iceoryx_platform/generic/include/iceoryx_platform/string.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2024 by ekxide IO GmbH. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_PLATFORM_STRING_HPP
#define IOX_PLATFORM_STRING_HPP

#if __has_include("iceoryx_platform/override/string.hpp")
#include "iceoryx_platform/override/string.hpp"
#else
#include "iceoryx_platform/generic/string.hpp"
#endif // __has_include

#endif // IOX_PLATFORM_STRING_HPP
46 changes: 46 additions & 0 deletions iceoryx_platform/generic/source/string.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) 2024 by ekxide IO GmbH. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_platform/string.hpp"

#ifndef IOX_PLATFORM_OVERRIDE_STRING_ALL

#include <cerrno>

#ifndef IOX_PLATFORM_OVERRIDE_STRING_STRERROR_R

namespace
{
[[maybe_unused]] char* strerror_r_gnu_xsi_unificaton(const int returnCode [[maybe_unused]], char* buf)
{
return buf;
}

[[maybe_unused]] char* strerror_r_gnu_xsi_unificaton(char* msg, char* buf [[maybe_unused]])
{
return msg;
}

} // namespace

char* iox_gnu_strerror_r(int errnum, char* buf, size_t buflen)
{
return strerror_r_gnu_xsi_unificaton(strerror_r(errnum, buf, buflen), buf);
}

#endif

#endif
62 changes: 62 additions & 0 deletions iceoryx_platform/test/moduletests/test_platform_string.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) 2024 by ekxide IO GmbH. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_platform/string.hpp"

#include "test.hpp"

namespace
{
using namespace ::testing;

TEST(STRING_test, strerror_r_of_known_erron_works)
{
::testing::Test::RecordProperty("TEST_ID", "1fbf88c9-07c4-4959-9127-18a78db27c22");
constexpr size_t BUFFER_SIZE{1024};
char buf[BUFFER_SIZE];
buf[0] = 0;

auto* error_string = iox_gnu_strerror_r(ENOENT, &buf[0], BUFFER_SIZE);

EXPECT_THAT(error_string, StrEq("No such file or directory"));
}

TEST(STRING_test, strerror_r_of_unknown_error_works_when_buffer_is_large_enough)
{
::testing::Test::RecordProperty("TEST_ID", "92213d70-61b7-47dd-beac-c86ce25b6991");
constexpr size_t BUFFER_SIZE{1024};
char buf[BUFFER_SIZE];
buf[0] = 0;

auto* error_string = iox_gnu_strerror_r(123456789, &buf[0], BUFFER_SIZE);

// on Linux this is 'Unknown error 123456789', on macOS 'Unknown error: 123456789' and on Windows 'Unknown error'
EXPECT_THAT(error_string, HasSubstr("Unknown error"));
}

TEST(STRING_test, strerror_r_of_unknown_error_is_truncated_when_buffer_is_too_small)
{
::testing::Test::RecordProperty("TEST_ID", "1dbba291-575f-495b-a174-0859b79980b1");
constexpr size_t BUFFER_SIZE{10};
char buf[BUFFER_SIZE];
buf[0] = 0;

auto* error_string = iox_gnu_strerror_r(123456789, &buf[0], BUFFER_SIZE);

EXPECT_THAT(error_string, StrEq("Unknown e"));
}

} // namespace
24 changes: 24 additions & 0 deletions iceoryx_platform/win/include/iceoryx_platform/override/string.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2024 by ekxide IO GmbH. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#ifndef IOX_PLATFORM_WIN_OVERRIDE_STRING_HPP
#define IOX_PLATFORM_WIN_OVERRIDE_STRING_HPP

#define IOX_PLATFORM_OVERRIDE_STRING_STRERROR_R

#include "iceoryx_platform/generic/string.hpp"

#endif // IOX_PLATFORM_WIN_OVERRIDE_STRING_HPP
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,3 @@
#undef OPEN_EXISTING
#undef IGNORE
#undef OPTIONAL

/// @todo iox-#1616 required by posix but defined in libc header string.h
/// move it into the upcoming libc layer in platform
#define strerror_r(errnum, buf, buflen) strerror_s(buf, buflen, errnum)
23 changes: 23 additions & 0 deletions iceoryx_platform/win/source/string.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2024 by ekxide IO GmbH. All rights reserved.
//
// 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.
//
// SPDX-License-Identifier: Apache-2.0

#include "iceoryx_platform/string.hpp"

char* iox_gnu_strerror_r(int errnum, char* buf, size_t buflen)
{
strerror_s(buf, buflen, errnum);
return buf;
}

0 comments on commit 0795a5c

Please sign in to comment.