Collapse io_data switch statements

Now that each io_data knows its source and target fd, we don't need to switch
on its types any more.
This commit is contained in:
ridiculousfish 2019-12-29 15:51:22 -08:00
parent 0af5608ce8
commit c963442999
4 changed files with 31 additions and 91 deletions

View file

@ -382,45 +382,17 @@ static bool exec_internal_builtin_proc(parser_t &parser, const std::shared_ptr<j
// If this is the first process, check the io redirections and see where we should // If this is the first process, check the io redirections and see where we should
// be reading from. // be reading from.
if (pipe_read) { if (pipe_read) {
local_builtin_stdin = pipe_read->pipe_fd(); local_builtin_stdin = pipe_read->source_fd;
} else if (const auto in = proc_io_chain.io_for_fd(STDIN_FILENO)) { } else if (const auto in = proc_io_chain.io_for_fd(STDIN_FILENO)) {
switch (in->io_mode) { // Ignore fd redirections from an fd other than the
case io_mode_t::fd: { // standard ones. e.g. in source <&3 don't actually read from fd 3,
const io_fd_t *in_fd = static_cast<const io_fd_t *>(in.get()); // which is internal to fish. We still respect this redirection in
// Ignore fd redirections from an fd other than the // that we pass it on as a block IO to the code that source runs,
// standard ones. e.g. in source <&3 don't actually read from fd 3, // and therefore this is not an error.
// which is internal to fish. We still respect this redirection in bool ignore_redirect =
// that we pass it on as a block IO to the code that source runs, in->io_mode == io_mode_t::fd && in->source_fd >= 0 && in->source_fd < 3;
// and therefore this is not an error. if (!ignore_redirect) {
if (in_fd->source_fd >= 0 && in_fd->source_fd < 3) { local_builtin_stdin = in->source_fd;
local_builtin_stdin = in_fd->source_fd;
}
break;
}
case io_mode_t::pipe: {
const io_pipe_t *in_pipe = static_cast<const io_pipe_t *>(in.get());
if (in_pipe->fd == STDIN_FILENO) {
local_builtin_stdin = in_pipe->pipe_fd();
}
break;
}
case io_mode_t::file: {
const io_file_t *in_file = static_cast<const io_file_t *>(in.get());
local_builtin_stdin = in_file->file_fd();
break;
}
case io_mode_t::close: {
// FIXME: When requesting that stdin be closed, we really don't do
// anything. How should this be handled?
local_builtin_stdin = -1;
break;
}
default: {
local_builtin_stdin = -1;
debug(1, _(L"Unknown input redirection type %d"), in->io_mode);
break;
}
} }
} }

View file

