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.