/************************************************************************ * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * * provided to you without charge, and with no warranty. You may give * * away copies of JOVE, including sources, provided that this notice is * * included in all the files. * ************************************************************************/ /* This is a server for JOVE interactive subprocesses. It runs the command and wraps the command's output in packets so that JOVE can identify its source. By the time we get here, our standard output goes to JOVE's process input. */ #define NOT_JOVE #include "tune.h" #ifdef PIPEPROCS RCS("$Id: portsrv.c,v 14.31 1993/02/15 02:01:49 tom Exp tom $") #include "jove.h" #include "io.h" #include "process.h" struct { struct header header; char buf[BLKSIZ]; } packet; #ifdef PORTSRV_SHOULD_BUFFER int proc_read __(( int _(fd), char *_(buf), size_t _(size) )); int proc_read(fd, buf, size) register char *buf; size_t size; { register int n = size, nread = 0; /* line-buffer unbuffered output. */ while ((n = read(fd, buf, n)) == 1 && *buf++ != '\n' && --size > 0) nread += n; if (n >= 0) n += nread; return n; } #else # define proc_read read #endif void proc_write __(( int _(nbytes) )); void proc_write(nbytes) { write(1, &packet, sizeof packet.header + nbytes); } void serv_error __(( char *_(msg) )); void serv_error(msg) register char *msg; { register char *d = packet.buf; int status = -errno; while (*d++ = *msg++) ; --d; proc_write(packet.header.nbytes = d - packet.buf); packet.header.nbytes = EOF; *(int *) packet.buf = status << 8; proc_write(sizeof(WAIT_T)); /* cheat... */ _exit(status); } #endif /* PIPEPROCS */ /* ARGSUSED */ void main(argc, argv) char *argv[]; { #ifdef PIPEPROCS int p[2]; register int pid, wpid; packet.header.pid = getpid(); if (pipe(p) < 0) serv_error("[portsrv: Pipe failed.]\n"); if ((pid = fork()) < 0) serv_error("[portsrv: Fork failed.]\n"); if (pid == 0) { /* We'll intercept childs output in pipe p */ dup2(p[WRITE], 1); dup2(p[WRITE], 2); close(p[READ]); close(p[WRITE]); setpgrp(getpid(), getpid()); execv(argv[1], &argv[2]); _exit(-ENOEXEC); } signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); close(0); /* Don't want this guy to read anything jove sends to our soon to be created child */ close(p[WRITE]); /* Tell jove the pid of the real child as opposed to us. */ packet.header.nbytes = 0; /* special marker. */ *(int *) packet.buf = pid; proc_write(sizeof pid); /* Read proc's output and send it to jove */ while ((packet.header.nbytes = proc_read(p[READ], packet.buf, sizeof packet.buf)) > 0) proc_write(packet.header.nbytes); close(p[READ]); /* Tell jove we are finished; send exit code of child in EOF packet. */ packet.header.nbytes = EOF; while ((wpid = wait((int *) packet.buf)) != pid) { if (wpid < 0) break; } proc_write(sizeof(WAIT_T)); #endif /* PIPEPROCS */ _exit(EXIT_SUCCESS); } /*====================================================================== * $Log: portsrv.c,v $ * Revision 14.31 1993/02/15 02:01:49 tom * remove (void) casts. * * Revision 14.30 1993/01/26 18:43:17 tom * cleanup whitespace. * * Revision 14.26 1992/08/26 23:57:05 tom * add RCS directives. * */