diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2015-01-07 18:07:06 -0800 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2015-01-07 18:07:06 -0800 |
commit | 7864d0d416519774c614148920530bc7da4a3e3b (patch) | |
tree | a2fab74e5d3145349440d098d4cfc00363a3284c /postfork.cpp | |
parent | d1feb9bcbf141e2195f37a8ab0f526c24a533cda (diff) |
Rework file descriptor handling
Remove global array of file descriptors, in
favor of relying on CLO_EXEC exclusively.
Also correctly implement "pipe avoidance" so
that fd redirections do not conflict
with pipes.
Diffstat (limited to 'postfork.cpp')
-rw-r--r-- | postfork.cpp | 69 |
1 files changed, 1 insertions, 68 deletions
diff --git a/postfork.cpp b/postfork.cpp index 80318c47..8222862c 100644 --- a/postfork.cpp +++ b/postfork.cpp @@ -107,53 +107,6 @@ int set_child_group(job_t *j, process_t *p, int print_errors) return res; } -/** Make sure the fd used by each redirection is not used by a pipe. Note that while this does not modify the vector, it does modify the IO redirections within (gulp) */ -static void free_redirected_fds_from_pipes(const io_chain_t &io_chain) -{ - size_t max = io_chain.size(); - for (size_t i = 0; i < max; i++) - { - int fd_to_free = io_chain.at(i)->fd; - - /* We only have to worry about fds beyond the three standard ones */ - if (fd_to_free <= 2) - continue; - - /* Make sure the fd is not used by a pipe */ - for (size_t j = 0; j < max; j++) - { - /* We're only interested in pipes */ - 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->pipe_fd[k] != fd_to_free) - continue; - - /* Repeat until we have a replacement fd */ - int replacement_fd = -1; - while (replacement_fd < 0) - { - replacement_fd = dup(fd_to_free); - if (replacement_fd == -1 && errno != EINTR) - { - debug_safe_int(1, FD_ERROR, fd_to_free); - safe_perror("dup"); - FATAL_EXIT(); - } - } - possible_conflict->pipe_fd[k] = replacement_fd; - } - } - } -} - - /** Set up a childs io redirections. Should only be called by setup_child_process(). Does the following: First it closes any open @@ -168,9 +121,6 @@ static void free_redirected_fds_from_pipes(const io_chain_t &io_chain) */ static int handle_child_io(const io_chain_t &io_chain) { - //fprintf(stderr, "child IO for %d\n", getpid()); - close_unused_internal_pipes(io_chain); - free_redirected_fds_from_pipes(io_chain); for (size_t idx = 0; idx < io_chain.size(); idx++) { const io_data_t *io = io_chain.at(idx).get(); @@ -442,18 +392,7 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil sigemptyset(&sigmask); if (! err && reset_sigmask) err = posix_spawnattr_setsigmask(attr, &sigmask); - - /* Make sure that our pipes don't use an fd that the redirection itself wants to use */ - free_redirected_fds_from_pipes(io_chain); - - /* Close unused internal pipes */ - std::vector<int> files_to_close; - get_unused_internal_pipes(files_to_close, io_chain); - for (size_t i = 0; ! err && i < files_to_close.size(); i++) - { - err = posix_spawn_file_actions_addclose(actions, files_to_close.at(i)); - } - + for (size_t idx = 0; idx < io_chain.size(); idx++) { const shared_ptr<const io_data_t> io = io_chain.at(idx); @@ -465,12 +404,6 @@ bool fork_actions_make_spawn_properties(posix_spawnattr_t *attr, posix_spawn_fil continue; } - if (io->fd > 2) - { - /* Make sure the fd used by this redirection is not used by e.g. a pipe. */ - // free_fd(io_chain, io->fd ); - // PCA I don't think we need to worry about this. fd redirection is pretty uncommon anyways. - } switch (io->io_mode) { case IO_CLOSE: |