Ejemplo n.º 1
0
PTR
get_pipe(char *name, int type, int *pid_ptr)
{
    int the_pipe[2], local_fd, remote_fd;

    if (pipe(the_pipe) == -1)
	return (PTR) 0;

    /*
     * If this is an input-pipe then local_fd is reader, remote_fd is writer
     * If this is an output-pipe then local_fd is writer, remote_fd is reader
     */
    local_fd = the_pipe[type == PIPE_OUT];
    remote_fd = the_pipe[type == PIPE_IN];

    /* to keep output ordered correctly */
    fflush(stdout);
    fflush(stderr);

    switch (*pid_ptr = fork()) {
    case -1:
	close(local_fd);
	close(remote_fd);
	return (PTR) 0;

    case 0:
	/*
	 * This is the child process.  Close the unused end of the pipe, i.e,
	 * (local_fd) and then close the input/output file descriptor that
	 * corresponds to the direction we want to read/write.
	 *
	 * The dup() call uses the first unused file descriptor, which happens
	 * to be the one that we just closed, e.g., 0 or 1 for stdin and stdout
	 * respectively.
	 */
	close(local_fd);
	close(type == PIPE_IN);
	IGNORE_RC(dup(remote_fd));
	close(remote_fd);
	execl(shell, shell, "-c", name, (char *) 0);
	errmsg(errno, "failed to exec %s -c %s", shell, name);
	fflush(stderr);
	_exit(128);

    default:
	close(remote_fd);
	/* we could deadlock if future child inherit the local fd ,
	   set close on exec flag */
	(void) CLOSE_ON_EXEC(local_fd);
	break;
    }

    return ((type == PIPE_IN)
	    ? (PTR) FINdopen(local_fd, 0)
	    : (PTR) fdopen(local_fd, "w"));
}
Ejemplo n.º 2
0
/* Adds file descriptors to the child structure to support output_sync; one
   for stdout and one for stderr as long as they are open.  If stdout and
   stderr share a device they can share a temp file too.
   Will reset output_sync on error.  */
static void
setup_tmpfile (struct output *out)
{
  /* Is make's stdout going to the same place as stderr?  */
  static int combined_output = -1;

  if (combined_output < 0)
    combined_output = sync_init ();

  if (STREAM_OK (stdout))
    {
      int fd = output_tmpfd ();
      if (fd < 0)
        goto error;
      CLOSE_ON_EXEC (fd);
      out->out = fd;
    }

  if (STREAM_OK (stderr))
    {
      if (out->out != OUTPUT_NONE && combined_output)
        out->err = out->out;
      else
        {
          int fd = output_tmpfd ();
          if (fd < 0)
            goto error;
          CLOSE_ON_EXEC (fd);
          out->err = fd;
        }
    }

  return;

  /* If we failed to create a temp file, disable output sync going forward.  */
 error:
  output_close (out);
  output_sync = 0;
}