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
// be reading from.
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)) {
switch (in->io_mode) {
case io_mode_t::fd: {
const io_fd_t *in_fd = static_cast<const io_fd_t *>(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<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;
}
// 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;
}
}

View file

@ -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_buffer_t> io_bufferfill_t::finish(std::shared_ptr<io_bufferfi
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() {
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:
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;
int file_fd() const { return file_fd_.fd(); }
private:
// The fd for the file which we are writing to or reading from.
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_data_t(io_mode_t::pipe, fd, pipe_fd.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;
int pipe_fd() const { return pipe_fd_.fd(); }
};
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_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<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.
/// \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) {
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<const io_file_t *>(io_ref.get());
result.add_dup2(io->file_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;
}
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;