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.
This commit is contained in:
ridiculousfish 2021-02-02 16:44:33 -08:00
parent f0d07f9b1c
commit be9375e914
8 changed files with 82 additions and 61 deletions

View file

@ -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.

View file

@ -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

View file

@ -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, ...);

View file

@ -11,6 +11,7 @@
#include "common.h"
#include "env.h"
#include "fds.h"
#include "wutil.h"
/// Callback data, reflecting a change in universal variables.

View file

@ -8,6 +8,7 @@
#include <sys/select.h> // IWYU pragma: keep
#include "common.h"
#include "fds.h"
#include "maybe.h"
class fd_monitor_t;

26
src/fds.cpp Normal file
View file

@ -0,0 +1,26 @@
/** Facilities for working with file descriptors. */
#include "config.h" // IWYU pragma: keep
#include "fds.h"
#include <errno.h>
#include <unistd.h>
#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;
}
}
}

52
src/fds.h Normal file
View file

@ -0,0 +1,52 @@
/** Facilities for working with file descriptors. */
#ifndef FISH_FDS_H
#define FISH_FDS_H
#include <algorithm>
/// 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

View file

@ -14,6 +14,7 @@
#include "common.h"
#include "env.h"
#include "fds.h"
#include "flog.h"
#include "global_safety.h"
#include "maybe.h"