Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!apple!altos!megadon!clp From: bliss@sp64.csrd.uiuc.edu (Brian Bliss) Newsgroups: comp.unix Subject: Re: PIPES Message-ID: <2289@megadon.UUCP> Date: 6 Dec 90 22:30:01 GMT References: <2274@megadon.UUCP> <2281@megadon.UUCP> Sender: clp@megadon.UUCP Reply-To: bliss@sp64.csrd.uiuc.edu (Brian Bliss) Organization: Center for Supercomputing Research and Development Lines: 137 Approved: clp@megadon.UUCP I've done this before, and ran into this problem. well, you perfrom the fork, test whether you are child or parent, and then get ready to dup the pipes: if(c) { /* parent */ dup2(p2c[1], 1); dup2(c2p[0], 0); } else { /* child */ dup2(c2p[1], 1); dup2(p2c[0], 0); } consider the case of the parent: what if c2p[0] is fd 1? then the first dup2 call overwrites fd 1 before it can be copied to 0. it's really a pain if you need to dup fd 0 to 1, and fd 1 to 0, but here's a fix I wrote that should do what you want: /*****************************************************************************/ /* this file, "fork_cpp.c", is the source for a command which exec's a */ /* child process, sets the child's stdin to be to_child and returns a FILE */ /* pointer to its stdout (*from_child) and the child's process id (the */ /* function's return val). */ /*****************************************************************************/ # include # include #define RDR 0 #define WTR 1 int ae_fork_cpp (cmd, to_child, from_child) /*****************************************************************************/ /* ae_popen2 exec's cmd, sets the child's stdin to *to_child, and creats a */ /* a pipe from the child's stdout to *from_child. ae_fork_cpp () returns */ /* the process id of the child, or -1 for an error. It is used by the */ /* application executive to invoke the C preprocessor. */ /*****************************************************************************/ char *cmd; FILE *to_child; FILE **from_child; { int c2p[2]; register int child_stdin; register int child_stdout; register int parent_reader; register int pid; if (pipe (c2p) < 0) { return (-1); } child_stdout = c2p[WTR]; parent_reader = c2p[RDR]; child_stdin = fileno (to_child); /*************************************************/ /* if child_stdout == 0, it will be overwritten */ /* when dup2'ing child_stdin to 0, so change it. */ /* this should be done before the fork, in case */ /* of an error. */ /*************************************************/ if (child_stdout == 0) { if ((child_stdout = dup (child_stdout)) == -1) { close (child_stdout); close (parent_reader); return (-1); } close (child_stdout); } /********************/ /* perform the fork */ /********************/ if ((pid = fork ()) == -1) { close (child_stdout); close (parent_reader); return (-1); } if (pid == 0) { /**************************************************/ /* we are the child process - close the parent's */ /* file descriptor, and copy our file descriptors */ /* to 0 and 1, our stdin and stdout fd's. then, */ /* exec the appropriate command. */ /**************************************************/ close (parent_reader); if (child_stdout != 0) { if (child_stdin != 0) { dup2 (child_stdin, 0); close (child_stdin); } if (child_stdout != 1) { dup2 (child_stdout, 1); close (child_stdout); } } else { int temp; temp = open ("/dev/null", "w"); dup2 (child_stdout, temp); close (child_stdout); if (child_stdin != 0) { dup2 (child_stdin, 0); close (child_stdin); } dup2 (temp, 1); close (temp); } execl("/bin/sh", "sh", "-c", cmd, 0); /* it is an error to get past here */ exit(1); } else { /**************************************************/ /* we are the parent process - close the child's */ /* stdout file descriptor, set the from_child */ /* file pointer, and return the pid of the child. */ /**************************************************/ close (child_stdout); *from_child = fdopen (parent_reader, "r"); return(pid); } } Brought to you by Super Global Mega Corp .com