ftp.nice.ch/pub/next/unix/network/system/NeXTICS.NIHS.bs.tar.gz#/NeXTICS/Source/spawn.c

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.