1
0
mirror of https://github.com/Interlisp/maiko.git synced 2026-01-21 10:03:00 +00:00
Interlisp.maiko/src/unixfork.c
Nick Briggs 6528ac38e3 Remove proprietary license from all files.
The code is being re-licensed under the MIT license.

	modified:   bin/fixid
	modified:   bin/launch.asm
	modified:   bin/makefile-hpux.hp9000-x
	modified:   bin/makefile-init.sgi
	modified:   bin/makefile-init.sparc
	modified:   bin/makefile-init.sparc-multi
	modified:   bin/makefile-irix.sgi-x
	modified:   bin/makefile-sunos4.sparc
	modified:   bin/makefile-sunos4.sparc%
	modified:   bin/makefile-sunos4.sparc-multi
	modified:   bin/makefile-sunos5.386-x
	modified:   bin/makefile-sunos5.i386-x
	modified:   bin/makefile-sunos5.sparc-x
	modified:   bin/makefile-tail
	modified:   bin/makeisc
	modified:   bin/makeright
	modified:   inc/Check.h
	modified:   inc/MyWindow.h
	modified:   inc/Stipple.h
	modified:   inc/XCursors.h
	modified:   inc/XKeymap.h
	modified:   inc/XVersion.h
	modified:   inc/Xdeflt.h
	modified:   inc/Xicon.h
	modified:   inc/address.h
	modified:   inc/arith.h
	modified:   inc/arith2.h
	modified:   inc/array.h
	modified:   inc/bb.h
	modified:   inc/cell.h
	modified:   inc/cell.h%
	modified:   inc/copyright
	modified:   inc/dbprint.h
	modified:   inc/debug.h
	modified:   inc/devif.h
	modified:   inc/display.h
	modified:   inc/dspdata.h
	modified:   inc/ether.h
	modified:   inc/fast_dsp.h
	modified:   inc/fp.h
	modified:   inc/gc.h
	modified:   inc/gc.h.save
	modified:   inc/gcscan.h
	modified:   inc/hdw_conf.h
	modified:   inc/ifpage.h
	modified:   inc/inlineC.h
	modified:   inc/inlnMIPS.h
	modified:   inc/inlnPS2.h
	modified:   inc/inlndos.h
	modified:   inc/iopage.h
	modified:   inc/kbdif.h
	modified:   inc/keyboard.h
	modified:   inc/keyboard.h%
	modified:   inc/keysym.h
	modified:   inc/ldeXdefs.h
	modified:   inc/lispemul.h
	modified:   inc/lispemul.h.save
	modified:   inc/lispmap.h
	modified:   inc/lldsp.h
	modified:   inc/lnk-Xdeflt.h
	modified:   inc/lnk-debug.h
	modified:   inc/lnk-fast_dsp.h
	modified:   inc/lnk-inlineC.h
	modified:   inc/lnk-lispmap.h
	modified:   inc/lnk-tosfns.h
	modified:   inc/lnk-tosret.h
	modified:   inc/locfile.h
	modified:   inc/lpdefs.h
	modified:   inc/lpglobl.h
	modified:   inc/lspglob.h
	modified:   inc/lsptypes.h
	modified:   inc/medleyfp.h
	modified:   inc/mnxdefs.h
	modified:   inc/my.h
	modified:   inc/native.h
	modified:   inc/ocr.h
	modified:   inc/osmsg.h
	modified:   inc/picture.h
	modified:   inc/pilotbbt.h
	modified:   inc/print.h
	modified:   inc/profile.h
	modified:   inc/rawrs232c.h
	modified:   inc/return.h
	modified:   inc/rs232c.h
	modified:   inc/stack.h
	modified:   inc/stream.h
	modified:   inc/stream.h%
	modified:   inc/stream.h2
	modified:   inc/sysatms.h
	modified:   inc/timeout.h
	modified:   inc/tos1defs.h
	modified:   inc/tosfns.h
	modified:   inc/tosret.h
	modified:   inc/tty.h
	modified:   inc/version.h
	modified:   inc/vmemsave.h
	modified:   inc/xbitmaps.h
	modified:   inc/xdefs.h
	modified:   src/Cldeetr.c
	modified:   src/allocmds.c
	modified:   src/arith2.c
	modified:   src/arith3.c
	modified:   src/arith4.c
	modified:   src/array.c
	modified:   src/array2.c
	modified:   src/array3.c
	modified:   src/array4.c
	modified:   src/array5.c
	modified:   src/array6.c
	modified:   src/asmbbt.c
	modified:   src/asmbitblt.c
	modified:   src/atom.c
	modified:   src/bbtSPARC.s
	modified:   src/bbtsub.c
	modified:   src/bin.c
	modified:   src/binds.c
	modified:   src/bitblt.c
	modified:   src/blt.c
	modified:   src/byteswap.c
	modified:   src/call-c.c
	modified:   src/car-cdr.c
	modified:   src/cdaudio.c
	modified:   src/cdrom.c
	modified:   src/chardev.c
	modified:   src/chatter.c
	modified:   src/codeconv.c
	modified:   src/codetbl.c
	modified:   src/colorbltfns.c
	modified:   src/common.c
	modified:   src/conspage.c
	modified:   src/cr
	modified:   src/dbgtool.c
	modified:   src/dir.c
	modified:   src/doscomm.c
	modified:   src/doskbd.c
	modified:   src/dosmouse.c
	modified:   src/draw.c
	modified:   src/dsk.c
	modified:   src/dspif.c
	modified:   src/dspsubrs.c
	modified:   src/ejlisp.c
	modified:   src/eqf.c
	modified:   src/ether.c
	modified:   src/findkey.c
	modified:   src/foreign.c
	modified:   src/fp.c
	modified:   src/fvar.c
	modified:   src/gc.c
	modified:   src/gc2.c
	modified:   src/gcarray.c
	modified:   src/gccode.c
	modified:   src/gcfinal.c
	modified:   src/gchtfind.c
	modified:   src/gcmain3.c
	modified:   src/gcoflow.c
	modified:   src/gcr.c
	modified:   src/gcrcell.c
	modified:   src/gcscan.c
	modified:   src/gvar2.c
	modified:   src/hacks.c
	modified:   src/hardrtn.c
	modified:   src/imagefile.c
	modified:   src/imagefile2.c
	modified:   src/inet.c
	modified:   src/initdsp.c
	modified:   src/initkbd.c
	modified:   src/initsout.c
	modified:   src/intcall.c
	modified:   src/kbdif.c
	modified:   src/kbdsubrs.c
	modified:   src/keyevent.c
	modified:   src/keylib.c
	modified:   src/keymaker.c
	modified:   src/keytst.c
	modified:   src/keytstno.c
	modified:   src/kprint.c
	modified:   src/launch.asm
	modified:   src/ldeboot.c
	modified:   src/ldeether.c
	modified:   src/ldsout.c
	modified:   src/lineblt8.c
	modified:   src/lisp2c.c
	modified:   src/llcolor.c
	modified:   src/llstk.c
	modified:   src/loader.c
	modified:   src/loopsops.c
	modified:   src/lowlev1.c
	modified:   src/lowlev2.c
	modified:   src/lpdual.c
	modified:   src/lpkit.c
	modified:   src/lplexyy.c
	modified:   src/lpmain.c
	modified:   src/lpread.c
	modified:   src/lpsolve.c
	modified:   src/lptran.c
	modified:   src/lpwrite.c
	modified:   src/lpytab.c
	modified:   src/lsthandl.c
	modified:   src/main.c
	modified:   src/misc7.c
	modified:   src/miscn.c
	modified:   src/mkatom.c
	modified:   src/mkcell.c
	modified:   src/mkkey.c
	modified:   src/mkvdate.c
	modified:   src/mnwevent.c
	modified:   src/mnxmeth.c
	modified:   src/mouseif.c
	modified:   src/mvs.c
	modified:   src/ocr.c
	modified:   src/ocrproc.c
	modified:   src/oether.c
	modified:   src/oldeether.c
	modified:   src/optck.c
	modified:   src/osmsg.c
	modified:   src/perrno.c
	modified:   src/picture.c
	modified:   src/rawcolor.c
	modified:   src/rawrs232c.c
	modified:   src/return.c
	modified:   src/rpc.c
	modified:   src/rplcons.c
	modified:   src/rs232c.c
	modified:   src/setsout.c
	modified:   src/shift.c
	modified:   src/socdvr.c
	modified:   src/storage.c
	modified:   src/subr.c
	modified:   src/subr0374.c
	modified:   src/sxhash.c
	modified:   src/testdsp.c
	modified:   src/testtool.c
	modified:   src/timeoday.c
	modified:   src/timeofday.c
	modified:   src/timer.c
	modified:   src/truecolor.c
	modified:   src/tstsout.c
	modified:   src/tty.c
	modified:   src/typeof.c
	modified:   src/ubf1.c
	modified:   src/ubf2.c
	modified:   src/ubf3.c
	modified:   src/ufn.c
	modified:   src/ufs.c
	modified:   src/unixcomm.c
	modified:   src/unixfork.c
	modified:   src/unwind.c
	modified:   src/uraid.c
	modified:   src/usrsubr.c
	modified:   src/uutils.c
	modified:   src/vars3.c
	modified:   src/vesafns.asm
	modified:   src/vesainit.c
	modified:   src/vgainit.c
	modified:   src/vmemsave.c
	modified:   src/xbbt.c
	modified:   src/xc.c
	modified:   src/xc.c.orig
	modified:   src/xcursor.c
	modified:   src/xinit.c
	modified:   src/xlspwin.c
	modified:   src/xmkicon.c
	modified:   src/xrdopt.c
	modified:   src/xscroll.c
	modified:   src/xwinman.c
	modified:   src/z2.c