@ -28,11 +28,11 @@
#define OPEN_MASK 0666 #define OPEN_MASK 0666
io_data_t::~io_data_t() = default; io_data_t::~io_data_t() = default;
io_pipe_t::~io_pipe_t() = default;
io_file_t::io_file_t(int f, autoclose_fd_t file) io_fd_t::~io_fd_t() = default;
: io_data_t(io_mode_t::file, f, file_fd_.fd()), file_fd_(std::move(file)) { io_close_t::~io_close_t() = default;
assert(file_fd_.valid() && "File is not valid"); io_file_t::~io_file_t() = default;
} io_bufferfill_t::~io_bufferfill_t() = default;
void io_close_t::print() const { std::fwprintf(stderr, L"close %d\n", fd); } void io_close_t::print() const { std::fwprintf(stderr, L"close %d\n", fd); }
@ -41,7 +41,7 @@ void io_fd_t::print() const { std::fwprintf(stderr, L"FD map %d -> %d\n", source
void io_file_t::print() const { std::fwprintf(stderr, L"file (%d)\n", file_fd_.fd()); } void io_file_t::print() const { std::fwprintf(stderr, L"file (%d)\n", file_fd_.fd()); }
void io_pipe_t::print() const { void io_pipe_t::print() const {
std::fwprintf(stderr, L"pipe {%d} (input: %s)\n", pipe_fd(), is_input_ ? "yes" : "no"); std::fwprintf(stderr, L"pipe {%d} (input: %s)\n", source_fd, is_input_ ? "yes" : "no");
} }
void io_bufferfill_t::print() const { std::fwprintf(stderr, L"bufferfill {%d}\n", write_fd_.fd()); } void io_bufferfill_t::print() const { std::fwprintf(stderr, L"bufferfill {%d}\n", write_fd_.fd()); }
@ -207,12 +207,6 @@ std::shared_ptr<io_buffer_t> io_bufferfill_t::finish(std::shared_ptr<io_bufferfi
return buffer; return buffer;
} }
io_pipe_t::~io_pipe_t() = default;
io_fd_t::~io_fd_t() = default;
io_close_t::~io_close_t() = default;
io_file_t::~io_file_t() = default;
io_bufferfill_t::~io_bufferfill_t() = default;
io_buffer_t::~io_buffer_t() { io_buffer_t::~io_buffer_t() {
assert(!fillthread_running() && "io_buffer_t destroyed with outstanding fillthread"); assert(!fillthread_running() && "io_buffer_t destroyed with outstanding fillthread");
} }

View file

@ -215,12 +215,13 @@ class io_file_t : public io_data_t {
public: public:
void print() const override; void print() const override;
io_file_t(int f, autoclose_fd_t file); io_file_t(int fd, autoclose_fd_t file)
: io_data_t(io_mode_t::file, fd, file.fd()), file_fd_(std::move(file)) {
assert(file_fd_.valid() && "File is not valid");
}
~io_file_t() override; ~io_file_t() override;
int file_fd() const { return file_fd_.fd(); }
private: private:
// The fd for the file which we are writing to or reading from. // The fd for the file which we are writing to or reading from.
autoclose_fd_t file_fd_; autoclose_fd_t file_fd_;
@ -240,11 +241,11 @@ class io_pipe_t : public io_data_t {
io_pipe_t(int fd, bool is_input, autoclose_fd_t pipe_fd) io_pipe_t(int fd, bool is_input, autoclose_fd_t pipe_fd)
: io_data_t(io_mode_t::pipe, fd, pipe_fd.fd()), : io_data_t(io_mode_t::pipe, fd, pipe_fd.fd()),
pipe_fd_(std::move(pipe_fd)), pipe_fd_(std::move(pipe_fd)),
is_input_(is_input) {} is_input_(is_input) {
assert(pipe_fd_.valid() && "Pipe is not valid");
}
~io_pipe_t() override; ~io_pipe_t() override;
int pipe_fd() const { return pipe_fd_.fd(); }
}; };
class io_buffer_t; class io_buffer_t;
@ -267,15 +268,14 @@ class io_bufferfill_t : public io_data_t {
io_bufferfill_t(autoclose_fd_t write_fd, std::shared_ptr<io_buffer_t> buffer) io_bufferfill_t(autoclose_fd_t write_fd, std::shared_ptr<io_buffer_t> buffer)
: io_data_t(io_mode_t::bufferfill, STDOUT_FILENO, write_fd.fd()), : io_data_t(io_mode_t::bufferfill, STDOUT_FILENO, write_fd.fd()),
write_fd_(std::move(write_fd)), write_fd_(std::move(write_fd)),
buffer_(std::move(buffer)) {} buffer_(std::move(buffer)) {
assert(write_fd_.valid() && "fd is not valid");
}
~io_bufferfill_t() override; ~io_bufferfill_t() override;
std::shared_ptr<io_buffer_t> buffer() const { return buffer_; } std::shared_ptr<io_buffer_t> buffer() const { return buffer_; }
/// \return the fd that, when written to, fills the buffer.
int write_fd() const { return write_fd_.fd(); }
/// Create an io_bufferfill_t which, when written from, fills a buffer with the contents. /// Create an io_bufferfill_t which, when written from, fills a buffer with the contents.
/// \returns nullptr on failure, e.g. too many open fds. /// \returns nullptr on failure, e.g. too many open fds.
/// ///

View file

@ -35,37 +35,11 @@ int redirection_spec_t::oflags() const {
dup2_list_t dup2_list_t::resolve_chain(const io_chain_t &io_chain) { dup2_list_t dup2_list_t::resolve_chain(const io_chain_t &io_chain) {
ASSERT_IS_NOT_FORKED_CHILD(); ASSERT_IS_NOT_FORKED_CHILD();
dup2_list_t result; dup2_list_t result;
for (const auto &io_ref : io_chain) { for (const auto &io : io_chain) {
switch (io_ref->io_mode) { if (io->source_fd < 0) {
case io_mode_t::file: { result.add_close(io->fd);
const io_file_t *io = static_cast<const io_file_t *>(io_ref.get()); } else {
result.add_dup2(io->file_fd(), io->fd); result.add_dup2(io->source_fd, io->fd);
break;
}
case io_mode_t::close: {
const io_close_t *io = static_cast<const io_close_t *>(io_ref.get());
result.add_close(io->fd);
break;
}
case io_mode_t::fd: {
const io_fd_t *io = static_cast<const io_fd_t *>(io_ref.get());
result.add_dup2(io->source_fd, io->fd);
break;
}
case io_mode_t::pipe: {
const io_pipe_t *io = static_cast<const io_pipe_t *>(io_ref.get());
result.add_dup2(io->pipe_fd(), io->fd);
break;
}
case io_mode_t::bufferfill: {
const io_bufferfill_t *io = static_cast<const io_bufferfill_t *>(io_ref.get());
result.add_dup2(io->write_fd(), io->fd);
break;
}
} }
} }
return result; return result;