Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!rex!uflorida!travis!brad From: brad@SSD.CSD.HARRIS.COM (Brad Appleton) Newsgroups: comp.unix.programmer Subject: Re: More on how to do a pipe (was re: system() problem) Message-ID: <2506@travis.csd.harris.com> Date: 6 Mar 91 15:21:43 GMT References: <1991Mar6.025034.8697@csusac.csus.edu> Sender: news@travis.csd.harris.com Organization: Harris Computers Systems Division, Fort Lauderdale,FL Lines: 103 In article <1991Mar6.025034.8697@csusac.csus.edu> emmonsl@athena.ecs.csus.edu (L. Scott Emmons) writes: > >After some thinking about my pipe(), fork(), exec() implementation in my >last post, I knew there was something funky about the way I did it... > >Here is another version of my pipe program, about as efficient as my >previous version, but a bit cleaner (unless use of SIGCHLD is used for >something other than just closing the pipe() down.) I hate to be critical but I didnt care for the way the status codes from dup2 and pipe were ignored. I have a piece of code from a while back that was created specifically for the purpose of illustrating how to use fork and how to redirect parent/child i/o. Its a bit longer than yours but is cleaner (IMHO) and is easy to read. (BTW let me know ASAP of any errors - I thought they were all worked out be now but who knows): ------------------------------------- cut here -------------------------------- /* I/O Redirection example */ #include #define BUF_LEN 256 #define NULLSTR (char *)NULL /* read & write ends of a pipe */ #define READ_END 0 #define WRITE_END 1 /* ** macro to replace the dup2 system call (if its not present) */ ** ** NOTE: dup() returns the LOWEST NUMBERED available file descriptor. ** it is assumed below, that no file descriptors numbered lower ** than are available before the dup2 macro is invoked!! */ #ifdef DONT_HAVE_DUP2_SYSTEM_CALL # define dup2(to,from) ( (close(from) || (to = dup()) < 0) ? -1 : 0 ) #endif main( argc, argv ) int argc; char *argv[]; { int nbytes, /* number of bytes read */ status, /* return-code/status for various system calls */ pipe_fd[2]; /* pipe file-descriptor array */ char buf[ BUF_LEN ]; /* character buffer*/ /* open a pipe */ if ( pipe(pipe_fd) < 0 ) { perror( "unable to open unnamed pipe\n" ); exit( 1 ); } switch ( fork() ) { case -1: /* failure */ perror( "Unable to fork off a process" ); break; case 0: /* child */ /* redirect stdout to the write end of the pipe */ if ( dup2( pipe_fd[ WRITE_END ], fileno(stdout) ) < 0 ) { perror( "unable to redirect STDOUT to write end of pipe" ); exit( 1 ); } fprintf( stderr, "Child: Going to exec uptime (pid=%x).\n", getpid() ); fflush( stderr ); execl( "/usr/ucb/uptime", "uptime", NULLSTR ); break; default: /* parent */ do { /* read output from child (until see '\n' ) */ printf( "\n\nParent: reading from pipe\n\n" ); fflush( stdout ); if ( (nbytes=read( pipe_fd[ READ_END ], buf, BUF_LEN )) <0 ) { perror( "failed on pipe read" ); } if ( write( fileno(stdout), buf, nbytes ) != nbytes ) { perror( "failed on STDOUT write" ); } } while ( buf[ nbytes-1 ] != '\n' ); printf( "Parent: Waiting for child (pid=%x).\n", getpid() ); fflush( stdout ); wait( &status ); printf( "Parent: Child died (status=%x).\n", status ); fflush( stdout ); close( pipe_fd[ READ_END ] ); break; } exit( 0 ); } ______________________ "And miles to go before I sleep." ______________________ Brad Appleton brad@ssd.csd.harris.com Harris Computer Systems uunet!hcx1!brad Fort Lauderdale, FL USA ~~~~~~~~~~~~~~~~~~~~ Disclaimer: I said it, not my company! ~~~~~~~~~~~~~~~~~~~