Merge branch 'collectd-4.2' into collectd-4.3
authorFlorian Forster <octo@crystal.wlan.home.verplant.org>
Wed, 9 Apr 2008 16:34:48 +0000 (18:34 +0200)
committerFlorian Forster <octo@crystal.wlan.home.verplant.org>
Wed, 9 Apr 2008 16:34:48 +0000 (18:34 +0200)
Conflicts:

src/exec.c

1  2 
src/exec.c

diff --cc src/exec.c
@@@ -419,46 -262,27 +419,55 @@@ static int fork_child (program_list_t *
        sstrerror (errno, errbuf, sizeof (errbuf)));
      return (-1);
    }
 -  else if (pl->pid == 0)
 +  else if (pid == 0)
    {
-     close (fd_pipe_in[1]);
-     close (fd_pipe_out[0]);
+     int fd_num;
+     int fd;
+     /* Close all file descriptors but the pipe end we need. */
+     fd_num = getdtablesize ();
+     for (fd = 0; fd < fd_num; fd++)
+     {
 -      if (fd == fd_pipe[1])
++      if ((fd == fd_pipe_in[0]) || (fd == fd_pipe_out[1]))
+       continue;
+       close (fd);
+     }
  
 -    /* Connect the pipe to STDOUT and STDERR */
 -    if (fd_pipe[1] != STDOUT_FILENO)
 -      dup2 (fd_pipe[1], STDOUT_FILENO);
 -    if (fd_pipe[1] != STDERR_FILENO)
 -      dup2 (fd_pipe[1], STDERR_FILENO);
 -    if ((fd_pipe[1] != STDOUT_FILENO) && (fd_pipe[1] != STDERR_FILENO))
 -      close (fd_pipe[1]);
 +    /* If the `out' pipe has the filedescriptor STDIN we have to be careful
 +     * with the `dup's below. So, if this is the case we have to handle the
 +     * `out' pipe first. */
 +    if (fd_pipe_out[1] == STDIN_FILENO)
 +    {
 +      int new_fileno = (fd_pipe_in[0] == STDOUT_FILENO)
 +      ? STDERR_FILENO : STDOUT_FILENO;
 +      dup2 (fd_pipe_out[1], new_fileno);
 +      close (fd_pipe_out[1]);
 +      fd_pipe_out[1] = new_fileno;
 +    }
 +    /* Now `fd_pipe_out[1]' is either `STDOUT' or `STDERR', but definitely not
 +     * `STDIN_FILENO'. */
 +
 +    /* Connect the `in' pipe to STDIN */
 +    if (fd_pipe_in[0] != STDIN_FILENO)
 +    {
 +      dup2 (fd_pipe_in[0], STDIN_FILENO);
 +      close (fd_pipe_in[0]);
 +      fd_pipe_in[0] = STDIN_FILENO;
 +    }
 +
 +    /* Now connect the `out' pipe to STDOUT and STDERR */
 +    if (fd_pipe_out[1] != STDOUT_FILENO)
 +      dup2 (fd_pipe_out[1], STDOUT_FILENO);
 +    if (fd_pipe_out[1] != STDERR_FILENO)
 +      dup2 (fd_pipe_out[1], STDERR_FILENO);
 +
 +    /* If the pipe has some FD that's something completely different, close it
 +     * now. */
 +    if ((fd_pipe_out[1] != STDOUT_FILENO) && (fd_pipe_out[1] != STDERR_FILENO))
 +    {
 +      close (fd_pipe_out[1]);
 +      fd_pipe_out[1] = STDOUT_FILENO;
 +    }
  
      exec_child (pl);
      /* does not return */