From f6aecb29da20ad21dbbc84210db04ad7116ea5ab Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 4 Apr 2023 16:41:06 +0200 Subject: [PATCH 01/30] iox-#1962 Introduce posix file wrapper --- iceoryx_hoofs/BUILD.bazel | 2 + iceoryx_hoofs/CMakeLists.txt | 3 + .../iox/detail/file_management_interface.inl | 13 ++ .../include/iox/file_management_interface.hpp | 7 + .../source/file_management_interface.cpp | 6 + .../posix/filesystem/include/iox/file.hpp | 103 +++++++++++++++ .../posix/filesystem/source/file.cpp | 121 ++++++++++++++++++ 7 files changed, 255 insertions(+) create mode 100644 iceoryx_hoofs/posix/filesystem/include/iox/file.hpp create mode 100644 iceoryx_hoofs/posix/filesystem/source/file.cpp diff --git a/iceoryx_hoofs/BUILD.bazel b/iceoryx_hoofs/BUILD.bazel index 931a0f60ad..393ae70224 100644 --- a/iceoryx_hoofs/BUILD.bazel +++ b/iceoryx_hoofs/BUILD.bazel @@ -34,6 +34,7 @@ cc_library( "filesystem/source/*.cpp", "memory/source/*.cpp", "posix/design/source/*.cpp", + "posix/filesystem/source/*.cpp", "posix/time/source/*.cpp", "posix/vocabulary/source/*.cpp", "primitives/source/*.cpp", @@ -56,6 +57,7 @@ cc_library( "legacy/include/", "memory/include/", "posix/design/include/", + "posix/filesystem/include/", "posix/time/include/", "posix/vocabulary/include/", "primitives/include/", diff --git a/iceoryx_hoofs/CMakeLists.txt b/iceoryx_hoofs/CMakeLists.txt index 98c7ecd89a..b972bfaa2e 100644 --- a/iceoryx_hoofs/CMakeLists.txt +++ b/iceoryx_hoofs/CMakeLists.txt @@ -61,6 +61,7 @@ iox_add_library( ${PROJECT_SOURCE_DIR}/reporting/include ${PROJECT_SOURCE_DIR}/posix/design/include + ${PROJECT_SOURCE_DIR}/posix/filesystem/include ${PROJECT_SOURCE_DIR}/posix/time/include ${PROJECT_SOURCE_DIR}/posix/vocabulary/include @@ -81,6 +82,7 @@ iox_add_library( reporting/include/ posix/design/include/ + posix/filesystem/include/ posix/time/include/ posix/vocabulary/include/ FILES @@ -116,6 +118,7 @@ iox_add_library( utility/source/unique_id.cpp posix/design/source/file_management_interface.cpp + posix/filesystem/source/file.cpp posix/time/source/adaptive_wait.cpp posix/time/source/deadline_timer.cpp posix/vocabulary/source/file_name.cpp diff --git a/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl b/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl index 783a5060c1..b66df4ea50 100644 --- a/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl +++ b/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl @@ -76,6 +76,19 @@ FileManagementInterface::set_permissions(const access_rights permission return iox::success<>(); } + +template +inline expected FileManagementInterface::get_size() const noexcept +{ + const auto& derived_this = *static_cast(this); + auto result = details::get_file_status(derived_this.getFileHandle()); + if (result.has_error()) + { + return iox::error(result.get_error()); + } + + return iox::success(result->st_size); +} } // namespace iox #endif diff --git a/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp b/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp index b34bd1dbe1..c461ed9a56 100644 --- a/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp +++ b/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp @@ -84,6 +84,9 @@ class Ownership /// with existing user and group static optional from_user_and_group(const UserName& user_name, const GroupName& group_name) noexcept; + /// @brief Returns the user and group owner of the current process. + static Ownership from_process() noexcept; + private: template friend struct FileManagementInterface; @@ -125,6 +128,10 @@ struct FileManagementInterface /// @param[in] permissions the new permissions of the file descriptor /// @return On failure a 'FileSetPermissionError' describing the error. expected set_permissions(const access_rights permissions) noexcept; + + /// @brief Returns the size of the corresponding file. + /// @return On failure a 'FileStatError' describing the error otherwise the size. + expected get_size() const noexcept; }; } // namespace iox diff --git a/iceoryx_hoofs/posix/design/source/file_management_interface.cpp b/iceoryx_hoofs/posix/design/source/file_management_interface.cpp index 5b801c755f..471e97aed9 100644 --- a/iceoryx_hoofs/posix/design/source/file_management_interface.cpp +++ b/iceoryx_hoofs/posix/design/source/file_management_interface.cpp @@ -138,6 +138,12 @@ optional Ownership::from_user_and_group(const UserName& user_name, co return Ownership(user.getID(), group.getID()); } +Ownership Ownership::from_process() noexcept +{ + return Ownership(posix::PosixUser::getUserOfCurrentProcess().getID(), + posix::PosixGroup::getGroupOfCurrentProcess().getID()); +} + Ownership::Ownership(const uid_t uid, const gid_t gid) noexcept : m_uid{uid} , m_gid{gid} diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp new file mode 100644 index 0000000000..a6ca8bfd39 --- /dev/null +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -0,0 +1,103 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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_hoofs/posix_wrapper/types.hpp" +#include "iox/builder.hpp" +#include "iox/file_management_interface.hpp" +#include "iox/file_path.hpp" +#include "iox/filesystem.hpp" + +#ifndef IOX_HOOFS_POSIX_FILESYSTEM_FILE_HPP +#define IOX_HOOFS_POSIX_FILESYSTEM_FILE_HPP + +namespace iox +{ +using AccessMode = posix::AccessMode; + +enum class FileCreationError +{ + PermissionDenied, + Interrupt, + IsDirectory, + TooManySymbolicLinksEncountered, + ProcessLimitOfOpenFileDescriptorsReached, + SystemLimitOfOpenFileDescriptorsReached, + DoesNotExist, + AlreadyExists, + InsufficientMemory, + FileTooLarge, + CurrentlyInUse, + UnknownError +}; + +enum class FileReadError +{ +}; + +enum class FileWriteError +{ +}; + +enum class FileAccessError +{ +}; + +enum class FileRemoveError +{ +}; + +class File : public FileManagementInterface +{ + public: + int getFileHandle() const noexcept; + + expected read(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + expected + read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + + expected write(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + expected + write_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + + static expected does_exist(const FilePath& file) noexcept; + static expected remove(const FilePath& file) noexcept; + + private: + friend class FileBuilder; + explicit File(const int file_descriptor) noexcept; + + private: + int file_descriptor{0}; +}; + +class FileBuilder +{ + IOX_BUILDER_PARAMETER(FilePath, name, FilePath::create("").value()) + IOX_BUILDER_PARAMETER(Ownership, owner, Ownership::from_process()) + IOX_BUILDER_PARAMETER(access_rights, permissions, perms::owner_read) + IOX_BUILDER_PARAMETER(AccessMode, access_mode, AccessMode::READ_ONLY) + + public: + expected create(const posix::OpenMode open_mode) noexcept; + expected open() noexcept; + + private: + expected open_impl(const bool print_error_on_non_existing_file, + const posix::OpenMode open_mode) noexcept; +}; +} // namespace iox + +#endif diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp new file mode 100644 index 0000000000..4628cbad95 --- /dev/null +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -0,0 +1,121 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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 "iox/file.hpp" +#include "iceoryx_hoofs/posix_wrapper/posix_call.hpp" +#include "iceoryx_platform/attributes.hpp" +#include "iceoryx_platform/fcntl.hpp" + +namespace iox +{ +expected FileBuilder::create(const posix::OpenMode open_mode) noexcept +{ + switch (open_mode) + { + case posix::OpenMode::OPEN_EXISTING: + { + return this->open(); + } + case posix::OpenMode::PURGE_AND_CREATE: + { + File::remove(m_name); + IOX_FALLTHROUGH + } + case posix::OpenMode::EXCLUSIVE_CREATE: + { + return this->open_impl(true, posix::OpenMode::EXCLUSIVE_CREATE); + } + case posix::OpenMode::OPEN_OR_CREATE: + { + auto result = this->open_impl(false, posix::OpenMode::OPEN_EXISTING); + if (!result.has_error() || result.get_error() != FileCreationError::DoesNotExist) + { + return result; + } + + return this->open_impl(true, posix::OpenMode::EXCLUSIVE_CREATE); + } + } +} + +expected FileBuilder::open_impl(const bool print_error_on_non_existing_file, + const posix::OpenMode open_mode) noexcept +{ + auto result = posix::posixCall(iox_open)(m_name.as_string().c_str(), + posix::convertToOflags(m_access_mode, open_mode), + static_cast(m_permissions.value())) + .failureReturnValue(-1) + .evaluate(); + + if (!result.has_error()) + { + return iox::success(File(result.value().value)); + } + + switch (result.get_error().errnum) + { + case EACCES: + IOX_LOG(ERROR) << "Unable to open/create file due to insufficient permissions."; + return iox::error(FileCreationError::PermissionDenied); + case EPERM: + IOX_LOG(ERROR) << "Unable to open/create file due to insufficient permissions."; + return iox::error(FileCreationError::PermissionDenied); + case EINTR: + IOX_LOG(ERROR) << "Unable to open/create file since an interrupt signal was received."; + return iox::error(FileCreationError::Interrupt); + case EISDIR: + IOX_LOG(ERROR) << "Unable to open/create file since it is actually a directory."; + return iox::error(FileCreationError::IsDirectory); + case ELOOP: + IOX_LOG(ERROR) << "Unable to open/create file since too many symbolic links were encountered."; + return iox::error(FileCreationError::TooManySymbolicLinksEncountered); + case EMFILE: + IOX_LOG(ERROR) << "Unable to open/create file since the process limit of open file descriptors was reached."; + return iox::error(FileCreationError::ProcessLimitOfOpenFileDescriptorsReached); + case ENFILE: + IOX_LOG(ERROR) << "Unable to open/create file since the system limit of open file descriptors was reached."; + return iox::error(FileCreationError::SystemLimitOfOpenFileDescriptorsReached); + case ENOENT: + if (print_error_on_non_existing_file) + { + IOX_LOG(ERROR) << "Unable to open file since the file does not exist."; + } + return iox::error(FileCreationError::DoesNotExist); + case ENOMEM: + IOX_LOG(ERROR) << "Unable to open/create file due to insufficient memory."; + return iox::error(FileCreationError::InsufficientMemory); + case EOVERFLOW: + IOX_LOG(ERROR) << "Unable to open/create file since it is too large."; + return iox::error(FileCreationError::FileTooLarge); + case ETXTBSY: + IOX_LOG(ERROR) << "Unable to open/create file since it is currently in use."; + return iox::error(FileCreationError::CurrentlyInUse); + case EEXIST: + IOX_LOG(ERROR) << "Unable to create file since it already exists."; + return iox::error(FileCreationError::AlreadyExists); + default: + IOX_LOG(ERROR) << "Unable to open/create file due to insufficient permissions."; + return iox::error(FileCreationError::UnknownError); + } + + return iox::success(File(result->value)); +} + +expected FileBuilder::open() noexcept +{ + return this->open_impl(true, posix::OpenMode::OPEN_EXISTING); +} +} // namespace iox From 920ba25161fb7723f6edddedd9b66d65018e98c5 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 4 Apr 2023 17:22:41 +0200 Subject: [PATCH 02/30] iox-#1962 Implement function to check if file exists Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 7 +++- .../posix/filesystem/source/file.cpp | 40 +++++++++++++++++++ .../linux/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/linux/source/unistd.cpp | 5 +++ .../mac/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/mac/source/unistd.cpp | 5 +++ .../qnx/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/qnx/source/unistd.cpp | 5 +++ .../unix/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/unix/source/unistd.cpp | 5 +++ .../win/include/iceoryx_platform/unistd.hpp | 4 ++ iceoryx_platform/win/source/unistd.cpp | 7 +++- 12 files changed, 80 insertions(+), 2 deletions(-) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index a6ca8bfd39..e5d433b174 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -53,6 +53,11 @@ enum class FileWriteError enum class FileAccessError { + InsufficientPermissions, + TooManySymbolicLinksEncountered, + IoFailure, + InsufficientKernelMemory, + UnknownError }; enum class FileRemoveError @@ -80,7 +85,7 @@ class File : public FileManagementInterface explicit File(const int file_descriptor) noexcept; private: - int file_descriptor{0}; + int m_file_descriptor{0}; }; class FileBuilder diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 4628cbad95..746b33580a 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -118,4 +118,44 @@ expected FileBuilder::open() noexcept { return this->open_impl(true, posix::OpenMode::OPEN_EXISTING); } + +File::File(const int file_descriptor) noexcept + : m_file_descriptor{file_descriptor} +{ +} + +expected File::does_exist(const FilePath& file) noexcept +{ + auto result = posix::posixCall(iox_access)(file.as_string().c_str(), F_OK).failureReturnValue(-1).evaluate(); + + if (!result.has_error()) + { + return iox::success(true); + } + + switch (result.get_error().errnum) + { + case EACCES: + IOX_LOG(ERROR) << "Unable to determine if file exists due to insufficient permissions."; + return iox::error(FileAccessError::InsufficientPermissions); + case ENOENT: + return iox::success(false); + case ELOOP: + IOX_LOG(ERROR) << "Unable to determine if file exists due to too many symbolic links."; + return iox::error(FileAccessError::TooManySymbolicLinksEncountered); + case EIO: + IOX_LOG(ERROR) << "Unable to determine if file exists due to an IO failure."; + return iox::error(FileAccessError::IoFailure); + case ENOMEM: + IOX_LOG(ERROR) << "Unable to determine if file exists due insufficient kernel memory."; + return iox::error(FileAccessError::InsufficientKernelMemory); + default: + IOX_LOG(ERROR) << "Unable to determine if file exists since an unknown error occurred."; + return iox::error(FileAccessError::UnknownError); + } +} + +expected File::remove(const FilePath& file) noexcept +{ +} } // namespace iox diff --git a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp index ab712280d0..6300a43756 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp @@ -21,5 +21,6 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); +int iox_access(const char* pathname, int mode); #endif // IOX_HOOFS_LINUX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index 3d6ca37e12..652d53fc08 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -27,3 +27,8 @@ int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); } + +int iox_access(const char* pathname, int mode) +{ + return access(pathname, mode); +} diff --git a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp index 0eee25a0de..9b00990918 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp @@ -21,4 +21,5 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); +int iox_access(const char* pathname, int mode); #endif // IOX_HOOFS_MAC_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/mac/source/unistd.cpp b/iceoryx_platform/mac/source/unistd.cpp index 85105d168c..89db6a0205 100644 --- a/iceoryx_platform/mac/source/unistd.cpp +++ b/iceoryx_platform/mac/source/unistd.cpp @@ -26,3 +26,8 @@ int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); } + +int iox_access(const char* pathname, int mode) +{ + return access(pathname, mode); +} diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp index 6c5e968ae7..6628ec5585 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp @@ -21,5 +21,6 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); +int iox_access(const char* pathname, int mode); #endif // IOX_HOOFS_QNX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/qnx/source/unistd.cpp b/iceoryx_platform/qnx/source/unistd.cpp index 85105d168c..89db6a0205 100644 --- a/iceoryx_platform/qnx/source/unistd.cpp +++ b/iceoryx_platform/qnx/source/unistd.cpp @@ -26,3 +26,8 @@ int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); } + +int iox_access(const char* pathname, int mode) +{ + return access(pathname, mode); +} diff --git a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp index 7e6e46374f..3fa07941ae 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp @@ -21,5 +21,6 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); +int iox_access(const char* pathname, int mode); #endif // IOX_HOOFS_UNIX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/unix/source/unistd.cpp b/iceoryx_platform/unix/source/unistd.cpp index 3d6ca37e12..652d53fc08 100644 --- a/iceoryx_platform/unix/source/unistd.cpp +++ b/iceoryx_platform/unix/source/unistd.cpp @@ -27,3 +27,8 @@ int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); } + +int iox_access(const char* pathname, int mode) +{ + return access(pathname, mode); +} diff --git a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp index 39620413fc..83f4487eea 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp @@ -30,11 +30,15 @@ using uid_t = int; using gid_t = int; +#define F_OK 0 +#define W_OK 2 +#define R_OK 4 int ftruncate(int fildes, off_t length); long sysconf(int name); int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); +int iox_access(const char* pathname, int mode); gid_t getgid(); #endif // IOX_HOOFS_WIN_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/win/source/unistd.cpp b/iceoryx_platform/win/source/unistd.cpp index f1682fb163..b5bee471e3 100644 --- a/iceoryx_platform/win/source/unistd.cpp +++ b/iceoryx_platform/win/source/unistd.cpp @@ -24,6 +24,11 @@ int ftruncate(int fildes, off_t length) return 0; } +int iox_access(const char* pathname, int mode) +{ + return _access(pathname, mode); +} + long sysconf(int name) { if (name == _SC_PAGESIZE) @@ -60,4 +65,4 @@ int iox_fchown(int fd, uid_t owner, gid_t group) gid_t getgid() { return 0; -} \ No newline at end of file +} From 795c3d784ff54fb7675461598061fe7c267a0434 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 4 Apr 2023 18:58:22 +0200 Subject: [PATCH 03/30] iox-#1962 Implement file remove functionality Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 10 ++++- .../posix/filesystem/source/file.cpp | 40 ++++++++++++++++++- .../linux/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/linux/source/unistd.cpp | 5 +++ .../mac/include/iceoryx_platform/unistd.hpp | 2 + iceoryx_platform/mac/source/unistd.cpp | 5 +++ .../qnx/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/qnx/source/unistd.cpp | 5 +++ .../unix/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/unix/source/unistd.cpp | 5 +++ .../win/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/win/source/unistd.cpp | 5 +++ 12 files changed, 79 insertions(+), 2 deletions(-) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index e5d433b174..869d10f0cf 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -62,6 +62,14 @@ enum class FileAccessError enum class FileRemoveError { + PermissionDenied, + CurrentlyInUse, + IoFailure, + TooManySymbolicLinksEncountered, + InsufficientKernelMemory, + IsDirectory, + ReadOnlyFilesystem, + UnknownError }; class File : public FileManagementInterface @@ -78,7 +86,7 @@ class File : public FileManagementInterface write_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; static expected does_exist(const FilePath& file) noexcept; - static expected remove(const FilePath& file) noexcept; + static expected remove(const FilePath& file) noexcept; private: friend class FileBuilder; diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 746b33580a..7cc12f297a 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -155,7 +155,45 @@ expected File::does_exist(const FilePath& file) noexcept } } -expected File::remove(const FilePath& file) noexcept +expected File::remove(const FilePath& file) noexcept { + auto result = posix::posixCall(iox_unlink)(file.as_string().c_str()).failureReturnValue(-1).evaluate(); + + if (!result.has_error()) + { + return iox::success(true); + } + + switch (result.get_error().errnum) + { + case ENOENT: + return iox::success(false); + case EPERM: + IOX_FALLTHROUGH + case EACCES: + IOX_LOG(ERROR) << "Unable to remove file due to insufficient permissions."; + return iox::error(FileRemoveError::PermissionDenied); + case EBUSY: + IOX_LOG(ERROR) << "Unable to remove file since it is currently in use."; + return iox::error(FileRemoveError::CurrentlyInUse); + case EIO: + IOX_LOG(ERROR) << "Unable to remove file due to an IO failure."; + return iox::error(FileRemoveError::IoFailure); + case ELOOP: + IOX_LOG(ERROR) << "Unable to remove file due to too many symbolic links."; + return iox::error(FileRemoveError::TooManySymbolicLinksEncountered); + case ENOMEM: + IOX_LOG(ERROR) << "Unable to remove file due to insufficient kernel memory."; + return iox::error(FileRemoveError::InsufficientKernelMemory); + case EISDIR: + IOX_LOG(ERROR) << "Unable to remove file since it is a directory."; + return iox::error(FileRemoveError::IsDirectory); + case EROFS: + IOX_LOG(ERROR) << "Unable to remove file since it resides on a read-only file system."; + return iox::error(FileRemoveError::ReadOnlyFilesystem); + default: + IOX_LOG(ERROR) << "Unable to remove file since an unknown error occurred."; + return iox::error(FileRemoveError::UnknownError); + } } } // namespace iox diff --git a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp index 6300a43756..aa755a251d 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp @@ -22,5 +22,6 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); +int iox_unlink(const char* pathname); #endif // IOX_HOOFS_LINUX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index 652d53fc08..0a0c5412c1 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -32,3 +32,8 @@ int iox_access(const char* pathname, int mode) { return access(pathname, mode); } + +int iox_unlink(const char* pathname) +{ + return unlink(pathname); +} diff --git a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp index 9b00990918..fc64b7b8ff 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp @@ -22,4 +22,6 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); +int iox_unlink(const char* pathname); + #endif // IOX_HOOFS_MAC_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/mac/source/unistd.cpp b/iceoryx_platform/mac/source/unistd.cpp index 89db6a0205..837c402b91 100644 --- a/iceoryx_platform/mac/source/unistd.cpp +++ b/iceoryx_platform/mac/source/unistd.cpp @@ -31,3 +31,8 @@ int iox_access(const char* pathname, int mode) { return access(pathname, mode); } + +int iox_unlink(const char* pathname) +{ + return unlink(pathname); +} diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp index 6628ec5585..19fdfc4f5f 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp @@ -22,5 +22,6 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); +int iox_unlink(const char* pathname); #endif // IOX_HOOFS_QNX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/qnx/source/unistd.cpp b/iceoryx_platform/qnx/source/unistd.cpp index 89db6a0205..837c402b91 100644 --- a/iceoryx_platform/qnx/source/unistd.cpp +++ b/iceoryx_platform/qnx/source/unistd.cpp @@ -31,3 +31,8 @@ int iox_access(const char* pathname, int mode) { return access(pathname, mode); } + +int iox_unlink(const char* pathname) +{ + return unlink(pathname); +} diff --git a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp index 3fa07941ae..a6d0a3581f 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp @@ -22,5 +22,6 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); +int iox_unlink(const char* pathname); #endif // IOX_HOOFS_UNIX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/unix/source/unistd.cpp b/iceoryx_platform/unix/source/unistd.cpp index 652d53fc08..0a0c5412c1 100644 --- a/iceoryx_platform/unix/source/unistd.cpp +++ b/iceoryx_platform/unix/source/unistd.cpp @@ -32,3 +32,8 @@ int iox_access(const char* pathname, int mode) { return access(pathname, mode); } + +int iox_unlink(const char* pathname) +{ + return unlink(pathname); +} diff --git a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp index 83f4487eea..010666bbc3 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp @@ -39,6 +39,7 @@ long sysconf(int name); int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); +int iox_unlink(const char* pathname); gid_t getgid(); #endif // IOX_HOOFS_WIN_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/win/source/unistd.cpp b/iceoryx_platform/win/source/unistd.cpp index b5bee471e3..caee6c4f15 100644 --- a/iceoryx_platform/win/source/unistd.cpp +++ b/iceoryx_platform/win/source/unistd.cpp @@ -29,6 +29,11 @@ int iox_access(const char* pathname, int mode) return _access(pathname, mode); } +int iox_unlink(const char* pathname) +{ + return _unlink(pathname); +} + long sysconf(int name) { if (name == _SC_PAGESIZE) From 79ab6739c2fc3f639e95bfb5029e8246489975c0 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 5 Apr 2023 16:16:59 +0200 Subject: [PATCH 04/30] iox-#1962 Implement file set offset functionality Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 12 +++++ .../posix/filesystem/source/file.cpp | 53 +++++++++++++++++++ .../linux/include/iceoryx_platform/unistd.hpp | 6 +++ iceoryx_platform/linux/source/unistd.cpp | 5 ++ .../mac/include/iceoryx_platform/unistd.hpp | 4 ++ iceoryx_platform/mac/source/unistd.cpp | 5 ++ .../qnx/include/iceoryx_platform/unistd.hpp | 4 ++ iceoryx_platform/qnx/source/unistd.cpp | 5 ++ .../unix/include/iceoryx_platform/unistd.hpp | 4 ++ iceoryx_platform/unix/source/unistd.cpp | 5 ++ .../win/include/iceoryx_platform/unistd.hpp | 3 ++ iceoryx_platform/win/source/unistd.cpp | 5 ++ 12 files changed, 111 insertions(+) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 869d10f0cf..87874f6123 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -45,6 +45,7 @@ enum class FileCreationError enum class FileReadError { + OffsetFailure, }; enum class FileWriteError @@ -72,6 +73,15 @@ enum class FileRemoveError UnknownError }; +enum class FileOffsetError +{ + FileOffsetOverflow, + OffsetBeyondFileLimits, + SeekingNotSupportedByFileType, + OffsetAtWrongPosition, + UnknownError, +}; + class File : public FileManagementInterface { public: @@ -92,6 +102,8 @@ class File : public FileManagementInterface friend class FileBuilder; explicit File(const int file_descriptor) noexcept; + expected set_offset(const uint64_t offset) const noexcept; + private: int m_file_descriptor{0}; }; diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 7cc12f297a..e07be0aa39 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -196,4 +196,57 @@ expected File::remove(const FilePath& file) noexcept return iox::error(FileRemoveError::UnknownError); } } + +expected File::set_offset(const uint64_t offset) const noexcept +{ + auto result = posix::posixCall(iox_lseek)(m_file_descriptor, static_cast(offset), IOX_SEEK_SET) + .failureReturnValue(-1) + .evaluate(); + + if (!result.has_error()) + { + if (result->value == static_cast(offset)) + { + return iox::success<>(); + } + + IOX_LOG(ERROR) << "Unable to set file offset position since it set to the wrong offset position."; + return iox::error(FileOffsetError::OffsetAtWrongPosition); + } + + + switch (result.get_error().errnum) + { + case EINVAL: + IOX_FALLTHROUGH + case ENXIO: + IOX_LOG(ERROR) << "Unable to set file offset position since it beyond the file limits."; + return iox::error(FileOffsetError::OffsetBeyondFileLimits); + case EOVERFLOW: + IOX_LOG(ERROR) + << "Unable to set file offset position since the file is too large and the offset would overflow."; + return iox::error(FileOffsetError::FileOffsetOverflow); + case EPIPE: + IOX_LOG(ERROR) << "Unable to set file offset position since seeking is not supported by the file type."; + return iox::error(FileOffsetError::SeekingNotSupportedByFileType); + default: + IOX_LOG(ERROR) << "Unable to remove file since an unknown error occurred."; + return iox::error(FileOffsetError::UnknownError); + } +} + +expected File::read(uint8_t* const buffer, const uint64_t buffer_len) const noexcept +{ + return read_at(0, buffer, buffer_len); +} + +expected +File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept +{ + if (set_offset(offset).has_error()) + { + IOX_LOG(ERROR) << "Unable to read file since the offset could not be set."; + return iox::error(FileReadError::OffsetFailure); + } +} } // namespace iox diff --git a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp index aa755a251d..abc34655fe 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp @@ -19,9 +19,15 @@ #include +#define IOX_SEEK_SET SEEK_SET + +using iox_off_t = off_t; + + int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); #endif // IOX_HOOFS_LINUX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index 0a0c5412c1..c3d0d7e414 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -37,3 +37,8 @@ int iox_unlink(const char* pathname) { return unlink(pathname); } + +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) +{ + return lseek(fd, offset, whence); +} diff --git a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp index fc64b7b8ff..a342b4204f 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp @@ -19,9 +19,13 @@ #include +#define IOX_SEEK_SET SEEK_SET +using iox_off_t = off_t; + int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); #endif // IOX_HOOFS_MAC_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/mac/source/unistd.cpp b/iceoryx_platform/mac/source/unistd.cpp index 837c402b91..77634542bd 100644 --- a/iceoryx_platform/mac/source/unistd.cpp +++ b/iceoryx_platform/mac/source/unistd.cpp @@ -36,3 +36,8 @@ int iox_unlink(const char* pathname) { return unlink(pathname); } + +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) +{ + return lseek(fd, offset, whence); +} diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp index 19fdfc4f5f..d282b8697c 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp @@ -19,9 +19,13 @@ #include +#define IOX_SEEK_SET SEEK_SET +using iox_off_t = off_t; + int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); #endif // IOX_HOOFS_QNX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/qnx/source/unistd.cpp b/iceoryx_platform/qnx/source/unistd.cpp index 837c402b91..77634542bd 100644 --- a/iceoryx_platform/qnx/source/unistd.cpp +++ b/iceoryx_platform/qnx/source/unistd.cpp @@ -36,3 +36,8 @@ int iox_unlink(const char* pathname) { return unlink(pathname); } + +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) +{ + return lseek(fd, offset, whence); +} diff --git a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp index a6d0a3581f..6bfd355933 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp @@ -19,9 +19,13 @@ #include +#define IOX_SEEK_SET SEEK_SET +using iox_off_t = off_t; + int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); #endif // IOX_HOOFS_UNIX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/unix/source/unistd.cpp b/iceoryx_platform/unix/source/unistd.cpp index 0a0c5412c1..c3d0d7e414 100644 --- a/iceoryx_platform/unix/source/unistd.cpp +++ b/iceoryx_platform/unix/source/unistd.cpp @@ -37,3 +37,8 @@ int iox_unlink(const char* pathname) { return unlink(pathname); } + +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) +{ + return lseek(fd, offset, whence); +} diff --git a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp index 010666bbc3..7eaaad0672 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp @@ -24,11 +24,13 @@ #include #include +#define IOX_SEEK_SET SEEK_SET #define _SC_PAGESIZE 1 #define STDERR_FILENO 2 using uid_t = int; using gid_t = int; +using iox_off_t = long; #define F_OK 0 #define W_OK 2 @@ -40,6 +42,7 @@ int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); gid_t getgid(); #endif // IOX_HOOFS_WIN_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/win/source/unistd.cpp b/iceoryx_platform/win/source/unistd.cpp index caee6c4f15..b9c07b3c9d 100644 --- a/iceoryx_platform/win/source/unistd.cpp +++ b/iceoryx_platform/win/source/unistd.cpp @@ -67,6 +67,11 @@ int iox_fchown(int fd, uid_t owner, gid_t group) return 0; } +iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) +{ + return _lseek(fd, offset, whence); +} + gid_t getgid() { return 0; From ad717a93ed2ca615ea0f9fa99cd66bd590087d14 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 5 Apr 2023 16:31:13 +0200 Subject: [PATCH 05/30] iox-#1962 Implement file reading functionality Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 6 ++++ .../posix/filesystem/source/file.cpp | 29 +++++++++++++++++++ .../linux/include/iceoryx_platform/unistd.hpp | 3 +- iceoryx_platform/linux/source/unistd.cpp | 5 ++++ .../mac/include/iceoryx_platform/unistd.hpp | 2 ++ iceoryx_platform/mac/source/unistd.cpp | 5 ++++ .../qnx/include/iceoryx_platform/unistd.hpp | 2 ++ iceoryx_platform/qnx/source/unistd.cpp | 5 ++++ .../unix/include/iceoryx_platform/unistd.hpp | 2 ++ iceoryx_platform/unix/source/unistd.cpp | 5 ++++ .../win/include/iceoryx_platform/unistd.hpp | 2 ++ iceoryx_platform/win/source/unistd.cpp | 5 ++++ 12 files changed, 70 insertions(+), 1 deletion(-) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 87874f6123..570f128786 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -46,6 +46,12 @@ enum class FileCreationError enum class FileReadError { OffsetFailure, + Interrupt, + FileUnsuitableForReading, + IoFailure, + OperationWouldBlock, + IsDirectory, + UnknownError }; enum class FileWriteError diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index e07be0aa39..52563cdcd8 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -248,5 +248,34 @@ File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffe IOX_LOG(ERROR) << "Unable to read file since the offset could not be set."; return iox::error(FileReadError::OffsetFailure); } + + auto result = posix::posixCall(iox_read)(m_file_descriptor, buffer, buffer_len).failureReturnValue(-1).evaluate(); + + if (!result.has_error()) + { + return iox::success(result->value); + } + + switch (result.get_error().errnum) + { + case EAGAIN: + IOX_LOG(ERROR) << "Unable to read file since the operation would block."; + return iox::error(FileReadError::OperationWouldBlock); + case EINTR: + IOX_LOG(ERROR) << "Unable to read file since an interrupt signal was received."; + return iox::error(FileReadError::Interrupt); + case EINVAL: + IOX_LOG(ERROR) << "Unable to read file since is unsuitable for reading."; + return iox::error(FileReadError::FileUnsuitableForReading); + case EIO: + IOX_LOG(ERROR) << "Unable to read file since an IO failure occurred."; + return iox::error(FileReadError::IoFailure); + case EISDIR: + IOX_LOG(ERROR) << "Unable to read file since it is a directory."; + return iox::error(FileReadError::IsDirectory); + default: + IOX_LOG(ERROR) << "Unable to read file since an unknown error occurred."; + return iox::error(FileReadError::UnknownError); + } } } // namespace iox diff --git a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp index abc34655fe..3cb6e21513 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp @@ -22,12 +22,13 @@ #define IOX_SEEK_SET SEEK_SET using iox_off_t = off_t; - +using iox_ssize_t = ssize_t; int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); +iox_ssize_t iox_read(int fd, void* buf, size_t count); #endif // IOX_HOOFS_LINUX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index c3d0d7e414..ca32d2ae51 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -42,3 +42,8 @@ iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) { return lseek(fd, offset, whence); } + +iox_ssize_t iox_read(int fd, void* buf, size_t count) +{ + return read(fd, buf, count); +} diff --git a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp index a342b4204f..2ff48b3fa7 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp @@ -21,11 +21,13 @@ #define IOX_SEEK_SET SEEK_SET using iox_off_t = off_t; +using iox_ssize_t = ssize_t; int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); +iox_ssize_t iox_read(int fd, void* buf, size_t count); #endif // IOX_HOOFS_MAC_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/mac/source/unistd.cpp b/iceoryx_platform/mac/source/unistd.cpp index 77634542bd..851d089b88 100644 --- a/iceoryx_platform/mac/source/unistd.cpp +++ b/iceoryx_platform/mac/source/unistd.cpp @@ -41,3 +41,8 @@ iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) { return lseek(fd, offset, whence); } + +iox_ssize_t iox_read(int fd, void* buf, size_t count) +{ + return read(fd, buf, count); +} diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp index d282b8697c..a236babdf9 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp @@ -21,11 +21,13 @@ #define IOX_SEEK_SET SEEK_SET using iox_off_t = off_t; +using iox_ssize_t = ssize_t; int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); +iox_ssize_t iox_read(int fd, void* buf, size_t count); #endif // IOX_HOOFS_QNX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/qnx/source/unistd.cpp b/iceoryx_platform/qnx/source/unistd.cpp index 77634542bd..851d089b88 100644 --- a/iceoryx_platform/qnx/source/unistd.cpp +++ b/iceoryx_platform/qnx/source/unistd.cpp @@ -41,3 +41,8 @@ iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) { return lseek(fd, offset, whence); } + +iox_ssize_t iox_read(int fd, void* buf, size_t count) +{ + return read(fd, buf, count); +} diff --git a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp index 6bfd355933..1c6161d3a7 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp @@ -21,11 +21,13 @@ #define IOX_SEEK_SET SEEK_SET using iox_off_t = off_t; +using iox_ssize_t = ssize_t; int iox_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); +iox_ssize_t iox_read(int fd, void* buf, size_t count); #endif // IOX_HOOFS_UNIX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/unix/source/unistd.cpp b/iceoryx_platform/unix/source/unistd.cpp index c3d0d7e414..ca32d2ae51 100644 --- a/iceoryx_platform/unix/source/unistd.cpp +++ b/iceoryx_platform/unix/source/unistd.cpp @@ -42,3 +42,8 @@ iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) { return lseek(fd, offset, whence); } + +iox_ssize_t iox_read(int fd, void* buf, size_t count) +{ + return read(fd, buf, count); +} diff --git a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp index 7eaaad0672..56fe56a2e9 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp @@ -31,6 +31,7 @@ using uid_t = int; using gid_t = int; using iox_off_t = long; +using iox_ssize_t = int; #define F_OK 0 #define W_OK 2 @@ -43,6 +44,7 @@ int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); +iox_ssize_t iox_read(int fd, void* buf, size_t count); gid_t getgid(); #endif // IOX_HOOFS_WIN_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/win/source/unistd.cpp b/iceoryx_platform/win/source/unistd.cpp index b9c07b3c9d..293dd4a572 100644 --- a/iceoryx_platform/win/source/unistd.cpp +++ b/iceoryx_platform/win/source/unistd.cpp @@ -72,6 +72,11 @@ iox_off_t iox_lseek(int fd, iox_off_t offset, int whence) return _lseek(fd, offset, whence); } +iox_ssize_t iox_read(int fd, void* buf, size_t count) +{ + return _read(fd, buf, count); +} + gid_t getgid() { return 0; From 32486549a5862204619dc9739caec9ac7e2ca067 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 5 Apr 2023 16:52:34 +0200 Subject: [PATCH 06/30] iox-#1962 Implement file writing functionality Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 14 +++- .../posix/filesystem/source/file.cpp | 64 +++++++++++++++++-- .../linux/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/linux/source/unistd.cpp | 5 ++ .../mac/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/mac/source/unistd.cpp | 5 ++ .../qnx/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/qnx/source/unistd.cpp | 5 ++ .../unix/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/unix/source/unistd.cpp | 5 ++ .../win/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/win/source/unistd.cpp | 5 ++ 12 files changed, 99 insertions(+), 9 deletions(-) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 570f128786..e523a4ea36 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -56,6 +56,16 @@ enum class FileReadError enum class FileWriteError { + OffsetFailure, + OperationWouldBlock, + DiskQuotaExhausted, + FileSizeExceedsMaximumSupportedSize, + Interrupt, + FileUnsuitableForWriting, + IoFailure, + NoSpaceLeftOnDevice, + PreventedByFileSeal, + UnknownError }; enum class FileAccessError @@ -97,8 +107,8 @@ class File : public FileManagementInterface expected read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; - expected write(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; - expected + expected write(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + expected write_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; static expected does_exist(const FilePath& file) noexcept; diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 52563cdcd8..1612afa7f3 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -245,7 +245,7 @@ File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffe { if (set_offset(offset).has_error()) { - IOX_LOG(ERROR) << "Unable to read file since the offset could not be set."; + IOX_LOG(ERROR) << "Unable to read from file since the offset could not be set."; return iox::error(FileReadError::OffsetFailure); } @@ -259,23 +259,73 @@ File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffe switch (result.get_error().errnum) { case EAGAIN: - IOX_LOG(ERROR) << "Unable to read file since the operation would block."; + IOX_LOG(ERROR) << "Unable to read from file since the operation would block."; return iox::error(FileReadError::OperationWouldBlock); case EINTR: - IOX_LOG(ERROR) << "Unable to read file since an interrupt signal was received."; + IOX_LOG(ERROR) << "Unable to read from file since an interrupt signal was received."; return iox::error(FileReadError::Interrupt); case EINVAL: - IOX_LOG(ERROR) << "Unable to read file since is unsuitable for reading."; + IOX_LOG(ERROR) << "Unable to read from file since is unsuitable for reading."; return iox::error(FileReadError::FileUnsuitableForReading); case EIO: - IOX_LOG(ERROR) << "Unable to read file since an IO failure occurred."; + IOX_LOG(ERROR) << "Unable to read from file since an IO failure occurred."; return iox::error(FileReadError::IoFailure); case EISDIR: - IOX_LOG(ERROR) << "Unable to read file since it is a directory."; + IOX_LOG(ERROR) << "Unable to read from file since it is a directory."; return iox::error(FileReadError::IsDirectory); default: - IOX_LOG(ERROR) << "Unable to read file since an unknown error occurred."; + IOX_LOG(ERROR) << "Unable to read from file since an unknown error occurred."; return iox::error(FileReadError::UnknownError); } } + +expected File::write(uint8_t* const buffer, const uint64_t buffer_len) const noexcept +{ + return write_at(0, buffer, buffer_len); +} + +expected +File::write_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept +{ + if (set_offset(offset).has_error()) + { + IOX_LOG(ERROR) << "Unable to write to file since the offset could not be set."; + return iox::error(FileWriteError::OffsetFailure); + } + + auto result = posix::posixCall(iox_write)(m_file_descriptor, buffer, buffer_len).failureReturnValue(-1).evaluate(); + + if (!result.has_error()) + { + return iox::success(result->value); + } + + switch (result.get_error().errnum) + { + case EAGAIN: + IOX_LOG(ERROR) << "Unable to write to file since the operation would block."; + return iox::error(FileWriteError::OperationWouldBlock); + case EDQUOT: + IOX_LOG(ERROR) << "Unable to write to file since the users disk quota has been exhausted."; + return iox::error(FileWriteError::DiskQuotaExhausted); + case EFBIG: + IOX_LOG(ERROR) << "Unable to write to file since file size exceeds the maximum supported size."; + return iox::error(FileWriteError::FileSizeExceedsMaximumSupportedSize); + case EINTR: + IOX_LOG(ERROR) << "Unable to write to file since an interrupt signal occurred."; + return iox::error(FileWriteError::Interrupt); + case EINVAL: + IOX_LOG(ERROR) << "Unable to write to file since the file is unsuitable for writing."; + return iox::error(FileWriteError::FileUnsuitableForWriting); + case ENOSPC: + IOX_LOG(ERROR) << "Unable to write to file since there is no space left on target."; + return iox::error(FileWriteError::NoSpaceLeftOnDevice); + case EPERM: + IOX_LOG(ERROR) << "Unable to write to file since the operation was prevented by a file seal."; + return iox::error(FileWriteError::PreventedByFileSeal); + default: + IOX_LOG(ERROR) << "Unable to write to file since an unknown error has occurred."; + return iox::error(FileWriteError::UnknownError); + } +} } // namespace iox diff --git a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp index 3cb6e21513..db49988f0e 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp @@ -30,5 +30,6 @@ int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); iox_ssize_t iox_read(int fd, void* buf, size_t count); +iox_ssize_t iox_write(int fd, const void* buf, size_t count); #endif // IOX_HOOFS_LINUX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index ca32d2ae51..34df0f7844 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -47,3 +47,8 @@ iox_ssize_t iox_read(int fd, void* buf, size_t count) { return read(fd, buf, count); } + +iox_ssize_t iox_write(int fd, const void* buf, size_t count) +{ + return write(fd, buf, count); +} diff --git a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp index 2ff48b3fa7..adb430ab6d 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp @@ -29,5 +29,6 @@ int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); iox_ssize_t iox_read(int fd, void* buf, size_t count); +iox_ssize_t iox_write(int fd, const void* buf, size_t count); #endif // IOX_HOOFS_MAC_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/mac/source/unistd.cpp b/iceoryx_platform/mac/source/unistd.cpp index 851d089b88..3b28259c48 100644 --- a/iceoryx_platform/mac/source/unistd.cpp +++ b/iceoryx_platform/mac/source/unistd.cpp @@ -46,3 +46,8 @@ iox_ssize_t iox_read(int fd, void* buf, size_t count) { return read(fd, buf, count); } + +iox_ssize_t iox_write(int fd, const void* buf, size_t count) +{ + return write(fd, buf, count); +} diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp index a236babdf9..345ea4018f 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp @@ -29,5 +29,6 @@ int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); iox_ssize_t iox_read(int fd, void* buf, size_t count); +iox_ssize_t iox_write(int fd, const void* buf, size_t count); #endif // IOX_HOOFS_QNX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/qnx/source/unistd.cpp b/iceoryx_platform/qnx/source/unistd.cpp index 851d089b88..3b28259c48 100644 --- a/iceoryx_platform/qnx/source/unistd.cpp +++ b/iceoryx_platform/qnx/source/unistd.cpp @@ -46,3 +46,8 @@ iox_ssize_t iox_read(int fd, void* buf, size_t count) { return read(fd, buf, count); } + +iox_ssize_t iox_write(int fd, const void* buf, size_t count) +{ + return write(fd, buf, count); +} diff --git a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp index 1c6161d3a7..172d1327ec 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp @@ -29,5 +29,6 @@ int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); iox_ssize_t iox_read(int fd, void* buf, size_t count); +iox_ssize_t iox_write(int fd, const void* buf, size_t count); #endif // IOX_HOOFS_UNIX_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/unix/source/unistd.cpp b/iceoryx_platform/unix/source/unistd.cpp index ca32d2ae51..34df0f7844 100644 --- a/iceoryx_platform/unix/source/unistd.cpp +++ b/iceoryx_platform/unix/source/unistd.cpp @@ -47,3 +47,8 @@ iox_ssize_t iox_read(int fd, void* buf, size_t count) { return read(fd, buf, count); } + +iox_ssize_t iox_write(int fd, const void* buf, size_t count) +{ + return write(fd, buf, count); +} diff --git a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp index 56fe56a2e9..dda1ed89e1 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp @@ -45,6 +45,7 @@ int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); iox_off_t iox_lseek(int fd, iox_off_t offset, int whence); iox_ssize_t iox_read(int fd, void* buf, size_t count); +iox_ssize_t iox_write(int fd, const void* buf, size_t count); gid_t getgid(); #endif // IOX_HOOFS_WIN_PLATFORM_UNISTD_HPP diff --git a/iceoryx_platform/win/source/unistd.cpp b/iceoryx_platform/win/source/unistd.cpp index 293dd4a572..0f87317a7d 100644 --- a/iceoryx_platform/win/source/unistd.cpp +++ b/iceoryx_platform/win/source/unistd.cpp @@ -77,6 +77,11 @@ iox_ssize_t iox_read(int fd, void* buf, size_t count) return _read(fd, buf, count); } +iox_ssize_t iox_write(int fd, const void* buf, size_t count) +{ + return _write(fd, buf, count); +} + gid_t getgid() { return 0; From f8cefea4b1cef0e2e0430da3892d85a80a1e8e09 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 5 Apr 2023 16:54:34 +0200 Subject: [PATCH 07/30] iox-#1962 Introduce IOX_TEMP_DIR required for testing Signed-off-by: Christian Eltzschig --- .../linux/include/iceoryx_platform/platform_settings.hpp | 1 + .../mac/include/iceoryx_platform/platform_settings.hpp | 1 + .../qnx/include/iceoryx_platform/platform_settings.hpp | 1 + .../unix/include/iceoryx_platform/platform_settings.hpp | 1 + .../win/include/iceoryx_platform/platform_settings.hpp | 1 + 5 files changed, 5 insertions(+) diff --git a/iceoryx_platform/linux/include/iceoryx_platform/platform_settings.hpp b/iceoryx_platform/linux/include/iceoryx_platform/platform_settings.hpp index ac446abc0c..dbe087264b 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/platform_settings.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/platform_settings.hpp @@ -37,6 +37,7 @@ constexpr const char IOX_PATH_SEPARATORS[IOX_NUMBER_OF_PATH_SEPARATORS] = {'/'}; constexpr uint64_t IOX_UDS_SOCKET_MAX_MESSAGE_SIZE = 4096; constexpr const char IOX_UDS_SOCKET_PATH_PREFIX[] = "/tmp/"; constexpr const char IOX_LOCK_FILE_PATH_PREFIX[] = "/tmp/"; +constexpr const char IOX_TEMP_DIR[] = "/tmp/"; constexpr uint64_t MAX_USER_NAME_LENGTH = 32; constexpr uint64_t MAX_GROUP_NAME_LENGTH = 32; diff --git a/iceoryx_platform/mac/include/iceoryx_platform/platform_settings.hpp b/iceoryx_platform/mac/include/iceoryx_platform/platform_settings.hpp index 031230fe60..52426e4fc8 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/platform_settings.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/platform_settings.hpp @@ -38,6 +38,7 @@ constexpr const char IOX_PATH_SEPARATORS[IOX_NUMBER_OF_PATH_SEPARATORS] = {'/'}; constexpr uint64_t IOX_UDS_SOCKET_MAX_MESSAGE_SIZE = 2048; constexpr const char IOX_UDS_SOCKET_PATH_PREFIX[] = "/tmp/"; constexpr const char IOX_LOCK_FILE_PATH_PREFIX[] = "/tmp/"; +constexpr const char IOX_TEMP_DIR[] = "/tmp/"; constexpr uint64_t MAX_USER_NAME_LENGTH = 32; constexpr uint64_t MAX_GROUP_NAME_LENGTH = 16; diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/platform_settings.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/platform_settings.hpp index 6a1b57bc7b..49ac5ed24b 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/platform_settings.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/platform_settings.hpp @@ -36,6 +36,7 @@ constexpr const char IOX_PATH_SEPARATORS[IOX_NUMBER_OF_PATH_SEPARATORS] = {'/'}; constexpr uint64_t IOX_UDS_SOCKET_MAX_MESSAGE_SIZE = 2048; constexpr const char IOX_UDS_SOCKET_PATH_PREFIX[] = "/tmp/"; constexpr const char IOX_LOCK_FILE_PATH_PREFIX[] = "/var/lock/"; +constexpr const char IOX_TEMP_DIR[] = "/tmp/"; constexpr uint64_t MAX_USER_NAME_LENGTH = 32; constexpr uint64_t MAX_GROUP_NAME_LENGTH = 16; diff --git a/iceoryx_platform/unix/include/iceoryx_platform/platform_settings.hpp b/iceoryx_platform/unix/include/iceoryx_platform/platform_settings.hpp index 18f6d420f4..9e2a3c6e6e 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/platform_settings.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/platform_settings.hpp @@ -37,6 +37,7 @@ constexpr const char IOX_PATH_SEPARATORS[IOX_NUMBER_OF_PATH_SEPARATORS] = {'/'}; constexpr uint64_t IOX_UDS_SOCKET_MAX_MESSAGE_SIZE = 1024; constexpr const char IOX_UDS_SOCKET_PATH_PREFIX[] = "/tmp/"; constexpr const char IOX_LOCK_FILE_PATH_PREFIX[] = "/tmp/"; +constexpr const char IOX_TEMP_DIR[] = "/tmp/"; constexpr uint64_t MAX_USER_NAME_LENGTH = 32; constexpr uint64_t MAX_GROUP_NAME_LENGTH = 16; diff --git a/iceoryx_platform/win/include/iceoryx_platform/platform_settings.hpp b/iceoryx_platform/win/include/iceoryx_platform/platform_settings.hpp index 554a2eef7a..67b529667c 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/platform_settings.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/platform_settings.hpp @@ -37,6 +37,7 @@ constexpr const char IOX_PATH_SEPARATORS[IOX_NUMBER_OF_PATH_SEPARATORS] = {'/', constexpr uint64_t IOX_UDS_SOCKET_MAX_MESSAGE_SIZE = 1024U; constexpr char IOX_UDS_SOCKET_PATH_PREFIX[] = ""; constexpr const char IOX_LOCK_FILE_PATH_PREFIX[] = "C:\\Windows\\Temp\\"; +constexpr const char IOX_TEMP_DIR[] = "C:\\Windows\\Temp\\"; constexpr uint64_t IOX_MAX_FILENAME_LENGTH = 128U; constexpr uint64_t IOX_MAX_PATH_LENGTH = 255U; From 2981e161ba47f6d84e9769cb38ac4d705c942d9b Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 6 Apr 2023 13:09:17 +0200 Subject: [PATCH 08/30] iox-#1962 Rename getFileHandle into get_file_handle Signed-off-by: Christian Eltzschig --- .../internal/posix_wrapper/shared_memory_object.hpp | 2 +- .../include/iox/detail/file_management_interface.inl | 10 +++++----- .../design/include/iox/file_management_interface.hpp | 4 ++-- iceoryx_hoofs/posix/filesystem/include/iox/file.hpp | 2 +- .../source/posix_wrapper/shared_memory_object.cpp | 2 +- .../iceoryx_posh/internal/mepoo/mepoo_segment.inl | 2 +- iceoryx_posh/test/moduletests/test_mepoo_segment.cpp | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp index 71eb30c037..5bd9de45eb 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp @@ -74,7 +74,7 @@ class SharedMemoryObject : public FileManagementInterface uint64_t getSizeInBytes() const noexcept; /// @brief Returns the underlying file handle of the shared memory - int getFileHandle() const noexcept; + int get_file_handle() const noexcept; /// @brief True if the shared memory has the ownership. False if an already /// existing shared memory was opened. diff --git a/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl b/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl index b66df4ea50..7e9b113f01 100644 --- a/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl +++ b/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl @@ -24,7 +24,7 @@ template inline expected FileManagementInterface::get_ownership() const noexcept { const auto& derived_this = *static_cast(this); - auto result = details::get_file_status(derived_this.getFileHandle()); + auto result = details::get_file_status(derived_this.get_file_handle()); if (result.has_error()) { return iox::error(result.get_error()); @@ -37,7 +37,7 @@ template inline expected FileManagementInterface::get_permissions() const noexcept { const auto& derived_this = *static_cast(this); - auto result = details::get_file_status(derived_this.getFileHandle()); + auto result = details::get_file_status(derived_this.get_file_handle()); if (result.has_error()) { return iox::error(result.get_error()); @@ -54,7 +54,7 @@ template inline expected FileManagementInterface::set_ownership(const Ownership ownership) noexcept { const auto& derived_this = *static_cast(this); - auto result = details::set_owner(derived_this.getFileHandle(), ownership.uid(), ownership.gid()); + auto result = details::set_owner(derived_this.get_file_handle(), ownership.uid(), ownership.gid()); if (result.has_error()) { return iox::error(result.get_error()); @@ -68,7 +68,7 @@ inline expected FileManagementInterface::set_permissions(const access_rights permissions) noexcept { const auto& derived_this = *static_cast(this); - auto result = details::set_permissions(derived_this.getFileHandle(), permissions); + auto result = details::set_permissions(derived_this.get_file_handle(), permissions); if (result.has_error()) { return iox::error(result.get_error()); @@ -81,7 +81,7 @@ template inline expected FileManagementInterface::get_size() const noexcept { const auto& derived_this = *static_cast(this); - auto result = details::get_file_status(derived_this.getFileHandle()); + auto result = details::get_file_status(derived_this.get_file_handle()); if (result.has_error()) { return iox::error(result.get_error()); diff --git a/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp b/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp index c461ed9a56..6c0a7598b7 100644 --- a/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp +++ b/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp @@ -99,13 +99,13 @@ class Ownership /// @brief Abstract implementation to manage things common to all file descriptor /// based constructs like ownership and permissions. -/// @note Can be used by every class which provide the method 'getFileHandle' +/// @note Can be used by every class which provide the method 'get_file_handle' /// via inheritance. /// @code /// class MyResourceBasedOnFileDescriptor: public FileManagementInterface { /// public: /// // must be implemented -/// int getFileHandle() const noexcept; +/// int get_file_handle() const noexcept; /// }; /// @endcode template diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index e523a4ea36..6650706e42 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -101,7 +101,7 @@ enum class FileOffsetError class File : public FileManagementInterface { public: - int getFileHandle() const noexcept; + int get_file_handle() const noexcept; expected read(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; expected diff --git a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp index 590497891e..76e17e30b3 100644 --- a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp @@ -177,7 +177,7 @@ uint64_t SharedMemoryObject::getSizeInBytes() const noexcept return m_memorySizeInBytes; } -int32_t SharedMemoryObject::getFileHandle() const noexcept +int32_t SharedMemoryObject::get_file_handle() const noexcept { return m_sharedMemory.getHandle(); } diff --git a/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl b/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl index 85c146aec0..24ea9e3e65 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl @@ -55,7 +55,7 @@ inline MePooSegment::MePooSegment( accessController.addPermissionEntry(AccessController::Category::GROUP, AccessController::Permission::READWRITE); accessController.addPermissionEntry(AccessController::Category::OTHERS, AccessController::Permission::NONE); - if (!accessController.writePermissionsToFile(m_sharedMemoryObject.getFileHandle())) + if (!accessController.writePermissionsToFile(m_sharedMemoryObject.get_file_handle())) { errorHandler(PoshError::MEPOO__SEGMENT_COULD_NOT_APPLY_POSIX_RIGHTS_TO_SHARED_MEMORY); } diff --git a/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp b/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp index da45e32a47..7ca3c2c773 100644 --- a/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp +++ b/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp @@ -71,7 +71,7 @@ class MePooSegment_test : public Test remove("/tmp/roudi_segment_test"); } - int getFileHandle() + int get_file_handle() { return filehandle; } From 6aa88e9daf6303febe27a3b6e7d0f1b2dc4b71a0 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 6 Apr 2023 13:16:17 +0200 Subject: [PATCH 09/30] iox-#1962 Create test skeleton Signed-off-by: Christian Eltzschig --- .../test/moduletests/test_posix_file.cpp | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 iceoryx_hoofs/test/moduletests/test_posix_file.cpp diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp new file mode 100644 index 0000000000..d49db0a020 --- /dev/null +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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_hoofs/posix_wrapper/thread.hpp" +#include "iceoryx_hoofs/testing/barrier.hpp" +#include "iceoryx_platform/platform_settings.hpp" +#include "iox/duration.hpp" +#include "test.hpp" + +#include + +namespace +{ +using namespace ::testing; +using namespace iox::posix; +using namespace iox::cxx; +using namespace iox; +using namespace iox::units; +using namespace iox::units::duration_literals; + +struct File_test : public Test +{ +}; + +TEST_F(File_test, CreateThreadWithNonEmptyCallableSucceeds) +{ + ::testing::Test::RecordProperty("TEST_ID", "f11e3aae-2e63-468f-b58a-22aeeedbd7fc"); +} + +} // namespace From b34f2b4b881bc7266fa6f8b43b331972dd3a6a9d Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 6 Apr 2023 14:27:28 +0200 Subject: [PATCH 10/30] iox-#1962 Implement first file tests Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 17 ++-- .../posix/filesystem/source/file.cpp | 33 ++++---- .../test/moduletests/test_posix_file.cpp | 81 ++++++++++++++++++- .../include/iox/detail/semantic_string.inl | 3 +- 4 files changed, 111 insertions(+), 23 deletions(-) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 6650706e42..79a20a2aba 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -25,7 +25,6 @@ namespace iox { -using AccessMode = posix::AccessMode; enum class FileCreationError { @@ -107,9 +106,9 @@ class File : public FileManagementInterface expected read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; - expected write(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + expected write(const uint8_t* const buffer, const uint64_t buffer_len) const noexcept; expected - write_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + write_at(const uint64_t offset, const uint8_t* const buffer, const uint64_t buffer_len) const noexcept; static expected does_exist(const FilePath& file) noexcept; static expected remove(const FilePath& file) noexcept; @@ -126,18 +125,22 @@ class File : public FileManagementInterface class FileBuilder { - IOX_BUILDER_PARAMETER(FilePath, name, FilePath::create("").value()) + private: + using AccessMode = posix::AccessMode; + using OpenMode = posix::OpenMode; + IOX_BUILDER_PARAMETER(Ownership, owner, Ownership::from_process()) IOX_BUILDER_PARAMETER(access_rights, permissions, perms::owner_read) IOX_BUILDER_PARAMETER(AccessMode, access_mode, AccessMode::READ_ONLY) + IOX_BUILDER_PARAMETER(OpenMode, open_mode, OpenMode::OPEN_EXISTING) public: - expected create(const posix::OpenMode open_mode) noexcept; - expected open() noexcept; + expected create(const FilePath& name) noexcept; + expected open(const FilePath& name) noexcept; private: expected open_impl(const bool print_error_on_non_existing_file, - const posix::OpenMode open_mode) noexcept; + const FilePath& name) noexcept; }; } // namespace iox diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 1612afa7f3..b1a619d931 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -21,41 +21,41 @@ namespace iox { -expected FileBuilder::create(const posix::OpenMode open_mode) noexcept +expected FileBuilder::create(const FilePath& name) noexcept { - switch (open_mode) + switch (m_open_mode) { case posix::OpenMode::OPEN_EXISTING: { - return this->open(); + return this->open(name); } case posix::OpenMode::PURGE_AND_CREATE: { - File::remove(m_name); + File::remove(name); IOX_FALLTHROUGH } case posix::OpenMode::EXCLUSIVE_CREATE: { - return this->open_impl(true, posix::OpenMode::EXCLUSIVE_CREATE); + return this->open_impl(true, name); } case posix::OpenMode::OPEN_OR_CREATE: { - auto result = this->open_impl(false, posix::OpenMode::OPEN_EXISTING); + auto result = this->open_impl(false, name); if (!result.has_error() || result.get_error() != FileCreationError::DoesNotExist) { return result; } - return this->open_impl(true, posix::OpenMode::EXCLUSIVE_CREATE); + return this->open_impl(true, name); } } } expected FileBuilder::open_impl(const bool print_error_on_non_existing_file, - const posix::OpenMode open_mode) noexcept + const FilePath& name) noexcept { - auto result = posix::posixCall(iox_open)(m_name.as_string().c_str(), - posix::convertToOflags(m_access_mode, open_mode), + auto result = posix::posixCall(iox_open)(name.as_string().c_str(), + posix::convertToOflags(m_access_mode, m_open_mode), static_cast(m_permissions.value())) .failureReturnValue(-1) .evaluate(); @@ -114,9 +114,9 @@ expected FileBuilder::open_impl(const bool print_error_ return iox::success(File(result->value)); } -expected FileBuilder::open() noexcept +expected FileBuilder::open(const FilePath& name) noexcept { - return this->open_impl(true, posix::OpenMode::OPEN_EXISTING); + return this->open_impl(true, name); } File::File(const int file_descriptor) noexcept @@ -279,13 +279,13 @@ File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffe } } -expected File::write(uint8_t* const buffer, const uint64_t buffer_len) const noexcept +expected File::write(const uint8_t* const buffer, const uint64_t buffer_len) const noexcept { return write_at(0, buffer, buffer_len); } expected -File::write_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept +File::write_at(const uint64_t offset, const uint8_t* const buffer, const uint64_t buffer_len) const noexcept { if (set_offset(offset).has_error()) { @@ -328,4 +328,9 @@ File::write_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buff return iox::error(FileWriteError::UnknownError); } } + +int File::get_file_handle() const noexcept +{ + return m_file_descriptor; +} } // namespace iox diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index d49db0a020..da3b4c6d11 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -18,8 +18,12 @@ #include "iceoryx_hoofs/testing/barrier.hpp" #include "iceoryx_platform/platform_settings.hpp" #include "iox/duration.hpp" +#include "iox/file.hpp" +#include "iox/file_path.hpp" +#include "iox/path.hpp" #include "test.hpp" +#include #include namespace @@ -33,11 +37,86 @@ using namespace iox::units::duration_literals; struct File_test : public Test { + FilePath m_sut_file_path = [] { + auto path = Path::create(platform::IOX_TEMP_DIR).expect("invalid temp dir"); + path.append("test-file").expect("invalid file name"); + return FilePath::create(path.as_string()).expect("invalid file path"); + }(); + + void SetUp() override + { + File::remove(m_sut_file_path); + } }; -TEST_F(File_test, CreateThreadWithNonEmptyCallableSucceeds) +TEST_F(File_test, CreatingFileWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "f11e3aae-2e63-468f-b58a-22aeeedbd7fc"); + auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + + EXPECT_FALSE(sut.has_error()); +} + +TEST_F(File_test, PurgeAndCreateRemovesExistingFile) { ::testing::Test::RecordProperty("TEST_ID", "f11e3aae-2e63-468f-b58a-22aeeedbd7fc"); + auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + EXPECT_FALSE(sut.has_error()); + + std::array test_content{1, 2, 3, 4, 5}; + sut->write(test_content.data(), 5); + + auto sut2 = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + EXPECT_FALSE(sut.has_error()); + EXPECT_THAT(sut->get_size().value(), 0); } +TEST_F(File_test, CreatingExclusivelyTwiceFails) +{ + ::testing::Test::RecordProperty("TEST_ID", "e5bb9df2-a243-4c13-ade4-85915f5e1859"); + auto sut = FileBuilder().open_mode(OpenMode::EXCLUSIVE_CREATE).create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto sut2 = FileBuilder().open_mode(OpenMode::EXCLUSIVE_CREATE).create(m_sut_file_path); + ASSERT_TRUE(sut2.has_error()); + EXPECT_THAT(sut2.get_error(), Eq(FileCreationError::AlreadyExists)); +} + +TEST_F(File_test, OpeningExistingFileWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "b89f2e7c-bddf-4acb-abe7-af63c92a5bfe"); + auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + auto sut2 = FileBuilder().open_mode(OpenMode::OPEN_EXISTING).create(m_sut_file_path); + + EXPECT_FALSE(sut2.has_error()); +} + +TEST_F(File_test, OpeningNonExistingFileFails) +{ + ::testing::Test::RecordProperty("TEST_ID", "ab4c647b-b567-4448-a3ee-78883a92872a"); + auto sut = FileBuilder().open_mode(OpenMode::OPEN_EXISTING).create(m_sut_file_path); + + ASSERT_TRUE(sut.has_error()); + EXPECT_THAT(sut.get_error(), Eq(FileCreationError::DoesNotExist)); +} + +TEST_F(File_test, OpenOrCreateCreatesNonExistingFile) +{ + ::testing::Test::RecordProperty("TEST_ID", "6ba6cb08-df89-4f6e-a591-f34fdb065381"); + auto sut = FileBuilder().open_mode(OpenMode::OPEN_OR_CREATE).create(m_sut_file_path); + + ASSERT_FALSE(sut.has_error()); +} + +TEST_F(File_test, OpenOrCreateOpensExistingFile) +{ + ::testing::Test::RecordProperty("TEST_ID", "2edf5a84-08d5-4d10-8b98-0b54d8920742"); + auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto sut2 = FileBuilder().open_mode(OpenMode::OPEN_OR_CREATE).create(m_sut_file_path); + ASSERT_FALSE(sut2.has_error()); +} + + } // namespace diff --git a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl index dce5966e65..4826decd7c 100644 --- a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl +++ b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl @@ -18,6 +18,7 @@ #include "iox/logging.hpp" #include "iox/semantic_string.hpp" +#include "iox/string.hpp" namespace iox { @@ -136,7 +137,7 @@ inline expected SemanticString::append( const T& value) noexcept { - return insert(size(), value, value.size()); + return insert(size(), value, internal::GetSize::call(value)); } template Date: Thu, 6 Apr 2023 19:03:31 +0200 Subject: [PATCH 11/30] iox-#1962 Implement creation and access tests Signed-off-by: Christian Eltzschig --- .../test/moduletests/test_posix_file.cpp | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index da3b4c6d11..1e6023760f 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -118,5 +118,53 @@ TEST_F(File_test, OpenOrCreateOpensExistingFile) ASSERT_FALSE(sut2.has_error()); } +TEST_F(File_test, OpenFileForReadingWithInsufficientPermissionFails) +{ + ::testing::Test::RecordProperty("TEST_ID", "58843f37-0474-49b1-9228-207391346f70"); + auto sut = + FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).permissions(perms::owner_write).create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto sut2 = + FileBuilder().open_mode(OpenMode::OPEN_EXISTING).access_mode(AccessMode::READ_ONLY).create(m_sut_file_path); + ASSERT_TRUE(sut2.has_error()); + EXPECT_THAT(sut2.get_error(), Eq(FileCreationError::PermissionDenied)); +} + +TEST_F(File_test, OpenFileForReadWriteWithInsufficientPermissionFails) +{ + ::testing::Test::RecordProperty("TEST_ID", "42525850-3c77-4661-98b1-68c0701893a5"); + auto sut = + FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).permissions(perms::owner_read).create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto sut2 = + FileBuilder().open_mode(OpenMode::OPEN_EXISTING).access_mode(AccessMode::READ_WRITE).create(m_sut_file_path); + ASSERT_TRUE(sut2.has_error()); + EXPECT_THAT(sut2.get_error(), Eq(FileCreationError::PermissionDenied)); +} + +TEST_F(File_test, AfterCreationTheFileExists) +{ + ::testing::Test::RecordProperty("TEST_ID", "076f97da-d095-4349-abcc-0f7f28d9730f"); + + EXPECT_FALSE(File::does_exist(m_sut_file_path).value()); + auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + EXPECT_TRUE(File::does_exist(m_sut_file_path).value()); +} + +TEST_F(File_test, RemoveReturnsTrueWhenFileExist) +{ + ::testing::Test::RecordProperty("TEST_ID", "64123a2d-4350-4969-80ce-d66e7433ed22"); + auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + EXPECT_TRUE(File::remove(m_sut_file_path).value()); +} + +TEST_F(File_test, RemoveReturnsFalseWhenFileDoesNotExist) +{ + ::testing::Test::RecordProperty("TEST_ID", "aaed2102-288f-4a93-a2e9-db4a6cef825e"); + + EXPECT_FALSE(File::remove(m_sut_file_path).value()); +} } // namespace From 66ba93ae14a300f5e8eda26e781046d8c08179b2 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 11 Apr 2023 18:00:40 +0200 Subject: [PATCH 12/30] iox-#1962 Introduce AccessMode::WRITE_ONLY and verify file reading Signed-off-by: Christian Eltzschig --- .../internal/posix_wrapper/types.inl | 2 + .../iceoryx_hoofs/posix_wrapper/types.hpp | 3 +- .../posix/filesystem/include/iox/file.hpp | 17 +- .../posix/filesystem/source/file.cpp | 80 +++++++++- iceoryx_hoofs/source/posix_wrapper/types.cpp | 2 + .../test/moduletests/test_posix_file.cpp | 147 +++++++++++++++++- .../test/moduletests/test_posix_types.cpp | 8 + 7 files changed, 246 insertions(+), 13 deletions(-) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/types.inl b/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/types.inl index 94640b353e..f63d381438 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/types.inl +++ b/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/types.inl @@ -47,6 +47,8 @@ inline constexpr const char* asStringLiteral(const AccessMode mode) noexcept return "AccessMode::READ_ONLY"; case AccessMode::READ_WRITE: return "AccessMode::READ_WRITE"; + case AccessMode::WRITE_ONLY: + return "AccessMode::WRITE_ONLY"; } return "AccessMode::UNDEFINED_VALUE"; diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp index 466b682e3c..7aa00b4d3a 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp @@ -25,7 +25,8 @@ namespace posix enum class AccessMode : uint64_t { READ_ONLY = 0U, - READ_WRITE = 1U + READ_WRITE = 1U, + WRITE_ONLY = 2U }; /// @brief describes how the shared memory is opened or created diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 79a20a2aba..f5da314f3c 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -50,6 +50,7 @@ enum class FileReadError IoFailure, OperationWouldBlock, IsDirectory, + NotOpenedForReading, UnknownError }; @@ -64,6 +65,7 @@ enum class FileWriteError IoFailure, NoSpaceLeftOnDevice, PreventedByFileSeal, + NotOpenedForWriting, UnknownError }; @@ -100,6 +102,13 @@ enum class FileOffsetError class File : public FileManagementInterface { public: + File(const File&) noexcept = delete; + File& operator=(const File&) noexcept = delete; + + File(File&& rhs) noexcept; + File& operator=(File&& rhs) noexcept; + ~File() noexcept; + int get_file_handle() const noexcept; expected read(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; @@ -115,12 +124,16 @@ class File : public FileManagementInterface private: friend class FileBuilder; - explicit File(const int file_descriptor) noexcept; + explicit File(const int file_descriptor, const posix::AccessMode access_mode) noexcept; + void close_fd() noexcept; expected set_offset(const uint64_t offset) const noexcept; private: - int m_file_descriptor{0}; + static constexpr int INVALID_FILE_DESCRIPTOR{-1}; + + int m_file_descriptor{INVALID_FILE_DESCRIPTOR}; + posix::AccessMode m_access_mode{posix::AccessMode::READ_ONLY}; }; class FileBuilder diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index b1a619d931..fceff53ce0 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -62,7 +62,7 @@ expected FileBuilder::open_impl(const bool print_error_ if (!result.has_error()) { - return iox::success(File(result.value().value)); + return iox::success(File(result.value().value, m_access_mode)); } switch (result.get_error().errnum) @@ -111,7 +111,7 @@ expected FileBuilder::open_impl(const bool print_error_ return iox::error(FileCreationError::UnknownError); } - return iox::success(File(result->value)); + return iox::success(File(result->value, m_access_mode)); } expected FileBuilder::open(const FilePath& name) noexcept @@ -119,11 +119,68 @@ expected FileBuilder::open(const FilePath& name) noexce return this->open_impl(true, name); } -File::File(const int file_descriptor) noexcept +File::File(const int file_descriptor, const posix::AccessMode access_mode) noexcept : m_file_descriptor{file_descriptor} + , m_access_mode{access_mode} { } +File::File(File&& rhs) noexcept + : m_file_descriptor{rhs.m_file_descriptor} + , m_access_mode{rhs.m_access_mode} +{ + rhs.m_file_descriptor = INVALID_FILE_DESCRIPTOR; +} + +File& File::operator=(File&& rhs) noexcept +{ + if (this != &rhs) + { + close_fd(); + m_file_descriptor = rhs.m_file_descriptor; + m_access_mode = rhs.m_access_mode; + rhs.m_file_descriptor = INVALID_FILE_DESCRIPTOR; + } + + return *this; +} + +File::~File() noexcept +{ + close_fd(); +} + +void File::close_fd() noexcept +{ + if (m_file_descriptor == INVALID_FILE_DESCRIPTOR) + { + return; + } + + auto result = posix::posixCall(iox_close)(m_file_descriptor).failureReturnValue(-1).evaluate(); + m_file_descriptor = INVALID_FILE_DESCRIPTOR; + + if (!result.has_error()) + { + return; + } + + switch (result.get_error().errnum) + { + case EBADF: + IOX_LOG(FATAL) << "This should never happen! Unable to close file since the file descriptor is invalid."; + break; + case EINTR: + IOX_LOG(FATAL) << "This should never happen! Unable to close file since an interrupt signal was received."; + break; + case EIO: + IOX_LOG(FATAL) << "This should never happen! Unable to close file due to an IO failure."; + break; + } + + cxx::EnsuresWithMsg(false, "Unable to close file descriptor due to a corrupted file descriptor."); +} + expected File::does_exist(const FilePath& file) noexcept { auto result = posix::posixCall(iox_access)(file.as_string().c_str(), F_OK).failureReturnValue(-1).evaluate(); @@ -157,7 +214,10 @@ expected File::does_exist(const FilePath& file) noexcept expected File::remove(const FilePath& file) noexcept { - auto result = posix::posixCall(iox_unlink)(file.as_string().c_str()).failureReturnValue(-1).evaluate(); + auto result = posix::posixCall(iox_unlink)(file.as_string().c_str()) + .failureReturnValue(-1) + .suppressErrorMessagesForErrnos(ENOENT) + .evaluate(); if (!result.has_error()) { @@ -243,6 +303,12 @@ expected File::read(uint8_t* const buffer, const uint64 expected File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept { + if (m_access_mode == posix::AccessMode::WRITE_ONLY) + { + IOX_LOG(ERROR) << "Unable to read from file since it is opened for writing only."; + return iox::error(FileReadError::NotOpenedForReading); + } + if (set_offset(offset).has_error()) { IOX_LOG(ERROR) << "Unable to read from file since the offset could not be set."; @@ -287,6 +353,12 @@ expected File::write(const uint8_t* const buffer, cons expected File::write_at(const uint64_t offset, const uint8_t* const buffer, const uint64_t buffer_len) const noexcept { + if (m_access_mode == posix::AccessMode::READ_ONLY) + { + IOX_LOG(ERROR) << "Unable to write to file since it is opened for reading only."; + return iox::error(FileWriteError::NotOpenedForWriting); + } + if (set_offset(offset).has_error()) { IOX_LOG(ERROR) << "Unable to write to file since the offset could not be set."; diff --git a/iceoryx_hoofs/source/posix_wrapper/types.cpp b/iceoryx_hoofs/source/posix_wrapper/types.cpp index ff51164d61..46d116c411 100644 --- a/iceoryx_hoofs/source/posix_wrapper/types.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/types.cpp @@ -30,6 +30,8 @@ int convertToOflags(const AccessMode accessMode) noexcept return O_RDONLY; case AccessMode::READ_WRITE: return O_RDWR; + case AccessMode::WRITE_ONLY: + return O_WRONLY; } IOX_LOG(ERROR) << "Unable to convert to O_ flag since an undefined iox::posix::AccessMode was provided"; diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 1e6023760f..a19a47e528 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -60,15 +60,21 @@ TEST_F(File_test, CreatingFileWorks) TEST_F(File_test, PurgeAndCreateRemovesExistingFile) { ::testing::Test::RecordProperty("TEST_ID", "f11e3aae-2e63-468f-b58a-22aeeedbd7fc"); - auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); - EXPECT_FALSE(sut.has_error()); + { + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + EXPECT_FALSE(sut.has_error()); - std::array test_content{1, 2, 3, 4, 5}; - sut->write(test_content.data(), 5); + std::array test_content{1, 2, 3, 4, 5}; + auto result = sut->write(test_content.data(), 5); + ASSERT_FALSE(result.has_error()); + } auto sut2 = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); - EXPECT_FALSE(sut.has_error()); - EXPECT_THAT(sut->get_size().value(), 0); + EXPECT_FALSE(sut2.has_error()); + EXPECT_THAT(sut2->get_size().value(), 0); } TEST_F(File_test, CreatingExclusivelyTwiceFails) @@ -167,4 +173,133 @@ TEST_F(File_test, RemoveReturnsFalseWhenFileDoesNotExist) EXPECT_FALSE(File::remove(m_sut_file_path).value()); } + +TEST_F(File_test, ReadAndWriteToFileWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "494d9d0f-3a7f-40ba-bc92-36e445332aff"); + + const std::array test_content{12, 14, 18, 19, 22, 90, 200, 1}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + std::array read_content{0}; + auto read = sut->read(read_content.data(), read_content.size()); + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(test_content.size())); + EXPECT_THAT(read_content, Eq(test_content)); +} + +TEST_F(File_test, ReadingOfAWriteOnlyFileFails) +{ + ::testing::Test::RecordProperty("TEST_ID", "4a404243-33fb-4c28-9e7b-58980f6918a3"); + + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::WRITE_ONLY) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + std::array read_content{0}; + auto read = sut->read(read_content.data(), read_content.size()); + ASSERT_TRUE(read.has_error()); + EXPECT_THAT(read.get_error(), Eq(FileReadError::NotOpenedForReading)); +} + +TEST_F(File_test, ReadingWithSmallerBufferSizeWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "069f9752-7f1f-4da2-9015-a583f37b9e22"); + + const std::array test_content{112, 114, 118, 119, 122, 190, 100, 101}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + std::array read_content{0}; + auto read = sut->read(read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(read_content.size())); + EXPECT_THAT(read_content, Eq(std::array{112, 114})); +} + +TEST_F(File_test, ReadingWithLargerBufferSizeWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "63a19c93-f2ea-493f-b294-d3f8ae42ec27"); + + const std::array test_content{212, 214}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + std::array read_content{0}; + auto read = sut->read(read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(test_content.size())); + EXPECT_THAT(read_content, Eq(std::array{212, 214, 0, 0})); +} + +TEST_F(File_test, ReadingWithOffsetWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "322cc4fc-56bd-42f9-9d46-47e361006371"); + + const std::array test_content{112, 114, 118, 119, 122, 190, 100, 101}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + std::array read_content{0}; + auto read = sut->read_at(2, read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(read_content.size())); + EXPECT_THAT(read_content, Eq(std::array{118, 119, 122})); +} + +TEST_F(File_test, ReadingWithOutOfBoundsOffsetReadsNothing) +{ + ::testing::Test::RecordProperty("TEST_ID", "e5ef080e-c74d-40d0-a6c8-71541d3057da"); + + const std::array test_content{122, 190, 100, 101}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + std::array read_content{0}; + auto read = sut->read_at(8, read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(0)); +} } // namespace diff --git a/iceoryx_hoofs/test/moduletests/test_posix_types.cpp b/iceoryx_hoofs/test/moduletests/test_posix_types.cpp index 260ed64e63..18e935de35 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_types.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_types.cpp @@ -31,6 +31,7 @@ TEST(TypesTest, ConvertToOflagFromAccessModeWorks) ::testing::Test::RecordProperty("TEST_ID", "9eb74e8c-7498-4400-9248-92aa6bd15142"); EXPECT_THAT(convertToOflags(AccessMode::READ_ONLY), Eq(O_RDONLY)); EXPECT_THAT(convertToOflags(AccessMode::READ_WRITE), Eq(O_RDWR)); + EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY), Eq(O_WRONLY)); EXPECT_THAT(convertToOflags(INVALID_ACCESS_MODE), Eq(0U)); } @@ -64,6 +65,12 @@ TEST(TypesTest, ConvertToOflagFromAccessAndOpenModeWorks) EXPECT_THAT(convertToOflags(AccessMode::READ_WRITE, OpenMode::OPEN_EXISTING), Eq(O_RDWR)); EXPECT_THAT(convertToOflags(AccessMode::READ_WRITE, INVALID_OPEN_MODE), Eq(O_RDWR)); + EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY, OpenMode::EXCLUSIVE_CREATE), Eq(O_WRONLY | O_CREAT | O_EXCL)); + EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY, OpenMode::PURGE_AND_CREATE), Eq(O_WRONLY | O_CREAT | O_EXCL)); + EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY, OpenMode::OPEN_OR_CREATE), Eq(O_WRONLY | O_CREAT)); + EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY, OpenMode::OPEN_EXISTING), Eq(O_WRONLY)); + EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY, INVALID_OPEN_MODE), Eq(O_WRONLY)); + EXPECT_THAT(convertToOflags(INVALID_ACCESS_MODE, OpenMode::EXCLUSIVE_CREATE), Eq(O_CREAT | O_EXCL)); EXPECT_THAT(convertToOflags(INVALID_ACCESS_MODE, OpenMode::PURGE_AND_CREATE), Eq(O_CREAT | O_EXCL)); // NOLINTEND(hicpp-signed-bitwise) @@ -87,6 +94,7 @@ TEST(TypesTest, AccessModeAsStringLiteral) ::testing::Test::RecordProperty("TEST_ID", "c5a09ee7-df2c-4a28-929c-7de743f1e423"); EXPECT_THAT(asStringLiteral(AccessMode::READ_ONLY), StrEq("AccessMode::READ_ONLY")); EXPECT_THAT(asStringLiteral(AccessMode::READ_WRITE), StrEq("AccessMode::READ_WRITE")); + EXPECT_THAT(asStringLiteral(AccessMode::WRITE_ONLY), StrEq("AccessMode::WRITE_ONLY")); EXPECT_THAT(asStringLiteral(INVALID_ACCESS_MODE), StrEq("AccessMode::UNDEFINED_VALUE")); } } // namespace From cd230b148b2d51ecc27a5e4dc7730c80269d7ffd Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 11 Apr 2023 18:10:18 +0200 Subject: [PATCH 13/30] iox-#1962 Finalize File tests with write Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 1 - .../test/moduletests/test_posix_file.cpp | 70 +++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index f5da314f3c..12fdc72316 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -25,7 +25,6 @@ namespace iox { - enum class FileCreationError { PermissionDenied, diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index a19a47e528..421f82ab5e 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -302,4 +302,74 @@ TEST_F(File_test, ReadingWithOutOfBoundsOffsetReadsNothing) ASSERT_FALSE(read.has_error()); EXPECT_THAT(*read, Eq(0)); } + +TEST_F(File_test, WritingIntoAReadOnlyFileFails) +{ + ::testing::Test::RecordProperty("TEST_ID", "dba3d6b3-c09b-4bbe-acb4-22f20abdc9b9"); + + const std::array test_content{122, 190, 100, 101}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_ONLY) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_TRUE(result.has_error()); + EXPECT_THAT(result.get_error(), Eq(FileWriteError::NotOpenedForWriting)); +} + +TEST_F(File_test, WriteAtOverridesContent) +{ + ::testing::Test::RecordProperty("TEST_ID", "6b8de48f-a7cf-489e-bc66-95e92ddcb082"); + + const std::array test_content{122, 190, 100, 101}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + result = sut->write_at(2, test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + std::array read_content{0}; + auto read = sut->read(read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(6)); + EXPECT_THAT(read_content, Eq(std::array{122, 190, 122, 190, 100, 101, 0, 0, 0, 0})); +} + +TEST_F(File_test, WriteWithOutOfBoundsOffsetAddsZerosInBetween) +{ + ::testing::Test::RecordProperty("TEST_ID", "c27e2ce3-e100-4c86-b414-8b59415a6ea8"); + + const std::array test_content{240, 250}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + result = sut->write_at(4, test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + std::array read_content{0}; + auto read = sut->read(read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(6)); + EXPECT_THAT(read_content, Eq(std::array{240, 250, 0, 0, 240, 250, 0, 0, 0, 0})); +} } // namespace From 77c5cca8fcf9db69b064ead8c5e1cecf094f6997 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 11 Apr 2023 18:27:44 +0200 Subject: [PATCH 14/30] iox-#1962 Add file documentation Signed-off-by: Christian Eltzschig --- .../posix/filesystem/include/iox/file.hpp | 37 ++++++++++++ .../test/moduletests/test_posix_file.cpp | 59 ++++++++++++++++++- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 12fdc72316..69fbe97949 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -25,6 +25,7 @@ namespace iox { +/// @brief Describes failures which can occur when a file is opened or created. enum class FileCreationError { PermissionDenied, @@ -41,6 +42,7 @@ enum class FileCreationError UnknownError }; +/// @brief Describes failures which can occur when a file is read. enum class FileReadError { OffsetFailure, @@ -53,6 +55,7 @@ enum class FileReadError UnknownError }; +/// @brief Describes failures which can occur when a file is written to. enum class FileWriteError { OffsetFailure, @@ -68,6 +71,7 @@ enum class FileWriteError UnknownError }; +/// @brief Describes failures which can occur when the files metadata is accessed. enum class FileAccessError { InsufficientPermissions, @@ -77,6 +81,7 @@ enum class FileAccessError UnknownError }; +/// @brief Describes failures which can occur when a file is removed. enum class FileRemoveError { PermissionDenied, @@ -89,6 +94,7 @@ enum class FileRemoveError UnknownError }; +/// @brief Describes failures which can occur when a file offset is changed. enum class FileOffsetError { FileOffsetOverflow, @@ -98,6 +104,8 @@ enum class FileOffsetError UnknownError, }; +/// @brief Represents a file. It supports various read and write functionalities +/// and can verify the existance of a file as well as remove existing files. class File : public FileManagementInterface { public: @@ -108,17 +116,46 @@ class File : public FileManagementInterface File& operator=(File&& rhs) noexcept; ~File() noexcept; + /// @brief Returns the underlying native file handle. int get_file_handle() const noexcept; + /// @brief Reads the contents of the file and writes it into the provided buffer. + /// @param[in] buffer pointer to the memory. + /// @param[in] buffer_len the storage size of the provided memory. + /// @returns The amount of bytes read, at most buffer_len. expected read(uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + + /// @brief Reads the contents of the file from a given offset and writes it into the provided buffer. + /// If the offset is out of bounds it will read nothing. + /// @param[in] offset starting point from which the reading shall begin. + /// @param[in] buffer pointer to the memory. + /// @param[in] buffer_len the storage size of the provided memory. + /// @returns The amount of bytes read, at most buffer_len. expected read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + /// @brief Writes the provided buffer into the file. + /// @param[in] buffer pointer to the memory which shall be stored inside the file. + /// @param[in] buffer_len length of the memory. + /// @returns The amount of bytes written, at most buffer_len. expected write(const uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + + /// @brief Writes the provided buffer into the file starting from the given offset. If the offset + /// is out of bounds the file will be filled with zeroes until the offset. + /// @param[in] offset starting point from which the writing shall begin. + /// @param[in] buffer pointer to the memory which shall be stored inside the file. + /// @param[in] buffer_len length of the memory. + /// @returns The amount of bytes written, at most buffer_len. expected write_at(const uint64_t offset, const uint8_t* const buffer, const uint64_t buffer_len) const noexcept; + /// @brief Returns true if the provided file exists, otherwise false. + /// @param[in] file the path to the file static expected does_exist(const FilePath& file) noexcept; + + /// @brief Removes an existing file. + /// @param[in] file the path to the file which shall be removed + /// @returns true if the file did exist and was removed, otherwise false static expected remove(const FilePath& file) noexcept; private: diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 421f82ab5e..074168f533 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -51,7 +51,7 @@ struct File_test : public Test TEST_F(File_test, CreatingFileWorks) { - ::testing::Test::RecordProperty("TEST_ID", "f11e3aae-2e63-468f-b58a-22aeeedbd7fc"); + ::testing::Test::RecordProperty("TEST_ID", "bd272f33-5c5d-4a2d-8a50-02ccfc69b775"); auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); EXPECT_FALSE(sut.has_error()); @@ -372,4 +372,61 @@ TEST_F(File_test, WriteWithOutOfBoundsOffsetAddsZerosInBetween) EXPECT_THAT(*read, Eq(6)); EXPECT_THAT(read_content, Eq(std::array{240, 250, 0, 0, 240, 250, 0, 0, 0, 0})); } + +TEST_F(File_test, MoveConstructedFileWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "1f9ffd26-2171-4a1c-880b-c28ed11c843b"); + + const std::array test_content{242, 252}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + File sut2{std::move(sut.value())}; + + std::array read_content{0}; + auto read = sut2.read(read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(2)); + EXPECT_THAT(read_content, Eq(std::array{242, 252, 0})); +} + +TEST_F(File_test, MoveAssignedFileWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "70e19f33-5007-42be-8a5e-51df6ca429dd"); + + const std::array test_content{244, 254}; + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .access_mode(posix::AccessMode::READ_WRITE) + .create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + + auto result = sut->write(test_content.data(), test_content.size()); + ASSERT_FALSE(result.has_error()); + EXPECT_THAT(*result, Eq(test_content.size())); + + File sut2{std::move(sut.value())}; + auto sut3 = FileBuilder() + .open_mode(OpenMode::OPEN_EXISTING) + .access_mode(posix::AccessMode::READ_ONLY) + .create(m_sut_file_path); + ASSERT_FALSE(sut3.has_error()); + + sut2 = std::move(sut3.value()); + + std::array read_content{0}; + auto read = sut2.read(read_content.data(), read_content.size()); + + ASSERT_FALSE(read.has_error()); + EXPECT_THAT(*read, Eq(2)); + EXPECT_THAT(read_content, Eq(std::array{244, 254, 0})); +} } // namespace From f95b2a161a22112b4be30a7c8bc3d1db98e31fe4 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 11 Apr 2023 18:41:28 +0200 Subject: [PATCH 15/30] iox-#1962 Introduce convertToProtFlags function and use it in memoryMap to make the process cleanly testable Signed-off-by: Christian Eltzschig --- .../iceoryx_hoofs/posix_wrapper/types.hpp | 4 ++++ .../posix/filesystem/source/file.cpp | 8 -------- .../shared_memory_object/memory_map.cpp | 13 +------------ iceoryx_hoofs/source/posix_wrapper/types.cpp | 19 +++++++++++++++++++ .../test/moduletests/test_posix_types.cpp | 10 ++++++++++ 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp index 7aa00b4d3a..3a06596afc 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/posix_wrapper/types.hpp @@ -58,6 +58,10 @@ int convertToOflags(const AccessMode accessMode) noexcept; /// @param[in] openMode the openMode which should be converted int convertToOflags(const OpenMode openMode) noexcept; +/// @brief converts the AccessMode into the corresponding PROT_** flags. +/// @param[in] accessMode the accessMode which should be converted +int convertToProtFlags(const AccessMode accessMode) noexcept; + /// @brief converts the AccessMode and OpenMode into the corresponding O_** flags /// @param[in] accessMode the accessMode which should be converted /// @param[in] openMode the openMode which should be converted diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index fceff53ce0..ac9192acc0 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -26,20 +26,13 @@ expected FileBuilder::create(const FilePath& name) noex switch (m_open_mode) { case posix::OpenMode::OPEN_EXISTING: - { return this->open(name); - } case posix::OpenMode::PURGE_AND_CREATE: - { File::remove(name); IOX_FALLTHROUGH - } case posix::OpenMode::EXCLUSIVE_CREATE: - { return this->open_impl(true, name); - } case posix::OpenMode::OPEN_OR_CREATE: - { auto result = this->open_impl(false, name); if (!result.has_error() || result.get_error() != FileCreationError::DoesNotExist) { @@ -48,7 +41,6 @@ expected FileBuilder::create(const FilePath& name) noex return this->open_impl(true, name); } - } } expected FileBuilder::open_impl(const bool print_error_on_non_existing_file, diff --git a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/memory_map.cpp b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/memory_map.cpp index 214eb9260a..db851d2d1f 100644 --- a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/memory_map.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/memory_map.cpp @@ -28,22 +28,11 @@ namespace posix { expected MemoryMapBuilder::create() noexcept { - int32_t l_memoryProtection{PROT_NONE}; - switch (m_accessMode) - { - case AccessMode::READ_ONLY: - l_memoryProtection = PROT_READ; - break; - case AccessMode::READ_WRITE: - // NOLINTNEXTLINE(hicpp-signed-bitwise) enum type is defined by POSIX, no logical fault - l_memoryProtection = PROT_READ | PROT_WRITE; - break; - } // AXIVION Next Construct AutosarC++19_03-A5.2.3, CertC++-EXP55 : Incompatibility with POSIX definition of mmap // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) low-level memory management auto result = posixCall(mmap)(const_cast(m_baseAddressHint), m_length, - l_memoryProtection, + convertToProtFlags(m_accessMode), static_cast(m_flags), m_fileDescriptor, m_offset) diff --git a/iceoryx_hoofs/source/posix_wrapper/types.cpp b/iceoryx_hoofs/source/posix_wrapper/types.cpp index 46d116c411..bb01f49b5a 100644 --- a/iceoryx_hoofs/source/posix_wrapper/types.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/types.cpp @@ -16,6 +16,7 @@ #include "iceoryx_hoofs/posix_wrapper/types.hpp" #include "iceoryx_platform/fcntl.hpp" +#include "iceoryx_platform/mman.hpp" #include "iox/logging.hpp" namespace iox @@ -58,6 +59,24 @@ int convertToOflags(const OpenMode openMode) noexcept return 0; } +int convertToProtFlags(const AccessMode accessMode) noexcept +{ + switch (accessMode) + { + case AccessMode::READ_ONLY: + return PROT_READ; + case AccessMode::READ_WRITE: + // NOLINTNEXTLINE(hicpp-signed-bitwise) enum type is defined by POSIX, no logical fault + return PROT_READ | PROT_WRITE; + case AccessMode::WRITE_ONLY: + return PROT_WRITE; + } + + IOX_LOG(ERROR) << "Unable to convert to PROT_ flag since an undefined iox::posix::AccessMode was provided"; + return PROT_NONE; +} + + int convertToOflags(const AccessMode accessMode, const OpenMode openMode) noexcept { // wrapped inside function so that the user does not have to use bitwise operations; operands have positive diff --git a/iceoryx_hoofs/test/moduletests/test_posix_types.cpp b/iceoryx_hoofs/test/moduletests/test_posix_types.cpp index 18e935de35..f64514e550 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_types.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_types.cpp @@ -16,6 +16,7 @@ #include "iceoryx_hoofs/posix_wrapper/types.hpp" #include "iceoryx_platform/fcntl.hpp" +#include "iceoryx_platform/mman.hpp" #include "test.hpp" namespace @@ -35,6 +36,15 @@ TEST(TypesTest, ConvertToOflagFromAccessModeWorks) EXPECT_THAT(convertToOflags(INVALID_ACCESS_MODE), Eq(0U)); } +TEST(TypesTest, ConvertToProtflagFromAccessModeWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "7a5c699e-16e6-471f-80b6-a325644e60d3"); + EXPECT_THAT(convertToOflags(AccessMode::READ_ONLY), Eq(PROT_READ)); + EXPECT_THAT(convertToOflags(AccessMode::READ_WRITE), Eq(PROT_READ | PROT_WRITE)); + EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY), Eq(PROT_WRITE)); + EXPECT_THAT(convertToOflags(INVALID_ACCESS_MODE), Eq(PROT_NONE)); +} + TEST(TypesTest, ConvertToOflagFromOpenModeWorks) { ::testing::Test::RecordProperty("TEST_ID", "95fa55c9-2d64-4296-8bbb-41ff3c9dac3f"); From d0bcfe4128cf1ffe59f70829881cd7ca45ee3582 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 11 Apr 2023 19:00:44 +0200 Subject: [PATCH 16/30] iox-#1962 Fix IOX_FALLTHROUGH failures and handle error case when remove fails in purge and open Signed-off-by: Christian Eltzschig --- .../iox/detail/file_management_interface.inl | 2 +- .../posix/filesystem/include/iox/file.hpp | 1 + .../posix/filesystem/source/file.cpp | 21 +++++++++++++------ .../test/moduletests/test_posix_file.cpp | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl b/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl index 7e9b113f01..5c3df5fb0a 100644 --- a/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl +++ b/iceoryx_hoofs/posix/design/include/iox/detail/file_management_interface.inl @@ -87,7 +87,7 @@ inline expected FileManagementInterface::get_s return iox::error(result.get_error()); } - return iox::success(result->st_size); + return iox::success(static_cast(result->st_size)); } } // namespace iox diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 69fbe97949..0ed10c5cb9 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -39,6 +39,7 @@ enum class FileCreationError InsufficientMemory, FileTooLarge, CurrentlyInUse, + CannotBePurged, UnknownError }; diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index ac9192acc0..9d221bbf59 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -28,8 +28,13 @@ expected FileBuilder::create(const FilePath& name) noex case posix::OpenMode::OPEN_EXISTING: return this->open(name); case posix::OpenMode::PURGE_AND_CREATE: - File::remove(name); - IOX_FALLTHROUGH + if (File::remove(name).has_error()) + { + IOX_LOG(ERROR) << "Unable to purge and open file \"" << name.as_string() + << "\" since the file could not be removed"; + return iox::error(FileCreationError::CannotBePurged); + } + IOX_FALLTHROUGH; case posix::OpenMode::EXCLUSIVE_CREATE: return this->open_impl(true, name); case posix::OpenMode::OPEN_OR_CREATE: @@ -41,6 +46,10 @@ expected FileBuilder::create(const FilePath& name) noex return this->open_impl(true, name); } + + // can never be reached since all cases are handled in the above switch + // statement + return iox::error(FileCreationError::UnknownError); } expected FileBuilder::open_impl(const bool print_error_on_non_existing_file, @@ -221,7 +230,7 @@ expected File::remove(const FilePath& file) noexcept case ENOENT: return iox::success(false); case EPERM: - IOX_FALLTHROUGH + IOX_FALLTHROUGH; case EACCES: IOX_LOG(ERROR) << "Unable to remove file due to insufficient permissions."; return iox::error(FileRemoveError::PermissionDenied); @@ -270,7 +279,7 @@ expected File::set_offset(const uint64_t offset) const noexcept switch (result.get_error().errnum) { case EINVAL: - IOX_FALLTHROUGH + IOX_FALLTHROUGH; case ENXIO: IOX_LOG(ERROR) << "Unable to set file offset position since it beyond the file limits."; return iox::error(FileOffsetError::OffsetBeyondFileLimits); @@ -311,7 +320,7 @@ File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffe if (!result.has_error()) { - return iox::success(result->value); + return iox::success(static_cast(result->value)); } switch (result.get_error().errnum) @@ -361,7 +370,7 @@ File::write_at(const uint64_t offset, const uint8_t* const buffer, const uint64_ if (!result.has_error()) { - return iox::success(result->value); + return iox::success(static_cast(result->value)); } switch (result.get_error().errnum) diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 074168f533..2fb0b0d1d4 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -45,7 +45,7 @@ struct File_test : public Test void SetUp() override { - File::remove(m_sut_file_path); + IOX_DISCARD_RESULT(File::remove(m_sut_file_path)); } }; From 163891b53eb5af799f72b850dc398a9c459bd2a6 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 11 Apr 2023 19:45:42 +0200 Subject: [PATCH 17/30] iox-#1962 Add platform errno.hpp to fix unknown errno issue in windows, use explicit string to fix gcc-5.4 issue, fix prot flag conversion tests Signed-off-by: Christian Eltzschig --- iceoryx_hoofs/posix/filesystem/source/file.cpp | 1 + iceoryx_hoofs/test/moduletests/test_posix_file.cpp | 2 +- iceoryx_hoofs/test/moduletests/test_posix_types.cpp | 8 ++++---- .../vocabulary/include/iox/detail/semantic_string.inl | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 9d221bbf59..4a71311373 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -17,6 +17,7 @@ #include "iox/file.hpp" #include "iceoryx_hoofs/posix_wrapper/posix_call.hpp" #include "iceoryx_platform/attributes.hpp" +#include "iceoryx_platform/errno.hpp" #include "iceoryx_platform/fcntl.hpp" namespace iox diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 2fb0b0d1d4..676263068d 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -39,7 +39,7 @@ struct File_test : public Test { FilePath m_sut_file_path = [] { auto path = Path::create(platform::IOX_TEMP_DIR).expect("invalid temp dir"); - path.append("test-file").expect("invalid file name"); + path.append(iox::string<10>(TruncateToCapacity, "test-file")).expect("invalid file name"); return FilePath::create(path.as_string()).expect("invalid file path"); }(); diff --git a/iceoryx_hoofs/test/moduletests/test_posix_types.cpp b/iceoryx_hoofs/test/moduletests/test_posix_types.cpp index f64514e550..40ef3bc045 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_types.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_types.cpp @@ -39,10 +39,10 @@ TEST(TypesTest, ConvertToOflagFromAccessModeWorks) TEST(TypesTest, ConvertToProtflagFromAccessModeWorks) { ::testing::Test::RecordProperty("TEST_ID", "7a5c699e-16e6-471f-80b6-a325644e60d3"); - EXPECT_THAT(convertToOflags(AccessMode::READ_ONLY), Eq(PROT_READ)); - EXPECT_THAT(convertToOflags(AccessMode::READ_WRITE), Eq(PROT_READ | PROT_WRITE)); - EXPECT_THAT(convertToOflags(AccessMode::WRITE_ONLY), Eq(PROT_WRITE)); - EXPECT_THAT(convertToOflags(INVALID_ACCESS_MODE), Eq(PROT_NONE)); + EXPECT_THAT(convertToProtFlags(AccessMode::READ_ONLY), Eq(PROT_READ)); + EXPECT_THAT(convertToProtFlags(AccessMode::READ_WRITE), Eq(PROT_READ | PROT_WRITE)); + EXPECT_THAT(convertToProtFlags(AccessMode::WRITE_ONLY), Eq(PROT_WRITE)); + EXPECT_THAT(convertToProtFlags(INVALID_ACCESS_MODE), Eq(PROT_NONE)); } TEST(TypesTest, ConvertToOflagFromOpenModeWorks) diff --git a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl index 4826decd7c..642637aef5 100644 --- a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl +++ b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl @@ -50,7 +50,7 @@ SemanticString(SemanticStringError::ExceedsMaximumLength); } - auto str = string(TruncateToCapacity, value); + string str{TruncateToCapacity, value}; if (DoesContainInvalidCharacterCall(str)) { From 65929a5347ab5d6c663f220185ee321b7bdbfe10 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Tue, 11 Apr 2023 20:19:00 +0200 Subject: [PATCH 18/30] iox-#1962 Surpress out-of-bounds false positive for gcc 8.3 Signed-off-by: Christian Eltzschig --- .../vocabulary/include/iox/detail/semantic_string.inl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl index 642637aef5..f2e2071e4a 100644 --- a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl +++ b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl @@ -50,7 +50,18 @@ SemanticString(SemanticStringError::ExceedsMaximumLength); } + +// AXIVION DISABLE STYLE AutosarC++19_03-A16.0.1: pre-processor is required for setting gcc diagnostics, since gcc 8 incorrectly warns here about out of bo +// AXIVION DISABLE STYLE AutosarC++19_03-A16.7.1: see rule 'A16.0.1' above +#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif string str{TruncateToCapacity, value}; +#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3) +#pragma GCC diagnostic pop +#endif + if (DoesContainInvalidCharacterCall(str)) { From a02d9c2b3e2fa12082344025cfc4f1ee56c0781b Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 12 Apr 2023 12:02:32 +0200 Subject: [PATCH 19/30] iox-#1962 Surpress out-of-bounds false positive for gcc 8.3 Signed-off-by: Christian Eltzschig --- iceoryx_hoofs/test/moduletests/test_posix_file.cpp | 12 ++++++++++++ .../include/iox/detail/semantic_string.inl | 11 ----------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 676263068d..e5a4aef394 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -37,11 +37,23 @@ using namespace iox::units::duration_literals; struct File_test : public Test { +// AXIVION DISABLE STYLE AutosarC++19_03-A16.0.1: pre-processor is required for setting gcc diagnostics, since gcc 8 incorrectly warns here about out of bounds array access +// AXIVION DISABLE STYLE AutosarC++19_03-A16.7.1: see rule 'A16.0.1' above +#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif FilePath m_sut_file_path = [] { auto path = Path::create(platform::IOX_TEMP_DIR).expect("invalid temp dir"); path.append(iox::string<10>(TruncateToCapacity, "test-file")).expect("invalid file name"); return FilePath::create(path.as_string()).expect("invalid file path"); }(); +#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3) +#pragma GCC diagnostic pop +#endif + // AXIVION ENABLE STYLE AutosarC++19_03-A16.7.1 + // AXIVION ENABLE STYLE AutosarC++19_03-A16.0.1 + void SetUp() override { diff --git a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl index f2e2071e4a..642637aef5 100644 --- a/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl +++ b/iceoryx_hoofs/vocabulary/include/iox/detail/semantic_string.inl @@ -50,18 +50,7 @@ SemanticString(SemanticStringError::ExceedsMaximumLength); } - -// AXIVION DISABLE STYLE AutosarC++19_03-A16.0.1: pre-processor is required for setting gcc diagnostics, since gcc 8 incorrectly warns here about out of bo -// AXIVION DISABLE STYLE AutosarC++19_03-A16.7.1: see rule 'A16.0.1' above -#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif string str{TruncateToCapacity, value}; -#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3) -#pragma GCC diagnostic pop -#endif - if (DoesContainInvalidCharacterCall(str)) { From 4283eee8227522373b23be58269ab7e0d916f5a2 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 12 Apr 2023 18:14:20 +0200 Subject: [PATCH 20/30] iox-#1962 Add permission setting test Signed-off-by: Christian Eltzschig --- iceoryx_hoofs/test/moduletests/test_posix_file.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index e5a4aef394..197ef3c534 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -69,6 +69,20 @@ TEST_F(File_test, CreatingFileWorks) EXPECT_FALSE(sut.has_error()); } +TEST_F(File_test, CreatingWithPermissionsWorks) +{ + ::testing::Test::RecordProperty("TEST_ID", "fe16936a-2a10-4128-be56-01158943e251"); + + const auto perms = perms::owner_read | perms::group_exec; + FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).permissions(perms).create(m_sut_file_path); + + auto sut = FileBuilder().open_mode(OpenMode::OPEN_EXISTING).create(m_sut_file_path); + ASSERT_FALSE(sut.has_error()); + auto read_perms = sut->get_permissions().expect("failed to get permissions"); + + EXPECT_THAT(perms, Eq(read_perms)); +} + TEST_F(File_test, PurgeAndCreateRemovesExistingFile) { ::testing::Test::RecordProperty("TEST_ID", "f11e3aae-2e63-468f-b58a-22aeeedbd7fc"); From 5a2186025aac073a1046682734aaabb2f48eb294 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Wed, 12 Apr 2023 18:57:35 +0200 Subject: [PATCH 21/30] iox-#1962 Fix access mode and permission handling Signed-off-by: Christian Eltzschig --- .../posix/filesystem/source/file.cpp | 29 ++++++++++++++++++- .../test/moduletests/test_posix_file.cpp | 23 +++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 4a71311373..0427fc5e88 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -19,6 +19,7 @@ #include "iceoryx_platform/attributes.hpp" #include "iceoryx_platform/errno.hpp" #include "iceoryx_platform/fcntl.hpp" +#include "iox/filesystem.hpp" namespace iox { @@ -64,7 +65,33 @@ expected FileBuilder::open_impl(const bool print_error_ if (!result.has_error()) { - return iox::success(File(result.value().value, m_access_mode)); + File file(result.value().value, m_access_mode); + const auto perms = file.get_permissions(); + if (perms.has_error()) + { + IOX_LOG(ERROR) << "Unable to acquire the permissions of the file."; + return iox::error(FileCreationError::PermissionDenied); + } + + if (m_access_mode == posix::AccessMode::READ_ONLY || m_access_mode == posix::AccessMode::READ_WRITE) + { + if ((perms->value() & perms::owner_read.value()) == 0) + { + IOX_LOG(ERROR) << "Unable to open/create file due to insufficient read permissions."; + return iox::error(FileCreationError::PermissionDenied); + } + } + + if (m_access_mode == posix::AccessMode::WRITE_ONLY || m_access_mode == posix::AccessMode::READ_WRITE) + { + if ((perms->value() & perms::owner_write.value()) == 0) + { + IOX_LOG(ERROR) << "Unable to open/create file due to insufficient write permissions."; + return iox::error(FileCreationError::PermissionDenied); + } + } + + return iox::success(std::move(file)); } switch (result.get_error().errnum) diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 197ef3c534..59516280a2 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -74,7 +74,8 @@ TEST_F(File_test, CreatingWithPermissionsWorks) ::testing::Test::RecordProperty("TEST_ID", "fe16936a-2a10-4128-be56-01158943e251"); const auto perms = perms::owner_read | perms::group_exec; - FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).permissions(perms).create(m_sut_file_path); + ASSERT_FALSE( + FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).permissions(perms).create(m_sut_file_path).has_error()); auto sut = FileBuilder().open_mode(OpenMode::OPEN_EXISTING).create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -89,6 +90,7 @@ TEST_F(File_test, PurgeAndCreateRemovesExistingFile) { auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write | perms::owner_read) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); EXPECT_FALSE(sut.has_error()); @@ -153,8 +155,11 @@ TEST_F(File_test, OpenOrCreateOpensExistingFile) TEST_F(File_test, OpenFileForReadingWithInsufficientPermissionFails) { ::testing::Test::RecordProperty("TEST_ID", "58843f37-0474-49b1-9228-207391346f70"); - auto sut = - FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).permissions(perms::owner_write).create(m_sut_file_path); + auto sut = FileBuilder() + .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write) + .access_mode(AccessMode::WRITE_ONLY) + .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); auto sut2 = @@ -207,6 +212,7 @@ TEST_F(File_test, ReadAndWriteToFileWorks) const std::array test_content{12, 14, 18, 19, 22, 90, 200, 1}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write | perms::owner_read) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -228,6 +234,7 @@ TEST_F(File_test, ReadingOfAWriteOnlyFileFails) auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write) .access_mode(posix::AccessMode::WRITE_ONLY) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -245,6 +252,7 @@ TEST_F(File_test, ReadingWithSmallerBufferSizeWorks) const std::array test_content{112, 114, 118, 119, 122, 190, 100, 101}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write | perms::owner_read) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -268,6 +276,7 @@ TEST_F(File_test, ReadingWithLargerBufferSizeWorks) const std::array test_content{212, 214}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write | perms::owner_read) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -291,6 +300,7 @@ TEST_F(File_test, ReadingWithOffsetWorks) const std::array test_content{112, 114, 118, 119, 122, 190, 100, 101}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write | perms::owner_read) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -314,6 +324,7 @@ TEST_F(File_test, ReadingWithOutOfBoundsOffsetReadsNothing) const std::array test_content{122, 190, 100, 101}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_write | perms::owner_read) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -336,6 +347,7 @@ TEST_F(File_test, WritingIntoAReadOnlyFileFails) const std::array test_content{122, 190, 100, 101}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_read) .access_mode(posix::AccessMode::READ_ONLY) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -352,6 +364,7 @@ TEST_F(File_test, WriteAtOverridesContent) const std::array test_content{122, 190, 100, 101}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_read | perms::owner_write) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -379,6 +392,7 @@ TEST_F(File_test, WriteWithOutOfBoundsOffsetAddsZerosInBetween) const std::array test_content{240, 250}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_read | perms::owner_write) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -406,6 +420,7 @@ TEST_F(File_test, MoveConstructedFileWorks) const std::array test_content{242, 252}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_read | perms::owner_write) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -431,6 +446,7 @@ TEST_F(File_test, MoveAssignedFileWorks) const std::array test_content{244, 254}; auto sut = FileBuilder() .open_mode(OpenMode::PURGE_AND_CREATE) + .permissions(perms::owner_read | perms::owner_write) .access_mode(posix::AccessMode::READ_WRITE) .create(m_sut_file_path); ASSERT_FALSE(sut.has_error()); @@ -442,6 +458,7 @@ TEST_F(File_test, MoveAssignedFileWorks) File sut2{std::move(sut.value())}; auto sut3 = FileBuilder() .open_mode(OpenMode::OPEN_EXISTING) + .permissions(perms::owner_read) .access_mode(posix::AccessMode::READ_ONLY) .create(m_sut_file_path); ASSERT_FALSE(sut3.has_error()); From 93b511a1d05a6f45445da16a00fd42fb96203d5e Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 13 Apr 2023 12:21:36 +0200 Subject: [PATCH 22/30] iox-#1962 Fix removing file with wrong syscall Signed-off-by: Christian Eltzschig --- .../posix/filesystem/source/file.cpp | 3 ++- .../linux/include/iceoryx_platform/stdio.hpp | 26 +++++++++++++++++++ iceoryx_platform/linux/source/unistd.cpp | 5 ---- .../mac/include/iceoryx_platform/stdio.hpp | 26 +++++++++++++++++++ .../qnx/include/iceoryx_platform/stdio.hpp | 26 +++++++++++++++++++ .../unix/include/iceoryx_platform/stdio.hpp | 26 +++++++++++++++++++ .../win/include/iceoryx_platform/stdio.hpp | 26 +++++++++++++++++++ 7 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 iceoryx_platform/linux/include/iceoryx_platform/stdio.hpp create mode 100644 iceoryx_platform/mac/include/iceoryx_platform/stdio.hpp create mode 100644 iceoryx_platform/qnx/include/iceoryx_platform/stdio.hpp create mode 100644 iceoryx_platform/unix/include/iceoryx_platform/stdio.hpp create mode 100644 iceoryx_platform/win/include/iceoryx_platform/stdio.hpp diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 0427fc5e88..c907ce51fb 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -19,6 +19,7 @@ #include "iceoryx_platform/attributes.hpp" #include "iceoryx_platform/errno.hpp" #include "iceoryx_platform/fcntl.hpp" +#include "iceoryx_platform/stdio.hpp" #include "iox/filesystem.hpp" namespace iox @@ -243,7 +244,7 @@ expected File::does_exist(const FilePath& file) noexcept expected File::remove(const FilePath& file) noexcept { - auto result = posix::posixCall(iox_unlink)(file.as_string().c_str()) + auto result = posix::posixCall(iox_remove)(file.as_string().c_str()) .failureReturnValue(-1) .suppressErrorMessagesForErrnos(ENOENT) .evaluate(); diff --git a/iceoryx_platform/linux/include/iceoryx_platform/stdio.hpp b/iceoryx_platform/linux/include/iceoryx_platform/stdio.hpp new file mode 100644 index 0000000000..5240e7c17e --- /dev/null +++ b/iceoryx_platform/linux/include/iceoryx_platform/stdio.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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_HOOFS_LINUX_PLATFORM_STDIO_HPP +#define IOX_HOOFS_LINUX_PLATFORM_STDIO_HPP + +#include + +int iox_remove(const char* pathname) +{ + return remove(pathname); +} + +#endif diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index 34df0f7844..ca32d2ae51 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -47,8 +47,3 @@ iox_ssize_t iox_read(int fd, void* buf, size_t count) { return read(fd, buf, count); } - -iox_ssize_t iox_write(int fd, const void* buf, size_t count) -{ - return write(fd, buf, count); -} diff --git a/iceoryx_platform/mac/include/iceoryx_platform/stdio.hpp b/iceoryx_platform/mac/include/iceoryx_platform/stdio.hpp new file mode 100644 index 0000000000..73d91d6bf1 --- /dev/null +++ b/iceoryx_platform/mac/include/iceoryx_platform/stdio.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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_HOOFS_MAC_PLATFORM_STDIO_HPP +#define IOX_HOOFS_MAC_PLATFORM_STDIO_HPP + +#include + +int iox_remove(const char* pathname) +{ + return remove(pathname); +} + +#endif diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/stdio.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/stdio.hpp new file mode 100644 index 0000000000..1c2c9fa691 --- /dev/null +++ b/iceoryx_platform/qnx/include/iceoryx_platform/stdio.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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_HOOFS_QNX_PLATFORM_STDIO_HPP +#define IOX_HOOFS_QNX_PLATFORM_STDIO_HPP + +#include + +int iox_remove(const char* pathname) +{ + return remove(pathname); +} + +#endif diff --git a/iceoryx_platform/unix/include/iceoryx_platform/stdio.hpp b/iceoryx_platform/unix/include/iceoryx_platform/stdio.hpp new file mode 100644 index 0000000000..a7c9f9a674 --- /dev/null +++ b/iceoryx_platform/unix/include/iceoryx_platform/stdio.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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_HOOFS_UNIX_PLATFORM_STDIO_HPP +#define IOX_HOOFS_UNIX_PLATFORM_STDIO_HPP + +#include + +int iox_remove(const char* pathname) +{ + return remove(pathname); +} + +#endif diff --git a/iceoryx_platform/win/include/iceoryx_platform/stdio.hpp b/iceoryx_platform/win/include/iceoryx_platform/stdio.hpp new file mode 100644 index 0000000000..260479d7c3 --- /dev/null +++ b/iceoryx_platform/win/include/iceoryx_platform/stdio.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2023 by Apex.AI Inc. 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_HOOFS_WIN_PLATFORM_STDIO_HPP +#define IOX_HOOFS_WIN_PLATFORM_STDIO_HPP + +#include + +int iox_remove(const char* pathname) +{ + return remove(pathname); +} + +#endif From 3fd6985ebb45431ce6dc17e8e3e7f226feaa387f Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 13 Apr 2023 12:28:41 +0200 Subject: [PATCH 23/30] iox-#1962 Add cstdio as used platform header Signed-off-by: Christian Eltzschig --- iceoryx_platform/linux/source/unistd.cpp | 5 +++++ tools/scripts/used-headers.txt | 1 + 2 files changed, 6 insertions(+) diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index ca32d2ae51..34df0f7844 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -47,3 +47,8 @@ iox_ssize_t iox_read(int fd, void* buf, size_t count) { return read(fd, buf, count); } + +iox_ssize_t iox_write(int fd, const void* buf, size_t count) +{ + return write(fd, buf, count); +} diff --git a/tools/scripts/used-headers.txt b/tools/scripts/used-headers.txt index a4fb090b62..e297dad8ff 100644 --- a/tools/scripts/used-headers.txt +++ b/tools/scripts/used-headers.txt @@ -2,6 +2,7 @@ arpa/inet.h climits cstdint +cstdio dlfcn.h errno.h fcntl.h From 0ecd12ac5db3405f7da4651aa0e4efe7b65a5b32 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Thu, 13 Apr 2023 15:07:43 +0200 Subject: [PATCH 24/30] iox-#1962 Fix windows platform Signed-off-by: Christian Eltzschig --- .../test/moduletests/test_posix_file.cpp | 13 +++++++++- .../win/include/iceoryx_platform/stat.hpp | 5 +++- iceoryx_platform/win/source/fnctl.cpp | 24 +++++-------------- iceoryx_platform/win/source/unistd.cpp | 14 +---------- 4 files changed, 23 insertions(+), 33 deletions(-) diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 59516280a2..3c126ccbf6 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -69,6 +69,7 @@ TEST_F(File_test, CreatingFileWorks) EXPECT_FALSE(sut.has_error()); } +#ifndef _WIN32 TEST_F(File_test, CreatingWithPermissionsWorks) { ::testing::Test::RecordProperty("TEST_ID", "fe16936a-2a10-4128-be56-01158943e251"); @@ -83,6 +84,7 @@ TEST_F(File_test, CreatingWithPermissionsWorks) EXPECT_THAT(perms, Eq(read_perms)); } +#endif TEST_F(File_test, PurgeAndCreateRemovesExistingFile) { @@ -152,6 +154,7 @@ TEST_F(File_test, OpenOrCreateOpensExistingFile) ASSERT_FALSE(sut2.has_error()); } +#ifndef _WIN32 TEST_F(File_test, OpenFileForReadingWithInsufficientPermissionFails) { ::testing::Test::RecordProperty("TEST_ID", "58843f37-0474-49b1-9228-207391346f70"); @@ -180,6 +183,7 @@ TEST_F(File_test, OpenFileForReadWriteWithInsufficientPermissionFails) ASSERT_TRUE(sut2.has_error()); EXPECT_THAT(sut2.get_error(), Eq(FileCreationError::PermissionDenied)); } +#endif TEST_F(File_test, AfterCreationTheFileExists) { @@ -194,7 +198,10 @@ TEST_F(File_test, RemoveReturnsTrueWhenFileExist) { ::testing::Test::RecordProperty("TEST_ID", "64123a2d-4350-4969-80ce-d66e7433ed22"); - auto sut = FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path); + { + EXPECT_FALSE(FileBuilder().open_mode(OpenMode::PURGE_AND_CREATE).create(m_sut_file_path).has_error()); + } + EXPECT_TRUE(File::remove(m_sut_file_path).value()); } @@ -228,6 +235,7 @@ TEST_F(File_test, ReadAndWriteToFileWorks) EXPECT_THAT(read_content, Eq(test_content)); } +#ifndef _WIN32 TEST_F(File_test, ReadingOfAWriteOnlyFileFails) { ::testing::Test::RecordProperty("TEST_ID", "4a404243-33fb-4c28-9e7b-58980f6918a3"); @@ -244,6 +252,7 @@ TEST_F(File_test, ReadingOfAWriteOnlyFileFails) ASSERT_TRUE(read.has_error()); EXPECT_THAT(read.get_error(), Eq(FileReadError::NotOpenedForReading)); } +#endif TEST_F(File_test, ReadingWithSmallerBufferSizeWorks) { @@ -340,6 +349,7 @@ TEST_F(File_test, ReadingWithOutOfBoundsOffsetReadsNothing) EXPECT_THAT(*read, Eq(0)); } +#ifndef _WIN32 TEST_F(File_test, WritingIntoAReadOnlyFileFails) { ::testing::Test::RecordProperty("TEST_ID", "dba3d6b3-c09b-4bbe-acb4-22f20abdc9b9"); @@ -356,6 +366,7 @@ TEST_F(File_test, WritingIntoAReadOnlyFileFails) ASSERT_TRUE(result.has_error()); EXPECT_THAT(result.get_error(), Eq(FileWriteError::NotOpenedForWriting)); } +#endif TEST_F(File_test, WriteAtOverridesContent) { diff --git a/iceoryx_platform/win/include/iceoryx_platform/stat.hpp b/iceoryx_platform/win/include/iceoryx_platform/stat.hpp index a01a971c5f..9959cdca0d 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/stat.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/stat.hpp @@ -18,6 +18,7 @@ #define IOX_HOOFS_WIN_PLATFORM_STAT_HPP #include +#include #include #define S_IRUSR 0 @@ -36,7 +37,9 @@ using iox_mode_t = int; inline int iox_fstat(int fildes, iox_stat* buf) { - return _fstat(fildes, buf); + int ret_val = _fstat(fildes, buf); + buf->st_mode = std::numeric_limitsst_mode)>::max(); + return ret_val; } inline int iox_fchmod(int fildes, iox_mode_t mode) diff --git a/iceoryx_platform/win/source/fnctl.cpp b/iceoryx_platform/win/source/fnctl.cpp index 4a4992d98e..a956b23662 100644 --- a/iceoryx_platform/win/source/fnctl.cpp +++ b/iceoryx_platform/win/source/fnctl.cpp @@ -14,30 +14,18 @@ // // SPDX-License-Identifier: Apache-2.0 +#include + #include "iceoryx_platform/fcntl.hpp" #include "iceoryx_platform/handle_translator.hpp" #include "iceoryx_platform/win32_errorHandling.hpp" +#include "iceoryx_platform/windows.hpp" int iox_open(const char* pathname, int flags, mode_t mode) { - auto handle = Win32Call(CreateFileA, - pathname, - GENERIC_WRITE, - 0, - static_cast(NULL), - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - static_cast(NULL)) - .value; - - if (handle == INVALID_HANDLE_VALUE) - { - fprintf(stderr, "unable to create file \"%s\"\n", pathname); - errno = EWOULDBLOCK; - return -1; - } - - return HandleTranslator::getInstance().add(handle); + int fd; + _sopen_s(&fd, pathname, flags, _SH_DENYNO, _S_IREAD | _S_IWRITE); + return fd; } int iox_fcntl2(int, int) diff --git a/iceoryx_platform/win/source/unistd.cpp b/iceoryx_platform/win/source/unistd.cpp index 0f87317a7d..84a5c67c93 100644 --- a/iceoryx_platform/win/source/unistd.cpp +++ b/iceoryx_platform/win/source/unistd.cpp @@ -47,19 +47,7 @@ long sysconf(int name) int iox_close(int fd) { - HANDLE handle = HandleTranslator::getInstance().get(fd); - if (handle == nullptr) - { - return 0; - } - - auto success = Win32Call(CloseHandle, handle).value; - HandleTranslator::getInstance().remove(fd); - if (success == 0) - { - return -1; - } - return 0; + return _close(fd); } int iox_fchown(int fd, uid_t owner, gid_t group) From bae5026b1c355b22d1f2e032ba78a16eac2c4209 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 14 Apr 2023 13:00:06 +0200 Subject: [PATCH 25/30] iox-#1962 Fix issue where different close variants exists for file handles on windows Signed-off-by: Christian Eltzschig --- .../shared_memory_object/shared_memory.cpp | 2 +- .../linux/include/iceoryx_platform/mman.hpp | 1 + iceoryx_platform/linux/source/mman.cpp | 7 +++++++ .../mac/include/iceoryx_platform/mman.hpp | 1 + iceoryx_platform/mac/source/mman.cpp | 6 ++++++ .../qnx/include/iceoryx_platform/mman.hpp | 1 + iceoryx_platform/qnx/source/mman.cpp | 7 +++++++ .../unix/include/iceoryx_platform/mman.hpp | 1 + iceoryx_platform/unix/source/mman.cpp | 7 +++++++ .../win/include/iceoryx_platform/mman.hpp | 2 ++ iceoryx_platform/win/source/mman.cpp | 17 +++++++++++++++++ 11 files changed, 51 insertions(+), 1 deletion(-) diff --git a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp index 8fba125fa5..b805c5961d 100644 --- a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp @@ -132,7 +132,7 @@ expected SharedMemoryBuilder::create() noexcept { printError(); - posixCall(iox_close)(sharedMemoryFileHandle) + posixCall(iox_shm_close)(sharedMemoryFileHandle) .failureReturnValue(SharedMemory::INVALID_HANDLE) .evaluate() .or_else([&](auto& r) { diff --git a/iceoryx_platform/linux/include/iceoryx_platform/mman.hpp b/iceoryx_platform/linux/include/iceoryx_platform/mman.hpp index 6d1c44b453..1c6bd09765 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/mman.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/mman.hpp @@ -21,5 +21,6 @@ int iox_shm_open(const char* name, int oflag, mode_t mode); int iox_shm_unlink(const char* name); +int iox_shm_close(int fd); #endif // IOX_HOOFS_LINUX_PLATFORM_MMAN_HPP diff --git a/iceoryx_platform/linux/source/mman.cpp b/iceoryx_platform/linux/source/mman.cpp index 7c79713177..f2a161a9a5 100644 --- a/iceoryx_platform/linux/source/mman.cpp +++ b/iceoryx_platform/linux/source/mman.cpp @@ -16,6 +16,8 @@ #include "iceoryx_platform/mman.hpp" +#include + // NOLINTNEXTLINE(readability-identifier-naming) int iox_shm_open(const char* name, int oflag, mode_t mode) { @@ -27,3 +29,8 @@ int iox_shm_unlink(const char* name) { return shm_unlink(name); } + +int iox_shm_close(int fd) +{ + return close(fd); +} diff --git a/iceoryx_platform/mac/include/iceoryx_platform/mman.hpp b/iceoryx_platform/mac/include/iceoryx_platform/mman.hpp index 0fc8cfa8bf..5bf17f5f47 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/mman.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/mman.hpp @@ -21,5 +21,6 @@ int iox_shm_open(const char* name, int oflag, mode_t mode); int iox_shm_unlink(const char* name); +int iox_shm_close(int fd); #endif // IOX_HOOFS_MAC_PLATFORM_MMAN_HPP diff --git a/iceoryx_platform/mac/source/mman.cpp b/iceoryx_platform/mac/source/mman.cpp index 3b0871abe0..3c517aff7f 100644 --- a/iceoryx_platform/mac/source/mman.cpp +++ b/iceoryx_platform/mac/source/mman.cpp @@ -18,6 +18,7 @@ #include #include +#include int iox_shm_open(const char* name, int oflag, mode_t mode) { @@ -37,3 +38,8 @@ int iox_shm_unlink(const char* name) } return state; } + +int iox_shm_close(int fd) +{ + return close(fd); +} diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/mman.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/mman.hpp index e1ba26da95..1e41d510c6 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/mman.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/mman.hpp @@ -21,5 +21,6 @@ int iox_shm_open(const char* name, int oflag, mode_t mode); int iox_shm_unlink(const char* name); +int iox_shm_close(int fd); #endif // IOX_HOOFS_QNX_PLATFORM_MMAN_HPP diff --git a/iceoryx_platform/qnx/source/mman.cpp b/iceoryx_platform/qnx/source/mman.cpp index 8f543404f1..ccd1a0098b 100644 --- a/iceoryx_platform/qnx/source/mman.cpp +++ b/iceoryx_platform/qnx/source/mman.cpp @@ -16,6 +16,8 @@ #include "iceoryx_platform/mman.hpp" +#include + int iox_shm_open(const char* name, int oflag, mode_t mode) { return shm_open(name, oflag, mode); @@ -25,3 +27,8 @@ int iox_shm_unlink(const char* name) { return shm_unlink(name); } + +int iox_shm_close(int fd) +{ + return close(fd); +} diff --git a/iceoryx_platform/unix/include/iceoryx_platform/mman.hpp b/iceoryx_platform/unix/include/iceoryx_platform/mman.hpp index aa8774f265..63d6f04c98 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/mman.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/mman.hpp @@ -21,5 +21,6 @@ int iox_shm_open(const char* name, int oflag, mode_t mode); int iox_shm_unlink(const char* name); +int iox_shm_close(int fd); #endif // IOX_HOOFS_UNIX_PLATFORM_MMAN_HPP diff --git a/iceoryx_platform/unix/source/mman.cpp b/iceoryx_platform/unix/source/mman.cpp index 7c79713177..f2a161a9a5 100644 --- a/iceoryx_platform/unix/source/mman.cpp +++ b/iceoryx_platform/unix/source/mman.cpp @@ -16,6 +16,8 @@ #include "iceoryx_platform/mman.hpp" +#include + // NOLINTNEXTLINE(readability-identifier-naming) int iox_shm_open(const char* name, int oflag, mode_t mode) { @@ -27,3 +29,8 @@ int iox_shm_unlink(const char* name) { return shm_unlink(name); } + +int iox_shm_close(int fd) +{ + return close(fd); +} diff --git a/iceoryx_platform/win/include/iceoryx_platform/mman.hpp b/iceoryx_platform/win/include/iceoryx_platform/mman.hpp index fda5abc56d..2a5843465d 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/mman.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/mman.hpp @@ -45,4 +45,6 @@ int munmap(void* addr, size_t length); int iox_shm_open(const char* name, int oflag, mode_t mode); int iox_shm_unlink(const char* name); + +int iox_shm_close(int fd); #endif // IOX_HOOFS_WIN_PLATFORM_MMAN_HPP diff --git a/iceoryx_platform/win/source/mman.cpp b/iceoryx_platform/win/source/mman.cpp index 0dcd2296fb..ab9fb44e2e 100644 --- a/iceoryx_platform/win/source/mman.cpp +++ b/iceoryx_platform/win/source/mman.cpp @@ -172,3 +172,20 @@ int iox_shm_unlink(const char* name) errno = ENOENT; return -1; } + +int iox_shm_close(int fd) +{ + HANDLE handle = HandleTranslator::getInstance().get(fd); + if (handle == nullptr) + { + return 0; + } + + auto success = Win32Call(CloseHandle, handle).value; + HandleTranslator::getInstance().remove(fd); + if (success == 0) + { + return -1; + } + return 0; +} From 4b193c80c0970b242c65bf98f9fb0bffa3347dd5 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 14 Apr 2023 14:23:06 +0200 Subject: [PATCH 26/30] iox-#1962 Add iox_ext_open to support various file handling APIs, important for windows Signed-off-by: Christian Eltzschig --- .../source/posix_wrapper/file_lock.cpp | 12 +++++----- .../linux/include/iceoryx_platform/fcntl.hpp | 1 + .../linux/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/linux/source/fnctl.cpp | 5 +++++ iceoryx_platform/linux/source/unistd.cpp | 5 +++++ .../mac/include/iceoryx_platform/fcntl.hpp | 1 + .../mac/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/mac/source/fnctl.cpp | 5 +++++ iceoryx_platform/mac/source/unistd.cpp | 5 +++++ .../qnx/include/iceoryx_platform/fcntl.hpp | 1 + .../qnx/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/qnx/source/fnctl.cpp | 5 +++++ iceoryx_platform/qnx/source/unistd.cpp | 5 +++++ .../unix/include/iceoryx_platform/fcntl.hpp | 1 + .../unix/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/unix/source/fnctl.cpp | 5 +++++ iceoryx_platform/unix/source/unistd.cpp | 5 +++++ .../win/include/iceoryx_platform/fcntl.hpp | 1 + .../win/include/iceoryx_platform/unistd.hpp | 1 + iceoryx_platform/win/source/fnctl.cpp | 22 +++++++++++++++++++ iceoryx_platform/win/source/unistd.cpp | 17 ++++++++++++++ 21 files changed, 95 insertions(+), 6 deletions(-) diff --git a/iceoryx_hoofs/source/posix_wrapper/file_lock.cpp b/iceoryx_hoofs/source/posix_wrapper/file_lock.cpp index 47d62d63c8..ffce169b4c 100644 --- a/iceoryx_hoofs/source/posix_wrapper/file_lock.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/file_lock.cpp @@ -57,9 +57,9 @@ expected FileLockBuilder::create() noexcept fileLockPath.unsafe_append(m_name); fileLockPath.unsafe_append(FileLock::LOCK_FILE_SUFFIX); - auto openCall = posixCall(iox_open)(fileLockPath.c_str(), - convertToOflags(AccessMode::READ_ONLY, OpenMode::OPEN_OR_CREATE), - m_permission.value()) + auto openCall = posixCall(iox_ext_open)(fileLockPath.c_str(), + convertToOflags(AccessMode::READ_ONLY, OpenMode::OPEN_OR_CREATE), + m_permission.value()) .failureReturnValue(-1) .evaluate(); @@ -76,13 +76,13 @@ expected FileLockBuilder::create() noexcept if (lockCall.has_error()) { - posixCall(iox_close)(fileDescriptor).failureReturnValue(-1).evaluate().or_else([&](auto& result) { + posixCall(iox_ext_close)(fileDescriptor).failureReturnValue(-1).evaluate().or_else([&](auto& result) { IOX_DISCARD_RESULT(FileLock::convertErrnoToFileLockError(result.errnum, fileLockPath)); IOX_LOG(ERROR) << "Unable to close file lock \"" << fileLockPath << "\" in error related cleanup during initialization."; }); - // possible errors in iox_close() are masked and we inform the user about the actual error + // possible errors in iox_ext_close() are masked and we inform the user about the actual error return error(FileLock::convertErrnoToFileLockError(lockCall.get_error().errnum, fileLockPath)); } @@ -142,7 +142,7 @@ expected FileLock::closeFileDescriptor() noexcept IOX_LOG(ERROR) << "Unable to unlock the file lock \"" << m_fileLockPath << "\""; }); - posixCall(iox_close)(m_fd).failureReturnValue(-1).evaluate().or_else([&](auto& result) { + posixCall(iox_ext_close)(m_fd).failureReturnValue(-1).evaluate().or_else([&](auto& result) { cleanupFailed = true; IOX_DISCARD_RESULT(FileLock::convertErrnoToFileLockError(result.errnum, m_fileLockPath)); IOX_LOG(ERROR) << "Unable to close the file handle to the file lock \"" << m_fileLockPath << "\""; diff --git a/iceoryx_platform/linux/include/iceoryx_platform/fcntl.hpp b/iceoryx_platform/linux/include/iceoryx_platform/fcntl.hpp index 7a4ccace47..f55c168b9c 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/fcntl.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/fcntl.hpp @@ -20,6 +20,7 @@ #include int iox_open(const char* pathname, int flags, mode_t mode); +int iox_ext_open(const char* pathname, int flags, mode_t mode); int iox_fcntl2(int fd, int cmd); int iox_fcntl3(int fd, int cmd, int flags); diff --git a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp index db49988f0e..21e9493e90 100644 --- a/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/linux/include/iceoryx_platform/unistd.hpp @@ -25,6 +25,7 @@ using iox_off_t = off_t; using iox_ssize_t = ssize_t; int iox_close(int fd); +int iox_ext_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); diff --git a/iceoryx_platform/linux/source/fnctl.cpp b/iceoryx_platform/linux/source/fnctl.cpp index 5ecad499d7..678be850bb 100644 --- a/iceoryx_platform/linux/source/fnctl.cpp +++ b/iceoryx_platform/linux/source/fnctl.cpp @@ -22,6 +22,11 @@ int iox_open(const char* pathname, int flags, mode_t mode) return open(pathname, flags, mode); } +int iox_ext_open(const char* pathname, int flags, mode_t mode) +{ + return open(pathname, flags, mode); +} + int iox_fcntl2(int fd, int cmd) { return fcntl(fd, cmd); diff --git a/iceoryx_platform/linux/source/unistd.cpp b/iceoryx_platform/linux/source/unistd.cpp index 34df0f7844..1ce62b9ed8 100644 --- a/iceoryx_platform/linux/source/unistd.cpp +++ b/iceoryx_platform/linux/source/unistd.cpp @@ -23,6 +23,11 @@ int iox_close(int fd) return close(fd); } +int iox_ext_close(int fd) +{ + return close(fd); +} + int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); diff --git a/iceoryx_platform/mac/include/iceoryx_platform/fcntl.hpp b/iceoryx_platform/mac/include/iceoryx_platform/fcntl.hpp index 07e38515b9..63c35a96c7 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/fcntl.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/fcntl.hpp @@ -20,6 +20,7 @@ #include int iox_open(const char* pathname, int flags, mode_t mode); +int iox_ext_open(const char* pathname, int flags, mode_t mode); int iox_fcntl2(int fd, int cmd); int iox_fcntl3(int fd, int cmd, int flags); diff --git a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp index adb430ab6d..81c592b917 100644 --- a/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/mac/include/iceoryx_platform/unistd.hpp @@ -24,6 +24,7 @@ using iox_off_t = off_t; using iox_ssize_t = ssize_t; int iox_close(int fd); +int iox_ext_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); diff --git a/iceoryx_platform/mac/source/fnctl.cpp b/iceoryx_platform/mac/source/fnctl.cpp index acc98889ae..7c8fd9e975 100644 --- a/iceoryx_platform/mac/source/fnctl.cpp +++ b/iceoryx_platform/mac/source/fnctl.cpp @@ -21,6 +21,11 @@ int iox_open(const char* pathname, int flags, mode_t mode) return open(pathname, flags, mode); } +int iox_ext_open(const char* pathname, int flags, mode_t mode) +{ + return open(pathname, flags, mode); +} + int iox_fcntl2(int fd, int cmd) { return fcntl(fd, cmd); diff --git a/iceoryx_platform/mac/source/unistd.cpp b/iceoryx_platform/mac/source/unistd.cpp index 3b28259c48..770ff909ca 100644 --- a/iceoryx_platform/mac/source/unistd.cpp +++ b/iceoryx_platform/mac/source/unistd.cpp @@ -22,6 +22,11 @@ int iox_close(int fd) return close(fd); } +int iox_ext_close(int fd) +{ + return close(fd); +} + int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/fcntl.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/fcntl.hpp index 9aea81616d..7e3c464932 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/fcntl.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/fcntl.hpp @@ -20,6 +20,7 @@ #include int iox_open(const char* pathname, int flags, mode_t mode); +int iox_ext_open(const char* pathname, int flags, mode_t mode); int iox_fcntl2(int fd, int cmd); int iox_fcntl3(int fd, int cmd, int flags); diff --git a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp index 345ea4018f..06bf696c0c 100644 --- a/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/qnx/include/iceoryx_platform/unistd.hpp @@ -24,6 +24,7 @@ using iox_off_t = off_t; using iox_ssize_t = ssize_t; int iox_close(int fd); +int iox_ext_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); diff --git a/iceoryx_platform/qnx/source/fnctl.cpp b/iceoryx_platform/qnx/source/fnctl.cpp index acc98889ae..7c8fd9e975 100644 --- a/iceoryx_platform/qnx/source/fnctl.cpp +++ b/iceoryx_platform/qnx/source/fnctl.cpp @@ -21,6 +21,11 @@ int iox_open(const char* pathname, int flags, mode_t mode) return open(pathname, flags, mode); } +int iox_ext_open(const char* pathname, int flags, mode_t mode) +{ + return open(pathname, flags, mode); +} + int iox_fcntl2(int fd, int cmd) { return fcntl(fd, cmd); diff --git a/iceoryx_platform/qnx/source/unistd.cpp b/iceoryx_platform/qnx/source/unistd.cpp index 3b28259c48..770ff909ca 100644 --- a/iceoryx_platform/qnx/source/unistd.cpp +++ b/iceoryx_platform/qnx/source/unistd.cpp @@ -22,6 +22,11 @@ int iox_close(int fd) return close(fd); } +int iox_ext_close(int fd) +{ + return close(fd); +} + int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); diff --git a/iceoryx_platform/unix/include/iceoryx_platform/fcntl.hpp b/iceoryx_platform/unix/include/iceoryx_platform/fcntl.hpp index 1b28661b93..dde0dc1145 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/fcntl.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/fcntl.hpp @@ -20,6 +20,7 @@ #include int iox_open(const char* pathname, int flags, mode_t mode); +int iox_ext_open(const char* pathname, int flags, mode_t mode); int iox_fcntl2(int fd, int cmd); int iox_fcntl3(int fd, int cmd, int flags); diff --git a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp index 172d1327ec..738cba7d44 100644 --- a/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/unix/include/iceoryx_platform/unistd.hpp @@ -24,6 +24,7 @@ using iox_off_t = off_t; using iox_ssize_t = ssize_t; int iox_close(int fd); +int iox_ext_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); diff --git a/iceoryx_platform/unix/source/fnctl.cpp b/iceoryx_platform/unix/source/fnctl.cpp index 5ecad499d7..678be850bb 100644 --- a/iceoryx_platform/unix/source/fnctl.cpp +++ b/iceoryx_platform/unix/source/fnctl.cpp @@ -22,6 +22,11 @@ int iox_open(const char* pathname, int flags, mode_t mode) return open(pathname, flags, mode); } +int iox_ext_open(const char* pathname, int flags, mode_t mode) +{ + return open(pathname, flags, mode); +} + int iox_fcntl2(int fd, int cmd) { return fcntl(fd, cmd); diff --git a/iceoryx_platform/unix/source/unistd.cpp b/iceoryx_platform/unix/source/unistd.cpp index 34df0f7844..1ce62b9ed8 100644 --- a/iceoryx_platform/unix/source/unistd.cpp +++ b/iceoryx_platform/unix/source/unistd.cpp @@ -23,6 +23,11 @@ int iox_close(int fd) return close(fd); } +int iox_ext_close(int fd) +{ + return close(fd); +} + int iox_fchown(int fd, uid_t owner, gid_t group) { return fchown(fd, owner, group); diff --git a/iceoryx_platform/win/include/iceoryx_platform/fcntl.hpp b/iceoryx_platform/win/include/iceoryx_platform/fcntl.hpp index fc45de1ea1..f9410ddeac 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/fcntl.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/fcntl.hpp @@ -35,6 +35,7 @@ #define F_SETFL 4 int iox_open(const char* pathname, int flags, mode_t mode); +int iox_ext_open(const char* pathname, int flags, mode_t mode); int iox_fcntl2(int fd, int cmd); int iox_fcntl3(int fd, int cmd, int flags); diff --git a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp index dda1ed89e1..87085e39e1 100644 --- a/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp +++ b/iceoryx_platform/win/include/iceoryx_platform/unistd.hpp @@ -40,6 +40,7 @@ using iox_ssize_t = int; int ftruncate(int fildes, off_t length); long sysconf(int name); int iox_close(int fd); +int iox_ext_close(int fd); int iox_fchown(int fd, uid_t owner, gid_t group); int iox_access(const char* pathname, int mode); int iox_unlink(const char* pathname); diff --git a/iceoryx_platform/win/source/fnctl.cpp b/iceoryx_platform/win/source/fnctl.cpp index a956b23662..442ea1b91c 100644 --- a/iceoryx_platform/win/source/fnctl.cpp +++ b/iceoryx_platform/win/source/fnctl.cpp @@ -28,6 +28,28 @@ int iox_open(const char* pathname, int flags, mode_t mode) return fd; } +int iox_ext_open(const char* pathname, int flags, mode_t mode) +{ + auto handle = Win32Call(CreateFileA, + pathname, + GENERIC_WRITE, + 0, + static_cast(NULL), + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + static_cast(NULL)) + .value; + + if (handle == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "unable to create file \"%s\"\n", pathname); + errno = EWOULDBLOCK; + return -1; + } + + return HandleTranslator::getInstance().add(handle); +} + int iox_fcntl2(int, int) { fprintf(stderr, "%s is not implemented in windows!\n", __PRETTY_FUNCTION__); diff --git a/iceoryx_platform/win/source/unistd.cpp b/iceoryx_platform/win/source/unistd.cpp index 84a5c67c93..f77487430a 100644 --- a/iceoryx_platform/win/source/unistd.cpp +++ b/iceoryx_platform/win/source/unistd.cpp @@ -50,6 +50,23 @@ int iox_close(int fd) return _close(fd); } +int iox_ext_close(int fd) +{ + HANDLE handle = HandleTranslator::getInstance().get(fd); + if (handle == nullptr) + { + return 0; + } + + auto success = Win32Call(CloseHandle, handle).value; + HandleTranslator::getInstance().remove(fd); + if (success == 0) + { + return -1; + } + return 0; +} + int iox_fchown(int fd, uid_t owner, gid_t group) { return 0; From c290288881e07dd508b5dec14bbd2b3641cfedcd Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 14 Apr 2023 05:29:13 -0700 Subject: [PATCH 27/30] iox-#1962 Use iox_shm_close in the whole SharedMemory class Signed-off-by: Christian Eltzschig --- .../posix_wrapper/shared_memory_object/shared_memory.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp index b805c5961d..359d64911c 100644 --- a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object/shared_memory.cpp @@ -248,10 +248,11 @@ bool SharedMemory::close() noexcept { if (m_handle != INVALID_HANDLE) { - auto call = posixCall(iox_close)(m_handle).failureReturnValue(INVALID_HANDLE).evaluate().or_else([](auto& r) { - IOX_LOG(ERROR) << "Unable to close SharedMemory filedescriptor (close failed) : " - << r.getHumanReadableErrnum(); - }); + auto call = + posixCall(iox_shm_close)(m_handle).failureReturnValue(INVALID_HANDLE).evaluate().or_else([](auto& r) { + IOX_LOG(ERROR) << "Unable to close SharedMemory filedescriptor (close failed) : " + << r.getHumanReadableErrnum(); + }); m_handle = INVALID_HANDLE; return !call.has_error(); From 40005b41a2c753962597c9c430ee26409ce40301 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 17 Apr 2023 01:48:21 -0700 Subject: [PATCH 28/30] iox-#1962 Fix Windows shared memory test Signed-off-by: Christian Eltzschig --- iceoryx_hoofs/test/moduletests/test_posix_shared_memory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iceoryx_hoofs/test/moduletests/test_posix_shared_memory.cpp b/iceoryx_hoofs/test/moduletests/test_posix_shared_memory.cpp index 3983746611..003da67467 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_shared_memory.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_shared_memory.cpp @@ -76,7 +76,7 @@ class SharedMemory_Test : public Test return std::unique_ptr>(new int(result->value), [=](const int* fd) { cleanupSharedMemory(name); - iox_close(*fd); + iox_shm_close(*fd); delete fd; }); } From 55245f28c3157382dcae41b98c2921ae73f87936 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 17 Apr 2023 11:10:30 +0200 Subject: [PATCH 29/30] iox-#1962 use `get_file_handle` only internally, add errno values to default failures, cleanup open handling in file Signed-off-by: Christian Eltzschig --- .../posix_wrapper/shared_memory_object.hpp | 6 +- .../posix/filesystem/source/file.cpp | 57 +++++++------------ .../posix_wrapper/shared_memory_object.cpp | 5 ++ .../internal/mepoo/mepoo_segment.inl | 2 +- .../test/moduletests/test_mepoo_segment.cpp | 2 +- 5 files changed, 31 insertions(+), 41 deletions(-) diff --git a/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp b/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp index 5bd9de45eb..aff3f03451 100644 --- a/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp +++ b/iceoryx_hoofs/include/iceoryx_hoofs/internal/posix_wrapper/shared_memory_object.hpp @@ -74,18 +74,20 @@ class SharedMemoryObject : public FileManagementInterface uint64_t getSizeInBytes() const noexcept; /// @brief Returns the underlying file handle of the shared memory - int get_file_handle() const noexcept; + int getFileHandle() const noexcept; /// @brief True if the shared memory has the ownership. False if an already /// existing shared memory was opened. bool hasOwnership() const noexcept; - friend class SharedMemoryObjectBuilder; private: SharedMemoryObject(SharedMemory&& sharedMemory, MemoryMap&& memoryMap, const uint64_t memorySizeInBytes) noexcept; + friend struct FileManagementInterface; + int get_file_handle() const noexcept; + private: uint64_t m_memorySizeInBytes; diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index c907ce51fb..601f2bf2b0 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -26,37 +26,20 @@ namespace iox { expected FileBuilder::create(const FilePath& name) noexcept { - switch (m_open_mode) + if (m_open_mode == posix::OpenMode::PURGE_AND_CREATE) { - case posix::OpenMode::OPEN_EXISTING: - return this->open(name); - case posix::OpenMode::PURGE_AND_CREATE: if (File::remove(name).has_error()) { IOX_LOG(ERROR) << "Unable to purge and open file \"" << name.as_string() << "\" since the file could not be removed"; return iox::error(FileCreationError::CannotBePurged); } - IOX_FALLTHROUGH; - case posix::OpenMode::EXCLUSIVE_CREATE: - return this->open_impl(true, name); - case posix::OpenMode::OPEN_OR_CREATE: - auto result = this->open_impl(false, name); - if (!result.has_error() || result.get_error() != FileCreationError::DoesNotExist) - { - return result; - } - - return this->open_impl(true, name); } - // can never be reached since all cases are handled in the above switch - // statement - return iox::error(FileCreationError::UnknownError); + return this->open(name); } -expected FileBuilder::open_impl(const bool print_error_on_non_existing_file, - const FilePath& name) noexcept +expected FileBuilder::open(const FilePath& name) noexcept { auto result = posix::posixCall(iox_open)(name.as_string().c_str(), posix::convertToOflags(m_access_mode, m_open_mode), @@ -119,10 +102,7 @@ expected FileBuilder::open_impl(const bool print_error_ IOX_LOG(ERROR) << "Unable to open/create file since the system limit of open file descriptors was reached."; return iox::error(FileCreationError::SystemLimitOfOpenFileDescriptorsReached); case ENOENT: - if (print_error_on_non_existing_file) - { - IOX_LOG(ERROR) << "Unable to open file since the file does not exist."; - } + IOX_LOG(ERROR) << "Unable to open file since the file does not exist."; return iox::error(FileCreationError::DoesNotExist); case ENOMEM: IOX_LOG(ERROR) << "Unable to open/create file due to insufficient memory."; @@ -137,16 +117,10 @@ expected FileBuilder::open_impl(const bool print_error_ IOX_LOG(ERROR) << "Unable to create file since it already exists."; return iox::error(FileCreationError::AlreadyExists); default: - IOX_LOG(ERROR) << "Unable to open/create file due to insufficient permissions."; + IOX_LOG(ERROR) << "Unable to open/create file due to insufficient permissions (" << result.get_error().errnum + << ")."; return iox::error(FileCreationError::UnknownError); } - - return iox::success(File(result->value, m_access_mode)); -} - -expected FileBuilder::open(const FilePath& name) noexcept -{ - return this->open_impl(true, name); } File::File(const int file_descriptor, const posix::AccessMode access_mode) noexcept @@ -206,6 +180,10 @@ void File::close_fd() noexcept case EIO: IOX_LOG(FATAL) << "This should never happen! Unable to close file due to an IO failure."; break; + default: + IOX_LOG(FATAL) << "This should never happen! Unable to close file due to an unknown error (" + << result.get_error().errnum << ")."; + break; } cxx::EnsuresWithMsg(false, "Unable to close file descriptor due to a corrupted file descriptor."); @@ -237,7 +215,8 @@ expected File::does_exist(const FilePath& file) noexcept IOX_LOG(ERROR) << "Unable to determine if file exists due insufficient kernel memory."; return iox::error(FileAccessError::InsufficientKernelMemory); default: - IOX_LOG(ERROR) << "Unable to determine if file exists since an unknown error occurred."; + IOX_LOG(ERROR) << "Unable to determine if file exists since an unknown error occurred (" + << result.get_error().errnum << ")."; return iox::error(FileAccessError::UnknownError); } } @@ -282,7 +261,8 @@ expected File::remove(const FilePath& file) noexcept IOX_LOG(ERROR) << "Unable to remove file since it resides on a read-only file system."; return iox::error(FileRemoveError::ReadOnlyFilesystem); default: - IOX_LOG(ERROR) << "Unable to remove file since an unknown error occurred."; + IOX_LOG(ERROR) << "Unable to remove file since an unknown error occurred (" << result.get_error().errnum + << ")."; return iox::error(FileRemoveError::UnknownError); } } @@ -320,7 +300,8 @@ expected File::set_offset(const uint64_t offset) const noexcept IOX_LOG(ERROR) << "Unable to set file offset position since seeking is not supported by the file type."; return iox::error(FileOffsetError::SeekingNotSupportedByFileType); default: - IOX_LOG(ERROR) << "Unable to remove file since an unknown error occurred."; + IOX_LOG(ERROR) << "Unable to remove file since an unknown error occurred (" << result.get_error().errnum + << ")."; return iox::error(FileOffsetError::UnknownError); } } @@ -370,7 +351,8 @@ File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffe IOX_LOG(ERROR) << "Unable to read from file since it is a directory."; return iox::error(FileReadError::IsDirectory); default: - IOX_LOG(ERROR) << "Unable to read from file since an unknown error occurred."; + IOX_LOG(ERROR) << "Unable to read from file since an unknown error occurred (" << result.get_error().errnum + << ")."; return iox::error(FileReadError::UnknownError); } } @@ -426,7 +408,8 @@ File::write_at(const uint64_t offset, const uint8_t* const buffer, const uint64_ IOX_LOG(ERROR) << "Unable to write to file since the operation was prevented by a file seal."; return iox::error(FileWriteError::PreventedByFileSeal); default: - IOX_LOG(ERROR) << "Unable to write to file since an unknown error has occurred."; + IOX_LOG(ERROR) << "Unable to write to file since an unknown error has occurred (" << result.get_error().errnum + << ")."; return iox::error(FileWriteError::UnknownError); } } diff --git a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp index 76e17e30b3..2544698ef6 100644 --- a/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/shared_memory_object.cpp @@ -182,6 +182,11 @@ int32_t SharedMemoryObject::get_file_handle() const noexcept return m_sharedMemory.getHandle(); } +int32_t SharedMemoryObject::getFileHandle() const noexcept +{ + return m_sharedMemory.getHandle(); +} + bool SharedMemoryObject::hasOwnership() const noexcept { return m_sharedMemory.hasOwnership(); diff --git a/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl b/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl index 24ea9e3e65..85c146aec0 100644 --- a/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl +++ b/iceoryx_posh/include/iceoryx_posh/internal/mepoo/mepoo_segment.inl @@ -55,7 +55,7 @@ inline MePooSegment::MePooSegment( accessController.addPermissionEntry(AccessController::Category::GROUP, AccessController::Permission::READWRITE); accessController.addPermissionEntry(AccessController::Category::OTHERS, AccessController::Permission::NONE); - if (!accessController.writePermissionsToFile(m_sharedMemoryObject.get_file_handle())) + if (!accessController.writePermissionsToFile(m_sharedMemoryObject.getFileHandle())) { errorHandler(PoshError::MEPOO__SEGMENT_COULD_NOT_APPLY_POSIX_RIGHTS_TO_SHARED_MEMORY); } diff --git a/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp b/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp index 7ca3c2c773..da45e32a47 100644 --- a/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp +++ b/iceoryx_posh/test/moduletests/test_mepoo_segment.cpp @@ -71,7 +71,7 @@ class MePooSegment_test : public Test remove("/tmp/roudi_segment_test"); } - int get_file_handle() + int getFileHandle() { return filehandle; } From 8a179318882aa6df28897ef952efef8825573577 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Mon, 17 Apr 2023 15:45:41 +0200 Subject: [PATCH 30/30] iox-#1962 Remove unneeded function, more detailed error handling, fix typos, check invalidation of fd in move test Signed-off-by: Christian Eltzschig --- .../design/include/iox/file_management_interface.hpp | 2 +- iceoryx_hoofs/posix/filesystem/include/iox/file.hpp | 4 ---- iceoryx_hoofs/posix/filesystem/source/file.cpp | 11 +++++++---- iceoryx_hoofs/test/moduletests/test_posix_file.cpp | 2 ++ 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp b/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp index 6c0a7598b7..f4158c3618 100644 --- a/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp +++ b/iceoryx_hoofs/posix/design/include/iox/file_management_interface.hpp @@ -99,7 +99,7 @@ class Ownership /// @brief Abstract implementation to manage things common to all file descriptor /// based constructs like ownership and permissions. -/// @note Can be used by every class which provide the method 'get_file_handle' +/// @note Can be used by every class which provides the method 'get_file_handle' /// via inheritance. /// @code /// class MyResourceBasedOnFileDescriptor: public FileManagementInterface { diff --git a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp index 0ed10c5cb9..2c5da4ab1d 100644 --- a/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp +++ b/iceoryx_hoofs/posix/filesystem/include/iox/file.hpp @@ -187,10 +187,6 @@ class FileBuilder public: expected create(const FilePath& name) noexcept; expected open(const FilePath& name) noexcept; - - private: - expected open_impl(const bool print_error_on_non_existing_file, - const FilePath& name) noexcept; }; } // namespace iox diff --git a/iceoryx_hoofs/posix/filesystem/source/file.cpp b/iceoryx_hoofs/posix/filesystem/source/file.cpp index 601f2bf2b0..398b0f6ffc 100644 --- a/iceoryx_hoofs/posix/filesystem/source/file.cpp +++ b/iceoryx_hoofs/posix/filesystem/source/file.cpp @@ -117,7 +117,7 @@ expected FileBuilder::open(const FilePath& name) noexce IOX_LOG(ERROR) << "Unable to create file since it already exists."; return iox::error(FileCreationError::AlreadyExists); default: - IOX_LOG(ERROR) << "Unable to open/create file due to insufficient permissions (" << result.get_error().errnum + IOX_LOG(ERROR) << "Unable to open/create file since an unknown error occurred (" << result.get_error().errnum << ")."; return iox::error(FileCreationError::UnknownError); } @@ -290,13 +290,13 @@ expected File::set_offset(const uint64_t offset) const noexcept case EINVAL: IOX_FALLTHROUGH; case ENXIO: - IOX_LOG(ERROR) << "Unable to set file offset position since it beyond the file limits."; + IOX_LOG(ERROR) << "Unable to set file offset position since it is beyond the file limits."; return iox::error(FileOffsetError::OffsetBeyondFileLimits); case EOVERFLOW: IOX_LOG(ERROR) << "Unable to set file offset position since the file is too large and the offset would overflow."; return iox::error(FileOffsetError::FileOffsetOverflow); - case EPIPE: + case ESPIPE: IOX_LOG(ERROR) << "Unable to set file offset position since seeking is not supported by the file type."; return iox::error(FileOffsetError::SeekingNotSupportedByFileType); default: @@ -342,7 +342,7 @@ File::read_at(const uint64_t offset, uint8_t* const buffer, const uint64_t buffe IOX_LOG(ERROR) << "Unable to read from file since an interrupt signal was received."; return iox::error(FileReadError::Interrupt); case EINVAL: - IOX_LOG(ERROR) << "Unable to read from file since is unsuitable for reading."; + IOX_LOG(ERROR) << "Unable to read from file since it is unsuitable for reading."; return iox::error(FileReadError::FileUnsuitableForReading); case EIO: IOX_LOG(ERROR) << "Unable to read from file since an IO failure occurred."; @@ -407,6 +407,9 @@ File::write_at(const uint64_t offset, const uint8_t* const buffer, const uint64_ case EPERM: IOX_LOG(ERROR) << "Unable to write to file since the operation was prevented by a file seal."; return iox::error(FileWriteError::PreventedByFileSeal); + case EIO: + IOX_LOG(ERROR) << "Unable to write to file since an IO failure occurred."; + return iox::error(FileWriteError::IoFailure); default: IOX_LOG(ERROR) << "Unable to write to file since an unknown error has occurred (" << result.get_error().errnum << ")."; diff --git a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp index 3c126ccbf6..ef4ff618dc 100644 --- a/iceoryx_hoofs/test/moduletests/test_posix_file.cpp +++ b/iceoryx_hoofs/test/moduletests/test_posix_file.cpp @@ -441,6 +441,7 @@ TEST_F(File_test, MoveConstructedFileWorks) EXPECT_THAT(*result, Eq(test_content.size())); File sut2{std::move(sut.value())}; + EXPECT_THAT(sut->get_file_handle(), -1); std::array read_content{0}; auto read = sut2.read(read_content.data(), read_content.size()); @@ -475,6 +476,7 @@ TEST_F(File_test, MoveAssignedFileWorks) ASSERT_FALSE(sut3.has_error()); sut2 = std::move(sut3.value()); + EXPECT_THAT(sut3->get_file_handle(), -1); std::array read_content{0}; auto read = sut2.read(read_content.data(), read_content.size());