🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.unix
Article #341

Re: PIPES

#341
From: Brian Bliss
Date: Thu, 06 Dec 1990 22:30
137 lines
5094 bytes
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 <stdio.h>
# include <signal.h>



#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);
      }
   }
Technical Details
Message-ID: <2289@megadon.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!apple!altos!megadon!clp
References: <2274@megadon.UUCP> <2281@megadon.UUCP>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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