diff --git a/src/exec.cpp b/src/exec.cpp index 5325e872a..5c6f36f68 100644 --- a/src/exec.cpp +++ b/src/exec.cpp @@ -382,45 +382,17 @@ static bool exec_internal_builtin_proc(parser_t &parser, const std::shared_ptrpipe_fd(); + local_builtin_stdin = pipe_read->source_fd; } else if (const auto in = proc_io_chain.io_for_fd(STDIN_FILENO)) { - switch (in->io_mode) { - case io_mode_t::fd: { - const io_fd_t *in_fd = static_cast(in.get()); - // Ignore fd redirections from an fd other than the - // standard ones. e.g. in source <&3 don't actually read from fd 3, - // which is internal to fish. We still respect this redirection in - // that we pass it on as a block IO to the code that source runs, - // and therefore this is not an error. - if (in_fd->source_fd >= 0 && in_fd->source_fd < 3) { - local_builtin_stdin = in_fd->source_fd; - } - break; - } - case io_mode_t::pipe: { - const io_pipe_t *in_pipe = static_cast(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(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; - } + // Ignore fd redirections from an fd other than the + // standard ones. e.g. in source <&3 don't actually read from fd 3, + // which is internal to fish. We still respect this redirection in + // that we pass it on as a block IO to the code that source runs, + // and therefore this is not an error. + bool ignore_redirect = + in->io_mode == io_mode_t::fd && in->source_fd >= 0 && in->source_fd < 3; + if (!ignore_redirect) { + local_builtin_stdin = in->source_fd; } } diff --git a/src/io.cpp b/src/io.cpp index b00800c0d..9fa759f0d 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -28,11 +28,11 @@ #define OPEN_MASK 0666 io_data_t::~io_data_t() = default; - -io_file_t::io_file_t(int f, autoclose_fd_t file) - : io_data_t(io_mode_t::file, f, file_fd_.fd()), file_fd_(std::move(file)) { - assert(file_fd_.valid() && "File is not valid"); -} +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; 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_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()); } @@ -207,12 +207,6 @@ std::shared_ptr io_bufferfill_t::finish(std::shared_ptr buffer) : io_data_t(io_mode_t::bufferfill, STDOUT_FILENO, write_fd.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; std::shared_ptr 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. /// \returns nullptr on failure, e.g. too many open fds. /// diff --git a/src/redirection.cpp b/src/redirection.cpp index 059dd65a4..92a01d04a 100644 --- a/src/redirection.cpp +++ b/src/redirection.cpp @@ -35,37 +35,11 @@ int redirection_spec_t::oflags() const { dup2_list_t dup2_list_t::resolve_chain(const io_chain_t &io_chain) { ASSERT_IS_NOT_FORKED_CHILD(); dup2_list_t result; - for (const auto &io_ref : io_chain) { - switch (io_ref->io_mode) { - case io_mode_t::file: { - const io_file_t *io = static_cast(io_ref.get()); - result.add_dup2(io->file_fd(), io->fd); - break; - } - - case io_mode_t::close: { - const io_close_t *io = static_cast(io_ref.get()); - result.add_close(io->fd); - break; - } - - case io_mode_t::fd: { - const io_fd_t *io = static_cast(io_ref.get()); - result.add_dup2(io->source_fd, io->fd); - break; - } - - case io_mode_t::pipe: { - const io_pipe_t *io = static_cast(io_ref.get()); - result.add_dup2(io->pipe_fd(), io->fd); - break; - } - - case io_mode_t::bufferfill: { - const io_bufferfill_t *io = static_cast(io_ref.get()); - result.add_dup2(io->write_fd(), io->fd); - break; - } + for (const auto &io : io_chain) { + if (io->source_fd < 0) { + result.add_close(io->fd); + } else { + result.add_dup2(io->source_fd, io->fd); } } return result;