mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
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:
parent
0af5608ce8
commit
c963442999
4 changed files with 31 additions and 91 deletions
48
src/exec.cpp
48
src/exec.cpp
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
src/io.cpp
18
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_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");
|
||||
}
|
||||
|
|
20
src/io.h
20
src/io.h
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue