From 00b6431ad9ec17f551b5ea175a46e5d63c181fc7 Mon Sep 17 00:00:00 2001 From: Cheer Xiao Date: Tue, 15 Jan 2013 17:31:36 +0800 Subject: [PATCH] Split out io_pipe_t, let io_buffer_t inherit it --- exec.cpp | 29 +++++++++++++---------------- io.cpp | 29 ++++++++++++++--------------- io.h | 29 +++++++++++++++++------------ postfork.cpp | 33 ++++++++++++++++++--------------- proc.cpp | 9 +++++---- 5 files changed, 67 insertions(+), 62 deletions(-) diff --git a/exec.cpp b/exec.cpp index 4c6e8bfc1..9e63c3d11 100644 --- a/exec.cpp +++ b/exec.cpp @@ -164,8 +164,8 @@ static bool use_fd_in_pipe(int fd, const io_chain_t &io_chain) if ((io->io_mode == IO_BUFFER) || (io->io_mode == IO_PIPE)) { - if (io->param1.pipe_fd[0] == fd || - io->param1.pipe_fd[1] == fd) + CAST_INIT(const io_pipe_t *, io_pipe, io.get()); + if (io_pipe->pipe_fd[0] == fd || io_pipe->pipe_fd[1] == fd) return true; } } @@ -615,17 +615,13 @@ void exec(parser_t &parser, job_t *j) } - shared_ptr pipe_read(new io_data_t); - pipe_read->fd = 0; - pipe_read->io_mode = IO_PIPE; + shared_ptr pipe_read(new io_pipe_t(0)); pipe_read->is_input = 1; - pipe_read->param1.pipe_fd[0] = pipe_read->param1.pipe_fd[1] = -1; + pipe_read->pipe_fd[0] = pipe_read->pipe_fd[1] = -1; - shared_ptr pipe_write(new io_data_t); - pipe_write->fd = 1; - pipe_write->io_mode = IO_PIPE; + shared_ptr pipe_write(new io_pipe_t(1)); pipe_write->is_input = 0; - pipe_write->param1.pipe_fd[0] = pipe_write->param1.pipe_fd[1] = -1; + pipe_write->pipe_fd[0] = pipe_write->pipe_fd[1] = -1; j->io.push_back(pipe_write); @@ -738,7 +734,7 @@ void exec(parser_t &parser, job_t *j) break; } - memcpy(pipe_write->param1.pipe_fd, mypipe, sizeof(int)*2); + memcpy(pipe_write->pipe_fd, mypipe, sizeof(int)*2); } else { @@ -855,7 +851,8 @@ void exec(parser_t &parser, job_t *j) } case IO_PIPE: { - builtin_stdin = in->param1.pipe_fd[0]; + CAST_INIT(const io_pipe_t *, in_pipe, in.get()); + builtin_stdin = in_pipe->pipe_fd[0]; break; } @@ -908,7 +905,7 @@ void exec(parser_t &parser, job_t *j) } else { - builtin_stdin = pipe_read->param1.pipe_fd[0]; + builtin_stdin = pipe_read->pipe_fd[0]; } if (builtin_stdin == -1) @@ -1332,14 +1329,14 @@ void exec(parser_t &parser, job_t *j) Close the pipe the current process uses to read from the previous process_t */ - if (pipe_read->param1.pipe_fd[0] >= 0) - exec_close(pipe_read->param1.pipe_fd[0]); + if (pipe_read->pipe_fd[0] >= 0) + exec_close(pipe_read->pipe_fd[0]); /* Set up the pipe the next process uses to read from the current process_t */ if (p_wants_pipe) - pipe_read->param1.pipe_fd[0] = mypipe[0]; + pipe_read->pipe_fd[0] = mypipe[0]; /* If there is a next process in the pipeline, close the diff --git a/io.cpp b/io.cpp index 0020659cf..4ec1d2bf4 100644 --- a/io.cpp +++ b/io.cpp @@ -53,12 +53,6 @@ Utilities for io redirection. void io_data_t::print() const { - switch (io_mode) - { - case IO_PIPE: - fprintf(stderr, "pipe {%d, %d}\n", param1.pipe_fd[0], param1.pipe_fd[1]); - break; - } } void io_close_t::print() const @@ -76,6 +70,11 @@ void io_file_t::print() const fprintf(stderr, "file (%s)\n", filename_cstr); } +void io_pipe_t::print() const +{ + fprintf(stderr, "pipe {%d, %d}\n", pipe_fd[0], pipe_fd[1]); +} + void io_buffer_t::print() const { fprintf(stderr, "buffer %p (size %lu)\n", out_buffer_ptr(), out_buffer_size()); @@ -83,21 +82,21 @@ void io_buffer_t::print() const void io_buffer_t::read() { - exec_close(param1.pipe_fd[1]); + exec_close(pipe_fd[1]); if (io_mode == IO_BUFFER) { - /* if( fcntl( param1.pipe_fd[0], F_SETFL, 0 ) ) + /* if( fcntl( pipe_fd[0], F_SETFL, 0 ) ) { wperror( L"fcntl" ); return; } */ - debug(4, L"io_buffer_t::read: blocking read on fd %d", param1.pipe_fd[0]); + debug(4, L"io_buffer_t::read: blocking read on fd %d", pipe_fd[0]); while (1) { char b[4096]; long l; - l=read_blocked(param1.pipe_fd[0], b, 4096); + l=read_blocked(pipe_fd[0], b, 4096); if (l==0) { break; @@ -115,7 +114,7 @@ void io_buffer_t::read() { debug(1, _(L"An error occured while reading output from code block on file descriptor %d"), - param1.pipe_fd[0]); + pipe_fd[0]); wperror(L"io_buffer_t::read"); } @@ -137,13 +136,13 @@ io_buffer_t *io_buffer_t::create(bool is_input) buffer_redirect->out_buffer_create(); buffer_redirect->is_input = is_input ? true : false; - if (exec_pipe(buffer_redirect->param1.pipe_fd) == -1) + if (exec_pipe(buffer_redirect->pipe_fd) == -1) { debug(1, PIPE_ERROR); wperror(L"pipe"); success = false; } - else if (fcntl(buffer_redirect->param1.pipe_fd[0], + else if (fcntl(buffer_redirect->pipe_fd[0], F_SETFL, O_NONBLOCK)) { @@ -170,10 +169,10 @@ io_buffer_t::~io_buffer_t() */ if (is_input) { - exec_close(param1.pipe_fd[1]); + exec_close(pipe_fd[1]); } - exec_close(param1.pipe_fd[0]); + exec_close(pipe_fd[0]); /* Dont free fd for writing. This should already be free'd before diff --git a/io.h b/io.h index 62087037c..5f3c1a678 100644 --- a/io.h +++ b/io.h @@ -27,15 +27,6 @@ public: /** FD to redirect */ int fd; - /** - Type-specific parameter for redirection - */ - union - { - /** Fds for IO_PIPE and for IO_BUFFER */ - int pipe_fd[2]; - } param1; - virtual void print() const; /** Set to true if this is an input io redirection */ @@ -44,7 +35,6 @@ public: io_data_t(io_mode_t m = IO_INVALID, int f=0) : io_mode(m), fd(f), - param1(), is_input(0) { } @@ -113,16 +103,31 @@ public: } }; -class io_buffer_t : public io_data_t +class io_pipe_t : public io_data_t +{ +public: + int pipe_fd[2]; + + virtual void print() const; + + io_pipe_t(int f): + io_data_t(IO_PIPE, f), + pipe_fd() + { + } +}; + +class io_buffer_t : public io_pipe_t { private: /** buffer to save output in */ shared_ptr > out_buffer; io_buffer_t(int f): - io_data_t(IO_BUFFER, f), + io_pipe_t(f), out_buffer() { + io_mode = IO_BUFFER; } public: diff --git a/postfork.cpp b/postfork.cpp index 17a46350a..558805ab4 100644 --- a/postfork.cpp +++ b/postfork.cpp @@ -117,15 +117,16 @@ static void free_redirected_fds_from_pipes(io_chain_t &io_chain) for (size_t j = 0; j < max; j++) { /* We're only interested in pipes */ - io_data_t *possible_conflict = io_chain.at(j).get(); - if (possible_conflict->io_mode != IO_PIPE && possible_conflict->io_mode != IO_BUFFER) + io_data_t *io = io_chain.at(j).get(); + if (io->io_mode != IO_PIPE && io->io_mode != IO_BUFFER) continue; + CAST_INIT(io_pipe_t *, possible_conflict, io); /* If the pipe is a conflict, dup it to some other value */ for (int k=0; k<2; k++) { /* If it's not a conflict, we don't care */ - if (possible_conflict->param1.pipe_fd[k] != fd_to_free) + if (possible_conflict->pipe_fd[k] != fd_to_free) continue; /* Repeat until we have a replacement fd */ @@ -140,7 +141,7 @@ static void free_redirected_fds_from_pipes(io_chain_t &io_chain) FATAL_EXIT(); } } - possible_conflict->param1.pipe_fd[k] = replacement_fd; + possible_conflict->pipe_fd[k] = replacement_fd; } } } @@ -245,6 +246,7 @@ static int handle_child_io(io_chain_t &io_chain) case IO_BUFFER: case IO_PIPE: { + CAST_INIT(io_pipe_t *, io_pipe, io); /* If write_pipe_idx is 0, it means we're connecting to the read end (first pipe fd). If it's 1, we're connecting to the write end (second pipe fd). */ unsigned int write_pipe_idx = (io->is_input ? 0 : 1); /* @@ -253,20 +255,20 @@ static int handle_child_io(io_chain_t &io_chain) write_pipe?L"write":L"read", (io->io_mode == IO_BUFFER)?L"buffer":L"pipe", io->fd, - io->param1.pipe_fd[0], - io->param1.pipe_fd[1]); + io->pipe_fd[0], + io->pipe_fd[1]); */ - if (dup2(io->param1.pipe_fd[write_pipe_idx], io->fd) != io->fd) + if (dup2(io_pipe->pipe_fd[write_pipe_idx], io->fd) != io->fd) { debug_safe(1, LOCAL_PIPE_ERROR); safe_perror("dup2"); return -1; } - if (io->param1.pipe_fd[0] >= 0) - exec_close(io->param1.pipe_fd[0]); - if (io->param1.pipe_fd[1] >= 0) - exec_close(io->param1.pipe_fd[1]); + if (io_pipe->pipe_fd[0] >= 0) + exec_close(io_pipe->pipe_fd[0]); + if (io_pipe->pipe_fd[1] >= 0) + exec_close(io_pipe->pipe_fd[1]); break; } @@ -485,8 +487,9 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil case IO_BUFFER: case IO_PIPE: { + CAST_INIT(const io_pipe_t *, io_pipe, io.get()); unsigned int write_pipe_idx = (io->is_input ? 0 : 1); - int from_fd = io->param1.pipe_fd[write_pipe_idx]; + int from_fd = io_pipe->pipe_fd[write_pipe_idx]; int to_fd = io->fd; if (! err) err = posix_spawn_file_actions_adddup2(actions, from_fd, to_fd); @@ -495,14 +498,14 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil if (write_pipe_idx > 0) { if (! err) - err = posix_spawn_file_actions_addclose(actions, io->param1.pipe_fd[0]); + err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[0]); if (! err) - err = posix_spawn_file_actions_addclose(actions, io->param1.pipe_fd[1]); + err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[1]); } else { if (! err) - err = posix_spawn_file_actions_addclose(actions, io->param1.pipe_fd[0]); + err = posix_spawn_file_actions_addclose(actions, io_pipe->pipe_fd[0]); } break; diff --git a/proc.cpp b/proc.cpp index 2e6e32ee9..87c8f362f 100644 --- a/proc.cpp +++ b/proc.cpp @@ -869,10 +869,11 @@ static int select_try(job_t *j) for (size_t idx = 0; idx < j->io.size(); idx++) { - const io_data_t *d = j->io.at(idx).get(); - if (d->io_mode == IO_BUFFER) + const io_data_t *io = j->io.at(idx).get(); + if (io->io_mode == IO_BUFFER) { - int fd = d->param1.pipe_fd[0]; + CAST_INIT(const io_pipe_t *, io_pipe, io); + int fd = io_pipe->pipe_fd[0]; // fwprintf( stderr, L"fd %d on job %ls\n", fd, j->command ); FD_SET(fd, &fds); maxfd = maxi(maxfd, fd); @@ -924,7 +925,7 @@ static void read_try(job_t *j) char b[BUFFER_SIZE]; long l; - l=read_blocked(buff->param1.pipe_fd[0], + l=read_blocked(buff->pipe_fd[0], b, BUFFER_SIZE); if (l==0) {