aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuqian Yang <crupest@crupest.life>2025-09-04 22:14:57 +0800
committerYuqian Yang <crupest@crupest.life>2025-09-04 22:14:57 +0800
commit2ac35f7b67eac709cdae7981880f7d117f9a9d75 (patch)
tree7823ebbc58916fc95187169b4b02b1c6d383734f
parentac3d88fc043d628979675dc3ef99ba5e1b4d58ca (diff)
downloadcru-2ac35f7b67eac709cdae7981880f7d117f9a9d75.tar.gz
cru-2ac35f7b67eac709cdae7981880f7d117f9a9d75.tar.bz2
cru-2ac35f7b67eac709cdae7981880f7d117f9a9d75.zip
Add SetFileDescriptorFlags.
-rw-r--r--include/cru/base/platform/unix/UnixFile.h3
-rw-r--r--src/base/platform/unix/UnixFile.cpp27
2 files changed, 22 insertions, 8 deletions
diff --git a/include/cru/base/platform/unix/UnixFile.h b/include/cru/base/platform/unix/UnixFile.h
index d2b540cd..dfbdfffb 100644
--- a/include/cru/base/platform/unix/UnixFile.h
+++ b/include/cru/base/platform/unix/UnixFile.h
@@ -26,6 +26,7 @@ class UnixFileDescriptor {
UnixFileDescriptor& operator=(UnixFileDescriptor&& other) noexcept;
bool IsValid() const;
+ void EnsureValid() const;
int GetValue() const;
void Close();
@@ -35,6 +36,8 @@ class UnixFileDescriptor {
explicit operator bool() const { return this->IsValid(); }
operator int() const { return this->GetValue(); }
+ void SetFileDescriptorFlags(int flags);
+
private:
bool DoClose();
diff --git a/src/base/platform/unix/UnixFile.cpp b/src/base/platform/unix/UnixFile.cpp
index b9af109a..a3c5cc6c 100644
--- a/src/base/platform/unix/UnixFile.cpp
+++ b/src/base/platform/unix/UnixFile.cpp
@@ -54,17 +54,19 @@ UnixFileDescriptor& UnixFileDescriptor::operator=(
bool UnixFileDescriptor::IsValid() const { return this->descriptor_ >= 0; }
-int UnixFileDescriptor::GetValue() const {
+void UnixFileDescriptor::EnsureValid() const {
if (!this->IsValid()) {
- throw Exception("Can't get value of an invalid unix file descriptor.");
+ throw Exception("Can't do operation on an invalid unix file descriptor.");
}
+}
+
+int UnixFileDescriptor::GetValue() const {
+ EnsureValid();
return this->descriptor_;
}
void UnixFileDescriptor::Close() {
- if (!this->IsValid()) {
- throw Exception("Can't close an invalid unix file descriptor.");
- }
+ EnsureValid();
if (!this->DoClose()) {
throw ErrnoException(u"Failed to call close on file descriptor.");
}
@@ -80,17 +82,26 @@ bool UnixFileDescriptor::DoClose() {
}
}
+void UnixFileDescriptor::SetFileDescriptorFlags(int flags) {
+ EnsureValid();
+ if (::fcntl(GetValue(), F_SETFL, flags) != -1) {
+ throw ErrnoException(u"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.");
}
+ UnixFileDescriptor read(fds[0]), write(fds[1]);
+
if (flags & UnixPipeFlags::NonBlock) {
- ::fcntl(fds[0], F_SETFL, O_NONBLOCK);
- ::fcntl(fds[1], F_SETFL, O_NONBLOCK);
+ read.SetFileDescriptorFlags(O_NONBLOCK);
+ write.SetFileDescriptorFlags(O_NONBLOCK);
}
- return {UnixFileDescriptor(fds[0]), UnixFileDescriptor(fds[1])};
+ return {std::move(read), std::move(write)};
}
} // namespace cru::platform::unix