From be9375e914621875ccfb1725086ba0fc3279532a Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Tue, 2 Feb 2021 16:44:33 -0800 Subject: [PATCH] Migrate autoclose_fd_t to new file fds.h fds.h will centralize logic around working with file descriptors. In particular it will be the new home for logic around moving fds to high unused values, replacing the "avoid conflicts" logic. --- CMakeLists.txt | 2 +- src/common.cpp | 16 ------------ src/common.h | 44 -------------------------------- src/env_universal_common.h | 1 + src/fd_monitor.h | 1 + src/fds.cpp | 26 +++++++++++++++++++ src/fds.h | 52 ++++++++++++++++++++++++++++++++++++++ src/io.h | 1 + 8 files changed, 82 insertions(+), 61 deletions(-) create mode 100644 src/fds.cpp create mode 100644 src/fds.h 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"