2020-08-11 18:39:45 -07:00

679 lines
19 KiB
C

/* $Id: unixfork.c,v 1.6 2001/12/26 22:17:05 sybalsky Exp $ (C) Copyright Venue, All Rights Reserved
*/
static char *id = "$Id: unixfork.c,v 1.6 2001/12/26 22:17:05 sybalsky Exp $ Copyright (C) Venue";
/************************************************************************/
/* */
/* Code to fork a subprocess for Unix communication */
/* */
/* */
/* */
/************************************************************************/
/************************************************************************/
/* */
/* (C) Copyright 1989-1998 Venue. All Rights Reserved. */
/* Manufactured in the United States of America. */
/* */
/************************************************************************/
#include "version.h"
#include <stdlib.h>
#include <string.h>
#ifdef OS4
#define USETERMIOS
#endif
#ifdef OS5
#define USETERMIOS
#include <sys/stropts.h>
#define FULLSLAVENAME
#endif
#ifdef INDIGO
#define USETERMIOS
#define TCSETS TCSETA
#define TCGETS TCGETA
#define FULLSLAVENAME
#endif
#include <sys/ioctl.h>
#ifndef USETERMIOS
#include <sys/ioctl.h>
#else
#if defined(INDIGO) || defined(MACOSX) || defined(FREEBSD)
#include <termios.h>
#else
#include <sys/termios.h>
#endif /* INDIGO */
#endif /* USETERMIOS */
#ifdef OSF1
#define _CLOCK_ID_T
typedef int clockid_t;
#include "time.h"
#include <sys/resource.h>
#endif /* OSF1 */
#ifdef HPUX
#include <sgtty.h>
#include <unistd.h>
#endif /* HPUX */
#if defined(SYSVONLY) || defined(OS5) || defined(FREEBSD) || defined(MACOSX)
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#endif /* SYSVONLY */
#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include "dbprint.h"
#include <sys/socket.h>
#include <sys/un.h>
#ifdef RISCOS
/* #include <sys/un.h> */
#include <sgtty.h>
#endif /* RISCOS */
#ifdef INDIGO
/* #include <sys/un.h> */
#include <sgtty.h>
#endif
#include "unixfork.h"
#ifdef DEBUG
/* required by DBPRINT from dbprint.h */
extern int flushing = 0;
#endif
/* The following globals are used to communicate between Unix
subprocesses and LISP */
long StartTime; /* Time, for creating pipe filenames */
char shcom[512]; /* Here because I'm suspicious of */
/* large allocations on the stack */
static __inline__ int
SAFEREAD(int f, char *b, int c)
{
int res;
loop:
res = read(f, b, c);
if ((res < 0)) {
if (errno == EINTR || errno == EAGAIN) goto loop;
perror("reading UnixPipeIn");
}
return (res);
}
/************************************************************************/
/* */
/* F o r k U n i x S h e l l */
/* */
/* Fork a PTY connection to a C-shell process. */
/* Returns PID of process, or -1 if something failed */
/* */
/* */
/************************************************************************/
/* Creates a PTY connection to a csh */
#ifdef FULLSLAVENAME
int ForkUnixShell(int slot, char *PtySlave, char *termtype, char *shellarg)
#else
int ForkUnixShell(int slot, char ltr, char numb, char *termtype, char *shellarg)
#endif
{
#ifndef FULLSLAVENAME
char PtySlave[20];
#endif
int res, PID, SlaveFD;
#ifdef USETERMIOS
struct termios tio;
#else
struct sgttyb tio;
#endif /* USETERMIOS */
PID = fork();
if (PID == 0) {
char envstring[64];
char *argvec[4];
#ifndef SYSVONLY
/* Divorce ourselves from /dev/tty */
res = open("/dev/tty", O_RDWR);
if (res >= 0) {
(void)ioctl(res, TIOCNOTTY, (char *)0);
(void)close(res);
} else {
perror("Slave TTY");
exit(0);
}
#else
if (0 > setsid()) /* create us a new session for tty purposes */
perror("setsid");
#endif
/* Open the slave side */
#ifndef FULLSLAVENAME
sprintf(PtySlave, "/dev/tty%c%c", ltr, numb);
#endif
SlaveFD = open(PtySlave, O_RDWR);
if (SlaveFD == -1) {
perror("Slave Open");
perror(PtySlave);
exit(0);
}
#ifdef OS5
ioctl(SlaveFD, I_PUSH, "ptem");
ioctl(SlaveFD, I_PUSH, "ldterm");
#endif /* OS5 */
#ifndef USETERMIOS
/* This is the old way we set up terminal (OS 3), using an
obsolete ioctl and wrong flags for a display. */
ioctl(SlaveFD, TIOCGETP, (char *)&tio);
tio.sg_flags |= CRMOD;
tio.sg_flags |= ECHO;
ioctl(SlaveFD, TIOCSETP, (char *)&tio);
#else
/* Set up as basic display terminal: canonical erase,
kill processing, echo, backspace to erase, echo ctrl
chars as ^x, kill line by backspacing */
#if defined(MACOSX) || defined(FREEBSD)
tcgetattr(SlaveFD, &tio);
#else
ioctl(SlaveFD, TCGETS, (char *)&tio);
#endif
#ifdef INDIGO
tio.c_lflag |= ICANON | ECHO | ECHOE;
#else
tio.c_lflag |= ICANON | ECHO | ECHOE | ECHOCTL | ECHOKE;
#endif /* INDIGO */
#if defined(MACOSX) || defined(FREEBSD)
tcsetattr(SlaveFD, TCSANOW, &tio);
#else
ioctl(SlaveFD, TCSETS, (char *)&tio);
#endif
#endif /* USETERMIOS */
(void)dup2(SlaveFD, 0);
(void)dup2(SlaveFD, 1);
(void)dup2(SlaveFD, 2);
(void)close(SlaveFD);
/* set the LDESHELL variable so the underlying .cshrc can see it and
configure the shell appropriately, though this may not be so important any more */
putenv("LDESHELL=YES");
if ((termtype[0] != 0) && (strlen(termtype) < 59)) { /* set the TERM environment var */
sprintf(envstring, "TERM=%s", termtype);
putenv(envstring);
}
/* Start up csh */
argvec[0] = "csh";
if (shellarg[0] != 0) { /* setup to run command */
argvec[1] = "-c"; /* read commands from next arg */
argvec[2] = shellarg;
argvec[3] = (char *)0;
} else
argvec[1] = (char *)0;
execv("/bin/csh", argvec);
/* Should never get here */
perror("execv");
exit(0);
} else { /* not the forked process. */
if (shellarg != shcom) free(shellarg);
}
/* Set the process group so all the kids get the bullet too
if (setpgrp(PID, PID) != 0)
perror("setpgrp"); */
return (PID);
}
/* fork_Unix is the secondary process spawned right after LISP is
started, to avoid having TWO 8 mbyte images sitting around. It listens
to the pipe LispToUnix waiting for requests, and responds on UnixToLisp.
The data passed through this pipe is in 4 byte packets, of the form:
Byte 0: Command character, one of:
S: Fork PTY (shell) process. This is used for CHAT windows.
P: New version of S, takes 2 string args.
F: Fork piped shell, takes 1 string arg.
K: Kill process
E: Exit (kill all subprocesses)
C: Close stdin to subprocess
W: call WAIT3 & get one process's close info.
O: Fork OCR process.
Byte 1: Process number (0 to NPROCS - 1)
Not used for S, F, and E commands
[For S&P, pty letter]
[For F, process # for pipe naming]
Byte 2: Value, used as follows:
Only used for W command, contains byte to write
[For S&P, pty number]
Byte 3: Slot number.
In the case of F & P commands, additional data follows the 4 byte packet.
This consists of 2 bytes representing the length of the shell command
string, and the string itself.
fork_Unix will return another 4 byte packet. The bytes are the same as those
of the packet received except:
F: Byte 2 is job number
Byte 3 is 1 if successful, 0 if not
S: Byte 2 is job number
Byte 3 is 1 if successful, 0 if not
R: Byte 2 is value of byte read from stdin, if any
Byte 3 is 1 if successful, 2 if EOF, 0 if nothing waiting
W: Bytes 0 & 1 are the Process ID of the terminated process
Bytes 2 & 3 are the high & low bytes of the exit status.
K: Bytes 1 and 2 are the high and low bytes of the exit status
of the process.
Byte 3 is 1 if an exit status was available.
E: Always the same
C: Always the same
O: Byte 3 is 1 if successful, 0 if not
Byte 1 and Byte 2 are the process ID of OCR process
*/
int fork_Unix() {
int LispToUnix[2], /* Incoming pipe from LISP */
UnixToLisp[2], /* Outgoing pipe to LISP */
UnixPID, LispPipeIn, LispPipeOut, res, slot;
pid_t pid;
char IOBuf[4];
unsigned short tmp;
char *cmdstring;
/* Pipes between LISP subr and process */
if (pipe(LispToUnix) == -1) {
perror("pipe");
exit(-1);
}
if (pipe(UnixToLisp) == -1) {
perror("pipe");
exit(-1);
}
StartTime = time(0); /* Save the time, to create filenames with */
StartTime &= 0xFFFFFF; /* as a positive number! */
/* interrupts need to be blocked here so subprocess won't see them */
#ifdef SYSVSIGNALS
sighold(SIGVTALRM);
sighold(SIGIO);
sighold(SIGALRM);
sighold(SIGXFSZ);
sighold(SIGFPE);
#else
sigblock(sigmask(SIGVTALRM) | sigmask(SIGIO) | sigmask(SIGALRM)
#ifndef HPUX
| sigmask(SIGXFSZ)
#endif /* HPUX */
| sigmask(SIGFPE));
#endif /* SYSVSIGNALS */
if ((UnixPID = fork()) == -1) { /* Fork off small version of the emulator */
perror("fork");
exit(-1);
}
if (UnixPID != 0) {
/* JRB - fork_Unix is now called in ldeboot; leave UnixPipe{In,Out} open
and put their numbers in the environment so parent can find them */
/* JDS - NB that sprintf doesn't always return a string! */
char *tempstring;
tempstring = (char *)malloc(30);
sprintf(tempstring, "LDEPIPEIN=%d", UnixToLisp[0]);
putenv(tempstring);
tempstring = (char *)malloc(30);
sprintf(tempstring, "LDEPIPEOUT=%d", LispToUnix[1]);
putenv(tempstring);
tempstring = (char *)malloc(30);
sprintf(tempstring, "LDESTARTTIME=%ld", StartTime);
putenv(tempstring);
tempstring = (char *)malloc(30);
sprintf(tempstring, "LDEUNIXPID=%d", UnixPID);
putenv(tempstring);
close(LispToUnix[0]);
close(UnixToLisp[1]);
return (1);
}
LispPipeIn = LispToUnix[0];
LispPipeOut = UnixToLisp[1];
close(LispToUnix[1]);
close(UnixToLisp[0]);
res = fcntl(LispPipeIn, F_GETFL, 0);
res &= (65535 - FNDELAY);
res = fcntl(LispPipeIn, F_SETFL, res);
while (1) {
int len;
len = 0;
while (len != 4) {
if ((len = SAFEREAD(LispPipeIn, IOBuf, 4)) < 0) { /* Get packet */
perror("Packet read by slave");
/* kill_comm_processes(); */
exit(0);
}
if (len != 4) {
DBPRINT(("Input packet wrong length: %d.\n", len));
exit(0);
}
}
slot = IOBuf[3];
IOBuf[3] = 1; /* Start by signalling success in return-code */
switch (IOBuf[0]) {
case 'S':
case 'P': /* Fork PTY shell */
if (slot >= 0) { /* Found a free slot */
char termtype[32];
#ifdef FULLSLAVENAME
char slavepty[32]; /* For slave pty name */
if (SAFEREAD(LispPipeIn, (char *)&tmp, 2) < 0) perror("Slave reading slave pty len");
if (SAFEREAD(LispPipeIn, slavepty, tmp) < 0) perror("Slave reading slave pty id");
#endif /* INDIGO */
if (IOBuf[0] == 'P') { /* The new style, which takes term type & command to csh */
if (SAFEREAD(LispPipeIn, (char *)&tmp, 2) < 0) perror("Slave reading cmd length");
if (SAFEREAD(LispPipeIn, termtype, tmp) < 0) perror("Slave reading termtype");
if (SAFEREAD(LispPipeIn, (char *)&tmp, 2) < 0) perror("Slave reading cmd length");
if (tmp > 510)
cmdstring = (char *)malloc(tmp + 5);
else
cmdstring = shcom;
if (SAFEREAD(LispPipeIn, cmdstring, tmp) < 0) perror("Slave reading shcom");
} else /* old style, no args */
{
termtype[0] = 0;
cmdstring[0] = 0;
}
/* Alloc a PTY and fork */
#ifdef FULLSLAVENAME
pid = ForkUnixShell(slot, slavepty, termtype, cmdstring);
#else
pid = ForkUnixShell(slot, IOBuf[1], IOBuf[2], termtype, cmdstring);
#endif
if (pid == -1) {
printf("Impossible failure from ForkUnixShell??\n");
fflush(stdout);
IOBuf[3] = 0;
} else {
/* ForkUnixShell sets the pid and standard in/out variables */
IOBuf[1] = (pid >> 8) & 0xFF;
IOBuf[2] = pid & 0xFF;
}
} else {
printf("Can't get process slot for PTY shell.\n");
fflush(stdout);
IOBuf[3] = 0;
}
break;
case 'F': /* Fork pipe command */
if (slot >= 0) {
/* Read in the length of the shell command, and then the command */
if (SAFEREAD(LispPipeIn, (char *)&tmp, 2) < 0) perror("Slave reading cmd length");
if (tmp > 510)
cmdstring = (char *)malloc(tmp + 5);
else
cmdstring = shcom;
if (SAFEREAD(LispPipeIn, cmdstring, tmp) < 0) perror("Slave reading cmd");
DBPRINT(("Cmd len = %d.\n", tmp));
DBPRINT(("Rev'd cmd string: %s\n", cmdstring));
pid = fork(); /* Fork */
if (pid == 0) {
int i;
int status, sock;
#ifndef ISC
struct sockaddr_un addr;
char PipeName[40];
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
perror("slave socket");
exit(0);
}
sprintf(PipeName, "/tmp/LPU%ld-%d", StartTime, slot);
memset(&addr, 0, sizeof(struct sockaddr_un));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, PipeName);
status =
connect(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_un));
if (status < 0) {
perror("slave connect");
printf("Name = %s.\n", PipeName);
fflush(stdout);
exit(0);
} else {
DBPRINT(("Slave connected on %s.\n", PipeName));
}
/* Copy the pipes onto stdin, stdout, and stderr */
dup2(sock, 0);
dup2(sock, 1);
dup2(sock, 2);
#else
/* New, FIFO-based communication regime */
int down, up; /* fifo fds */
char DownFIFO[48], UpFIFO[48];
sprintf(DownFIFO, "/tmp/LPD%d-%d", StartTime, slot);
sprintf(UpFIFO, "/tmp/LPU%d-%d", StartTime, slot);
if ((down = open(DownFIFO, O_RDONLY | O_NDELAY)) < 0) {
perror("slave opening down fifo");
exit(0);
}
if ((up = open(UpFIFO, O_WRONLY | O_NDELAY)) < 0) {
perror("slave opening up fifo");
exit(0);
}
/* Copy the fifos onto stdin, stdout, and stderr */
dup2(down, 0);
dup2(up, 1);
dup2(up, 2);
/* unlink(DownFIFO);
unlink(UpFIFO); */
#endif /* oldPIPEway */
#ifdef SYSVONLY
/* Make sure everything else is closed POSIX has no getdtab... */
for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) close(i);
#else
/* Make sure everything else is closed */
for (i = 3; i < getdtablesize(); i++) close(i);
#endif /* HPUX */
/* Run the shell command and get the result */
status = system(cmdstring);
if (cmdstring != shcom) free(cmdstring);
/* Comment out to fix USAR 11302 (FXAR 320)
unlink(PipeName);
*/
_exit((status & ~0xff) ? (status >> 8) : status);
}
/* Check for error doing the fork */
if (pid == (pid_t)-1) {
perror("unixcomm: fork");
IOBuf[3] = 0;
} else {
IOBuf[1] = (pid >> 8) & 0xFF;
IOBuf[2] = pid & 0xFF;
}
} else {
printf("No process slots available.\n");
IOBuf[3] = 0; /* Couldn't get a process slot */
}
break;
case 'W': /* Wait for a process to die. */
{
int pid;
#if defined(SYSVONLY) || defined(WAITINT)
int status;
#else
union wait status;
#endif /* SYSVONLY */
#ifdef OCR
int slot;
#endif
#if defined(SYSVONLY) || defined(WAITINT)
status = 0;
#else
status.w_status = 0;
#endif /* SYSVONLY */
IOBuf[0] = 0;
IOBuf[1] = 0;
DBPRINT(("About to wait for processes.\n"));
#ifdef SYSVONLY
retry1:
pid = waitpid(-1, &status, WNOHANG);
if (pid == -1 && errno == EINTR) goto retry1;
#else
pid = wait3(&status, WNOHANG, 0);
#endif /* SYSVONLY */
if (pid > 0)
{
/* Ignore processes which are suspended but haven't exited
(this shouldn't happen) */
#if defined(SYSVONLY) || defined(WAITINT)
if (WIFSTOPPED(status)) break;
IOBuf[3] = status >> 8;
IOBuf[2] = status & 0xFF;
#else
if (status.w_stopval == WSTOPPED) break;
IOBuf[3] = status.w_T.w_Retcode;
IOBuf[2] = status.w_T.w_Termsig;
#endif /* SYSVONLY */
IOBuf[1] = pid & 0xFF;
IOBuf[0] = (pid >> 8) & 0xFF;
}
DBPRINT(("wait3 returned pid = %d.\n", pid));
}
break;
case 'C': /* Close stdin to subprocess */ break;
case 'K': /* Kill subprocess */ break;
#ifdef OCR
case 'w': /* Wait paticular process to die */
{
int pid, res, status;
pid = IOBuf[1] << 8 | IOBuf[2];
retry:
res = waitpid(pid, &status, WNOHANG);
if (res == -1 && errno == EINTR) goto retry;
if (res == pid) {
IOBuf[0] = res >> 24 & 0xFF;
IOBuf[1] = res >> 16 & 0xFF;
IOBuf[2] = res >> 8 & 0xFF;
IOBuf[3] = res & 0xFF;
} else {
IOBuf[0] = IOBuf[1] = IOBuf[2] = IOBuf[3] = 0;
}
} break;
case 'O': /* Fork OCR process */
if (slot >= 0) {
pid_t ppid;
ppid = getppid();
pid = fork();
if (pid == 0) {
int i;
int status, len;
struct sockaddr_un addr;
char PipeName[40];
extern int OCR_sv;
OCR_sv = socket(AF_UNIX, SOCK_STREAM, 0);
if (OCR_sv < 0) {
perror("slave socket");
exit(0);
}
sprintf(PipeName, "/tmp/LispPipe%d-%d", StartTime, slot);
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, PipeName);
len = strlen(PipeName) + sizeof(addr.sun_family);
status = connect(OCR_sv, &addr, len);
if (status < 0) {
perror("OCR slave connect");
OCR_sv = -1;
exit(0);
}
(void)ocr_proc(ppid);
OCR_sv = -1;
exit(1);
}
if (pid == -1) {
perror("unixcomm: fork OCR");
IOBuf[3] = 0;
} else {
IOBuf[1] = (pid >> 8) & 0xFF;
IOBuf[2] = pid & 0xFF;
}
} else
IOBuf[3] = 0;
break;
#endif /* OCR */
} /* End of switch */
/* Return the status/data packet */
write(LispPipeOut, IOBuf, 4);
}
}