This is spawn.c in view mode; [Download] [Up]
#include <stdio.h> #include <sys/types.h> #include <sys/time.h> #include <libc.h> #include "spawn.h" int childStdin; int childStdout; int childStatus; int childProcess; void (*filterFunc)(); struct sgttyb origTerm; void turnOnEcho() { struct sgttyb t; t = origTerm; t.sg_flags |= CBREAK; t.sg_flags |= ECHO; ioctl(fileno(stdin), TIOCSETP, &t); } void turnOffEcho() { struct sgttyb t; t = origTerm; t.sg_flags |= CBREAK; t.sg_flags &= ~ECHO; ioctl(fileno(stdin), TIOCSETP, &t); } int Spawn( name, argv, charFilter ) char *name; char *argv[]; void (*charFilter)(); { int cPipeW[2]; int cPipeR[2]; ioctl(fileno(stdin), TIOCGETP, &origTerm); pipe( cPipeW ); pipe( cPipeR ); childProcess = vfork(); if (childProcess) { close(cPipeW[0]); childStdin = cPipeW[1]; close(cPipeR[1]); childStdout = cPipeR[0]; filterFunc = charFilter; return 0; /* Parent returns, child execs */ } if ( dup2(cPipeW[0],fileno(stdin)) == -1 ) exit(1); if ( dup2(cPipeR[1],fileno(stdout)) == -1 ) exit(1); if ( dup2(cPipeR[1],fileno(stderr)) == -1 ) exit(1); close(cPipeW[0]); close(cPipeR[1]); execv( name, argv ); fprintf( stderr, "Couldn't exec...\n" ); exit(1); } void cleanUp() { ioctl(fileno(stdin), TIOCSETP, &origTerm);/* Back to original tty settings */ if (childProcess) { kill(0, SIGTERM); } } int childPID() { return childProcess; } int WriteChars( buf, num ) char *buf; int num; { return write( childStdin, buf, num ); } int childsOutput() { return childStdout; } void RunSelect( timeout ) struct timeval *timeout; { fd_set readfds; int nfound; char buf[1025]; int numread; FD_ZERO(&readfds); FD_SET( fileno(stdin), &readfds ); FD_SET( childStdout, &readfds ); nfound = select( 256, &readfds, 0, 0, timeout ); if (nfound == 0) return; if (FD_ISSET( childStdout, &readfds )) { numread = read( childStdout, buf, 1024 ); if (numread <= 0) { childProcess = 0; return; } if (numread > 0) { write( fileno(stdout), buf, numread ); } if (filterFunc) filterFunc( buf, numread ); } if (FD_ISSET( fileno(stdin), &readfds )) { numread = read( fileno(stdin), buf, 1024 ); if (numread < 0) { childProcess = 0; return; } if (numread > 0) { write( childStdin, buf, numread ); } } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.