diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ec35b97c..cbcb78652 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -123,7 +123,7 @@ set(FISH_SRCS src/proc.cpp src/reader.cpp src/redirection.cpp src/sanity.cpp src/screen.cpp src/signal.cpp src/termsize.cpp src/timer.cpp src/tinyexpr.cpp src/tokenizer.cpp src/topic_monitor.cpp src/trace.cpp src/utf8.cpp src/util.cpp - src/wcstringutil.cpp src/wgetopt.cpp src/wildcard.cpp src/wutil.cpp + src/wcstringutil.cpp src/wgetopt.cpp src/wildcard.cpp src/wutil.cpp src/fds.cpp ) # Header files are just globbed. diff --git a/src/common.cpp b/src/common.cpp index f237be299..2861a54d0 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1751,22 +1751,6 @@ double timef() { void exit_without_destructors(int code) { _exit(code); } -void autoclose_fd_t::close() { - if (fd_ < 0) return; - exec_close(fd_); - fd_ = -1; -} - -void exec_close(int fd) { - assert(fd >= 0 && "Invalid fd"); - while (close(fd) == -1) { - if (errno != EINTR) { - wperror(L"close"); - break; - } - } -} - extern "C" { [[gnu::noinline]] void debug_thread_error(void) { // Wait for a SIGINT. We can't use sigsuspend() because the signal may be delivered on another diff --git a/src/common.h b/src/common.h index bfff7b26f..66a37b604 100644 --- a/src/common.h +++ b/src/common.h @@ -442,50 +442,6 @@ class scoped_push { } }; -/// A helper class for managing and automatically closing a file descriptor. -class autoclose_fd_t { - int fd_; - - public: - // Closes the fd if not already closed. - void close(); - - // Returns the fd. - int fd() const { return fd_; } - - // Returns the fd, transferring ownership to the caller. - int acquire() { - int temp = fd_; - fd_ = -1; - return temp; - } - - // Resets to a new fd, taking ownership. - void reset(int fd) { - if (fd == fd_) return; - close(); - fd_ = fd; - } - - // \return if this has a valid fd. - bool valid() const { return fd_ >= 0; } - - autoclose_fd_t(const autoclose_fd_t &) = delete; - void operator=(const autoclose_fd_t &) = delete; - autoclose_fd_t(autoclose_fd_t &&rhs) : fd_(rhs.fd_) { rhs.fd_ = -1; } - - void operator=(autoclose_fd_t &&rhs) { - close(); - std::swap(this->fd_, rhs.fd_); - } - - explicit autoclose_fd_t(int fd = -1) : fd_(fd) {} - ~autoclose_fd_t() { close(); } -}; - -/// Close a file descriptor \p fd, retrying on EINTR. -void exec_close(int fd); - wcstring format_string(const wchar_t *format, ...); wcstring vformat_string(const wchar_t *format, va_list va_orig); void append_format(wcstring &str, const wchar_t *format, ...); diff --git a/src/env_universal_common.h b/src/env_universal_common.h index 468ae43b0..2d852a54d 100644 --- a/src/env_universal_common.h +++ b/src/env_universal_common.h @@ -11,6 +11,7 @@ #include "common.h" #include "env.h" +#include "fds.h" #include "wutil.h" /// Callback data, reflecting a change in universal variables. diff --git a/src/fd_monitor.h b/src/fd_monitor.h index 1127e102c..34b8706f2 100644 --- a/src/fd_monitor.h +++ b/src/fd_monitor.h @@ -8,6 +8,7 @@ #include // IWYU pragma: keep #include "common.h" +#include "fds.h" #include "maybe.h" class fd_monitor_t; diff --git a/src/fds.cpp b/src/fds.cpp new file mode 100644 index 000000000..30e49d77c --- /dev/null +++ b/src/fds.cpp @@ -0,0 +1,26 @@ +/** Facilities for working with file descriptors. */ + +#include "config.h" // IWYU pragma: keep + +#include "fds.h" + +#include +#include + +#include "wutil.h" + +void autoclose_fd_t::close() { + if (fd_ < 0) return; + exec_close(fd_); + fd_ = -1; +} + +void exec_close(int fd) { + assert(fd >= 0 && "Invalid fd"); + while (close(fd) == -1) { + if (errno != EINTR) { + wperror(L"close"); + break; + } + } +} diff --git a/src/fds.h b/src/fds.h new file mode 100644 index 000000000..14c3b21d6 --- /dev/null +++ b/src/fds.h @@ -0,0 +1,52 @@ +/** Facilities for working with file descriptors. */ + +#ifndef FISH_FDS_H +#define FISH_FDS_H + +#include + +/// A helper class for managing and automatically closing a file descriptor. +class autoclose_fd_t { + int fd_; + + public: + // Closes the fd if not already closed. + void close(); + + // Returns the fd. + int fd() const { return fd_; } + + // Returns the fd, transferring ownership to the caller. + int acquire() { + int temp = fd_; + fd_ = -1; + return temp; + } + + // Resets to a new fd, taking ownership. + void reset(int fd) { + if (fd == fd_) return; + close(); + fd_ = fd; + } + + // \return if this has a valid fd. + bool valid() const { return fd_ >= 0; } + + autoclose_fd_t(const autoclose_fd_t &) = delete; + void operator=(const autoclose_fd_t &) = delete; + autoclose_fd_t(autoclose_fd_t &&rhs) : fd_(rhs.fd_) { rhs.fd_ = -1; } + + void operator=(autoclose_fd_t &&rhs) { + close(); + std::swap(this->fd_, rhs.fd_); + } + + explicit autoclose_fd_t(int fd = -1) : fd_(fd) {} + ~autoclose_fd_t() { close(); } +}; + +/// Close a file descriptor \p fd, retrying on EINTR. +void exec_close(int fd); + +#endif diff --git a/src/io.h b/src/io.h index 1504509d7..b90f66355 100644 --- a/src/io.h +++ b/src/io.h @@ -14,6 +14,7 @@ #include "common.h" #include "env.h" +#include "fds.h" #include "flog.h" #include "global_safety.h" #include "maybe.h"