diff options
author | Yuqian Yang <crupest@crupest.life> | 2025-09-04 22:51:27 +0800 |
---|---|---|
committer | Yuqian Yang <crupest@crupest.life> | 2025-09-04 22:51:27 +0800 |
commit | fdddc7f4a8884a8481dc71c0f34b8775659ba236 (patch) | |
tree | 7b43bc30a7666f4dc2a87e7999a9f26d911dbe66 | |
parent | 2ac35f7b67eac709cdae7981880f7d117f9a9d75 (diff) | |
download | cru-fdddc7f4a8884a8481dc71c0f34b8775659ba236.tar.gz cru-fdddc7f4a8884a8481dc71c0f34b8775659ba236.tar.bz2 cru-fdddc7f4a8884a8481dc71c0f34b8775659ba236.zip |
UnixFileDescriptor Read and ErrnoException std::string.
-rw-r--r-- | include/cru/base/Exception.h | 17 | ||||
-rw-r--r-- | include/cru/base/platform/unix/UnixFile.h | 2 | ||||
-rw-r--r-- | src/base/Exception.cpp | 27 | ||||
-rw-r--r-- | src/base/platform/unix/PosixSpawnSubProcess.cpp | 6 | ||||
-rw-r--r-- | src/base/platform/unix/UnixFile.cpp | 22 |
5 files changed, 52 insertions, 22 deletions
diff --git a/include/cru/base/Exception.h b/include/cru/base/Exception.h index d102c263..a898043a 100644 --- a/include/cru/base/Exception.h +++ b/include/cru/base/Exception.h @@ -3,6 +3,7 @@ #include <exception> #include <optional> +#include <string_view> namespace cru { #ifdef _MSC_VER @@ -53,16 +54,18 @@ class CRU_BASE_API TextEncodeException : public Exception { class ErrnoException : public Exception { public: + ErrnoException(); + explicit ErrnoException(int error_code); /** * @brief will retrieve errno automatically. */ - explicit ErrnoException(String message = {}); - ErrnoException(String message, int errno_code); - - CRU_DELETE_COPY(ErrnoException) - CRU_DELETE_MOVE(ErrnoException) - - ~ErrnoException() override = default; + explicit ErrnoException(std::string_view message); + ErrnoException(std::string_view message, int errno_code); + /** + * @brief will retrieve errno automatically. + */ + explicit ErrnoException(StringView message); + ErrnoException(StringView message, int errno_code); int GetErrnoCode() const { return errno_code_; } diff --git a/include/cru/base/platform/unix/UnixFile.h b/include/cru/base/platform/unix/UnixFile.h index dfbdfffb..8ce3249d 100644 --- a/include/cru/base/platform/unix/UnixFile.h +++ b/include/cru/base/platform/unix/UnixFile.h @@ -6,6 +6,7 @@ #include "../../Bitmask.h" +#include <sys/types.h> #include <functional> namespace cru::platform::unix { @@ -36,6 +37,7 @@ class UnixFileDescriptor { explicit operator bool() const { return this->IsValid(); } operator int() const { return this->GetValue(); } + ssize_t Read(void* buffer, size_t size); void SetFileDescriptorFlags(int flags); private: diff --git a/src/base/Exception.cpp b/src/base/Exception.cpp index 1e3813a9..2bf66fc6 100644 --- a/src/base/Exception.cpp +++ b/src/base/Exception.cpp @@ -1,8 +1,10 @@ #include "cru/base/Exception.h" -#include "cru/base/Format.h" - #include <cerrno> +#include <format> +#include <string_view> + +constexpr auto NO_MESSAGE = "No message."; namespace cru { Exception::Exception(std::string message, std::unique_ptr<std::exception> inner) @@ -13,9 +15,7 @@ Exception::Exception(StringView message, std::unique_ptr<std::exception> inner) Exception::~Exception() {} -const char* Exception::what() const noexcept { - return message_.c_str(); -} +const char* Exception::what() const noexcept { return message_.c_str(); } void Exception::AppendMessage(StringView additional_message) { message_ += " "; @@ -26,10 +26,21 @@ void Exception::AppendMessage(std::optional<StringView> additional_message) { if (additional_message) AppendMessage(*additional_message); } -ErrnoException::ErrnoException(String message) +ErrnoException::ErrnoException() : ErrnoException(NO_MESSAGE) {} + +ErrnoException::ErrnoException(int errno_code) + : ErrnoException(NO_MESSAGE, errno_code) {} + +ErrnoException::ErrnoException(std::string_view message) : ErrnoException(message, errno) {} -ErrnoException::ErrnoException(String message, int errno_code) - : Exception(Format(u"{}. Errno is {}.", message, errno_code)), +ErrnoException::ErrnoException(std::string_view message, int errno_code) + : Exception(std::format("{} Errno is {}.", message, errno_code)), errno_code_(errno_code) {} + +ErrnoException::ErrnoException(StringView message) + : ErrnoException(message.ToUtf8()) {} + +ErrnoException::ErrnoException(StringView message, int errno_code) + : ErrnoException(message.ToUtf8(), errno_code) {} } // namespace cru diff --git a/src/base/platform/unix/PosixSpawnSubProcess.cpp b/src/base/platform/unix/PosixSpawnSubProcess.cpp index 34ae6622..4471c39c 100644 --- a/src/base/platform/unix/PosixSpawnSubProcess.cpp +++ b/src/base/platform/unix/PosixSpawnSubProcess.cpp @@ -56,7 +56,7 @@ void PosixSpawnSubProcessImpl::PlatformCreateProcess( const SubProcessStartInfo& start_info) { auto check_error = [](int error, String message) { if (error == 0) return; - std::unique_ptr<ErrnoException> inner(new ErrnoException({}, error)); + std::unique_ptr<ErrnoException> inner(new ErrnoException(error)); throw SubProcessFailedToStartException(std::move(message), std::move(inner)); }; @@ -145,7 +145,7 @@ SubProcessExitResult PosixSpawnSubProcessImpl::PlatformWaitForProcess() { continue; } - std::unique_ptr<ErrnoException> inner(new ErrnoException({}, errno)); + std::unique_ptr<ErrnoException> inner(new ErrnoException(errno)); throw SubProcessInternalException( u"Failed to call waitpid on a subprocess.", std::move(inner)); @@ -163,7 +163,7 @@ SubProcessExitResult PosixSpawnSubProcessImpl::PlatformWaitForProcess() { void PosixSpawnSubProcessImpl::PlatformKillProcess() { int error = kill(pid_, SIGKILL); if (error != 0) { - std::unique_ptr<ErrnoException> inner(new ErrnoException({}, errno)); + std::unique_ptr<ErrnoException> inner(new ErrnoException(errno)); throw SubProcessInternalException(u"Failed to call kill on a subprocess.", std::move(inner)); } diff --git a/src/base/platform/unix/UnixFile.cpp b/src/base/platform/unix/UnixFile.cpp index a3c5cc6c..763161ce 100644 --- a/src/base/platform/unix/UnixFile.cpp +++ b/src/base/platform/unix/UnixFile.cpp @@ -3,8 +3,9 @@ #include "cru/base/log/Logger.h" #include <fcntl.h> -#include <sys/fcntl.h> +#include <sys/types.h> #include <unistd.h> +#include <cerrno> namespace cru::platform::unix { @@ -68,7 +69,7 @@ int UnixFileDescriptor::GetValue() const { void UnixFileDescriptor::Close() { EnsureValid(); if (!this->DoClose()) { - throw ErrnoException(u"Failed to call close on file descriptor."); + throw ErrnoException("Failed to call close on file descriptor."); } descriptor_ = -1; auto_close_ = false; @@ -82,17 +83,30 @@ bool UnixFileDescriptor::DoClose() { } } +ssize_t UnixFileDescriptor::Read(void* buffer, size_t size) { + EnsureValid(); + auto result = ::read(GetValue(), buffer, size); + if (result == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return -1; + } else { + throw ErrnoException("Failed to read on file descriptor."); + } + } + return result; +} + void UnixFileDescriptor::SetFileDescriptorFlags(int flags) { EnsureValid(); if (::fcntl(GetValue(), F_SETFL, flags) != -1) { - throw ErrnoException(u"Failed to set flags on file descriptor."); + throw ErrnoException("Failed to set flags on file descriptor."); } } UniDirectionalUnixPipeResult OpenUniDirectionalPipe(UnixPipeFlag flags) { int fds[2]; if (::pipe(fds) != 0) { - throw ErrnoException(u"Failed to create unix pipe."); + throw ErrnoException("Failed to create unix pipe."); } UnixFileDescriptor read(fds[0]), write(fds[1]); |