diff --git a/exec.cpp b/exec.cpp index e72a787f5..2aa13dc1b 100644 --- a/exec.cpp +++ b/exec.cpp @@ -406,11 +406,6 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t &out_chain, s */ case IO_FILE: { - out.reset(new io_data_t()); - out->fd = in->fd; - out->io_mode = IO_FD; - out->param2.close_old = 1; - int fd; if ((fd=open(in->filename_cstr, in->param2.flags, OPEN_MASK))==-1) { @@ -424,7 +419,7 @@ static bool io_transmogrify(const io_chain_t &in_chain, io_chain_t &out_chain, s } opened_fds.push_back(fd); - out->param1.old_fd = fd; + out.reset(new io_fd_t(in->fd, fd, true)); break; } @@ -852,7 +847,8 @@ void exec(parser_t &parser, job_t *j) case IO_FD: { - builtin_stdin = in->param1.old_fd; + CAST_INIT(const io_fd_t *, in_fd, in.get()); + builtin_stdin = in_fd->old_fd; break; } case IO_PIPE: diff --git a/io.cpp b/io.cpp index 33045bcf4..8bbc07438 100644 --- a/io.cpp +++ b/io.cpp @@ -61,9 +61,6 @@ void io_data_t::print() const case IO_PIPE: fprintf(stderr, "pipe {%d, %d}\n", param1.pipe_fd[0], param1.pipe_fd[1]); break; - case IO_FD: - fprintf(stderr, "FD map %d -> %d\n", param1.old_fd, fd); - break; case IO_BUFFER: fprintf(stderr, "buffer %p (size %lu)\n", out_buffer_ptr(), out_buffer_size()); break; @@ -75,6 +72,11 @@ void io_close_t::print() const fprintf(stderr, "close %d\n", fd); } +void io_fd_t::print() const +{ + fprintf(stderr, "FD map %d -> %d\n", old_fd, fd); +} + void io_buffer_read(io_data_t *d) { exec_close(d->param1.pipe_fd[1]); diff --git a/io.h b/io.h index d7ddbd0ec..627bfc39c 100644 --- a/io.h +++ b/io.h @@ -37,8 +37,6 @@ public: { /** Fds for IO_PIPE and for IO_BUFFER */ int pipe_fd[2]; - /** fd to redirect specified fd to, for IO_FD */ - int old_fd; } param1; @@ -47,8 +45,6 @@ public: { /** file creation flags to send to open for IO_FILE */ int flags; - /** Whether to close old_fd for IO_FD */ - int close_old; } param2; /** Filename IO_FILE. malloc'd. This needs to be used after fork, so don't use wcstring here. */ @@ -127,6 +123,24 @@ public: virtual void print() const; }; +class io_fd_t : public io_data_t +{ +public: + /** fd to redirect specified fd to */ + int old_fd; + /** Whether to close old_fd */ + int close_old; + + virtual void print() const; + + io_fd_t(int f, int old, bool close = false) : + io_data_t(IO_FD, f), + old_fd(old), + close_old(close) + { + } +}; + class io_chain_t : public std::vector > { public: diff --git a/parser.cpp b/parser.cpp index 1c5f330b2..1329cea62 100644 --- a/parser.cpp +++ b/parser.cpp @@ -1607,13 +1607,11 @@ void parser_t::parse_job_argument_list(process_t *p, { wchar_t *end; - new_io.reset(new io_data_t(IO_FD, fd)); errno = 0; - new_io->param1.old_fd = fish_wcstoi(target.c_str(), &end, 10); + int old_fd = fish_wcstoi(target.c_str(), &end, 10); - if ((new_io->param1.old_fd < 0) || - errno || *end) + if (old_fd < 0 || errno || *end) { error(SYNTAX_ERROR, tok_get_pos(tok), @@ -1622,6 +1620,10 @@ void parser_t::parse_job_argument_list(process_t *p, tok_next(tok); } + else + { + new_io.reset(new io_fd_t(fd, old_fd)); + } } break; } diff --git a/postfork.cpp b/postfork.cpp index 9b8913cec..a5602ad19 100644 --- a/postfork.cpp +++ b/postfork.cpp @@ -169,7 +169,7 @@ static int handle_child_io(io_chain_t &io_chain) io_data_t *io = io_chain.at(idx).get(); int tmp; - if (io->io_mode == IO_FD && io->fd == io->param1.old_fd) + if (io->io_mode == IO_FD && io->fd == static_cast(io)->old_fd) { continue; } @@ -232,7 +232,7 @@ static int handle_child_io(io_chain_t &io_chain) */ close(io->fd); - if (dup2(io->param1.old_fd, io->fd) == -1) + if (dup2(static_cast(io)->old_fd, io->fd) == -1) { debug_safe_int(1, FD_ERROR, io->fd); safe_perror("dup2"); @@ -443,9 +443,11 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil { shared_ptr io = j->io.at(idx); - if (io->io_mode == IO_FD && io->fd == io->param1.old_fd) + if (io->io_mode == IO_FD) { - continue; + CAST_INIT(const io_fd_t *, io_fd, io.get()); + if (io->fd == io_fd->old_fd) + continue; } if (io->fd > 2) @@ -472,8 +474,9 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil case IO_FD: { + CAST_INIT(const io_fd_t *, io_fd, io.get()); if (! err) - err = posix_spawn_file_actions_adddup2(actions, io->param1.old_fd /* from */, io->fd /* to */); + err = posix_spawn_file_actions_adddup2(actions, io_fd->old_fd /* from */, io->fd /* to */); break; }