# 2.11BSD#431 - /usr/src/new/jove/iproc-pipes.c

##### Functions

    ProcInt           X
    ProcKill          X
    ProcQuit          X
    do_rtp            X
    doread            X
    pinit             X
    proc_close        X
    proc_strt         X
    procs_read        X
    pstate            X
    read_proc         X

##### Variables

    NumProcs          X
    ProcInput         X
    ProcOutput        X

##### Macros

    DEAD              X
    EXITED            X
    KILLED            X
    NEW               X
    RUNNING           X
    STOPPED           X
    isdead            X
    makedead          X
    proc_buf          X
    proc_cmd          X
    proc_state        X

##### struct's

    header            X

       1: /***************************************************************************
       2:  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
       3:  * is provided to you without charge, and with no warranty.  You may give  *
       4:  * away copies of JOVE, including sources, provided that this notice is    *
       5:  * included in all the files.                                              *
       6:  ***************************************************************************/
       7:
       8: #ifdef BSD4_2
       9: #   include <sys/wait.h>
      10: #else
      11: #   include <wait.h>
      12: #endif
      13: #include <signal.h>
      14: #include <sgtty.h>
      15:
      16: #define DEAD    1   /* Dead but haven't informed user yet */
      17: #define STOPPED 2   /* Job stopped */
      18: #define RUNNING 3   /* Just running */
      19: #define NEW 4   /* This process is brand new */
      20:
      21: /* If process is dead, flags says how. */
      22: #define EXITED  1
      23: #define KILLED  2
      24:
      25: #define isdead(p)   (p == 0 || proc_state(p) == DEAD || p->p_toproc == -1)
      26: #define makedead(p) (proc_state(p) = DEAD)
      27:
      28: #define proc_buf(p) (p->p_buffer->b_name)
      29: #define proc_cmd(p) (p->p_name)
      30: #define proc_state(p)   (p->p_state)
      31:
      32: private Process *procs = 0;
      33:
      34: int ProcInput,
      35:     ProcOutput,
      36:     NumProcs = 0;
      37:
      38: char *
      39: pstate(p)
      40: Process *p;
      41: {
      42:     switch (proc_state(p)) {
      43:     case NEW:
      44:         return "Pre-birth";
      45:
      46:     case STOPPED:
      47:         return "Stopped";
      48:
      49:     case RUNNING:
      50:         return "Running";
      51:
      52:     case DEAD:
      53:         if (p->p_howdied == EXITED) {
      54:             if (p->p_reason == 0)
      55:                 return "Done";
      56:             return sprint("Exit %d", p->p_reason);
      57:         }
      58:         return sprint("Killed %d", p->p_reason);
      59:
      60:     default:
      61:         return "Unknown state";
      62:     }
      63: }
      64:
      65: static Process *
      66: proc_pid(pid)
      67: {
      68:     register Process    *p;
      69:
      70:     for (p = procs; p != 0; p = p->p_next)
      71:         if (p->p_portpid == pid)
      72:             break;
      73:
      74:     return p;
      75: }
      76:
      77: procs_read()
      78: {
      79:     struct header {
      80:         int pid;
      81:         int nbytes;
      82:     } header;
      83:     int n;
      84:     long    nbytes;
      85:     static int  here = NO;
      86:
      87:     if (here)
      88:         return;
      89:     sighold(SIGCHLD);   /* block any other children */
      90:     here = YES;
      91:     for (;;) {
      92:         (void) ioctl(ProcInput, FIONREAD, (struct sgttyb *) &nbytes);
      93:         if (nbytes < sizeof header)
      94:             break;
      95:         n = read(ProcInput, (char *) &header, sizeof header);
      96:         if (n != sizeof header)
      97:             finish(1);
      98:         read_proc(header.pid, header.nbytes);
      99:     }
     100:     here = NO;
     101:     sigrelse(SIGCHLD);
     102: }
     103:
     104: read_proc(pid, nbytes)
     105: int pid;
     106: register int    nbytes;
     107: {
     108:     register Process    *p;
     109:     int n;
     110:     char    ibuf[512];
     111:
     112:     if ((p = proc_pid(pid)) == 0) {
     113:         printf("\riproc: unknown pid (%d)", pid);
     114:         return;
     115:     }
     116:     if (proc_state(p) == NEW) {
     117:         int rpid;
     118:         /* pid of real child, not of portsrv */
     119:
     120:         doread(ProcInput, (char *) &rpid, nbytes);
     121:         nbytes -= sizeof rpid;
     122:         p->p_pid = rpid;
     123:         p->p_state = RUNNING;
     124:     }
     125:
     126:     if (nbytes == EOF) {        /* okay to clean up this process */
     127:         proc_close(p);
     128:         makedead(p);
     129:         return;
     130:     }
     131:
     132:     while (nbytes > 0) {
     133:         n = min((sizeof ibuf) - 1, nbytes);
     134:         doread(ProcInput, ibuf, n);
     135:         ibuf[n] = 0;    /* Null terminate for convenience */
     136:         nbytes -= n;
     137:         proc_rec(p, ibuf);
     138:     }
     139: }
     140:
     141: ProcKill()
     142: {
     143:     proc_kill(curbuf->b_process, SIGKILL);
     144: }
     145:
     146: ProcInt()
     147: {
     148:     proc_kill(curbuf->b_process, SIGINT);
     149: }
     150:
     151: ProcQuit()
     152: {
     153:     proc_kill(curbuf->b_process, SIGQUIT);
     154: }
     155:
     156: private
     157: proc_close(p)
     158: Process *p;
     159: {
     160:     sighold(SIGCHLD);
     161:
     162:     if (p->p_toproc >= 0) {
     163:         (void) close(p->p_toproc);
     164:         p->p_toproc = -1;   /* writes will fail */
     165:         NumProcs -= 1;
     166:     }
     167:
     168:     sigrelse(SIGCHLD);
     169: }
     170:
     171: do_rtp(mp)
     172: register Mark   *mp;
     173: {
     174:     register Process    *p = curbuf->b_process;
     175:     Line    *line1 = curline,
     176:         *line2 = mp->m_line;
     177:     int char1 = curchar,
     178:         char2 = mp->m_char;
     179:     char    *gp;
     180:
     181:     if (isdead(p) || p->p_buffer != curbuf)
     182:         return;
     183:
     184:     (void) fixorder(&line1, &char1, &line2, &char2);
     185:     while (line1 != line2->l_next) {
     186:         gp = ltobuf(line1, genbuf) + char1;
     187:         if (line1 == line2)
     188:             gp[char2] = '\0';
     189:         else
     190:             strcat(gp, "\n");
     191:         (void) write(p->p_toproc, gp, strlen(gp));
     192:         line1 = line1->l_next;
     193:         char1 = 0;
     194:     }
     195: }
     196:
     197: /* VARARGS3 */
     198:
     199: private
     200: proc_strt(bufname, clobber, va_alist)
     201: char    *bufname;
     202: va_dcl
     203: {
     204:     Window  *owind = curwind;
     205:     int toproc[2],
     206:         pid;
     207:     Process *newp;
     208:     Buffer  *newbuf;
     209:         char    *argv[32],
     210:             *cp,
     211:             foo[10],
     212:         cmdbuf[128];
     213:         int i;
     214:     va_list ap;
     215:
     216:     isprocbuf(bufname); /* make sure BUFNAME is either nonexistant
     217: 				   or is of type B_PROCESS */
     218:     dopipe(toproc);
     219:
     220:     sighold(SIGCHLD);
     221: #ifdef SIGWINCH
     222:     sighold(SIGWINCH);
     223: #endif
     224:     switch (pid = fork()) {
     225:     case -1:
     226:         pclose(toproc);
     227:         complain("[Fork failed.]");
     228:
     229:     case 0:
     230:         sigrelse(SIGCHLD);
     231: #ifdef SIGWINCH
     232:         sigrelse(SIGWINCH);
     233: #endif
     234:             argv[0] = "portsrv";
     235:             argv[1] = foo;
     236:         sprintf(foo, "%d", ProcInput);
     237:         va_start(ap);
     238:         make_argv(&argv[2], ap);
     239:         va_end(ap);
     240:         (void) dup2(toproc[0], 0);
     241:         (void) dup2(ProcOutput, 1);
     242:         (void) dup2(ProcOutput, 2);
     243:         pclose(toproc);
     244:         execv(Portsrv, argv);
     245:         printf("execl failed\n");
     246:         _exit(1);
     247:     }
     248:
     249:     newp = (Process *) malloc(sizeof *newp);
     250:     newp->p_next = procs;
     251:     newp->p_state = NEW;
     252:     newp->p_cmd = 0;
     253:
     254:     cmdbuf[0] = '\0';
     255:     va_start(ap);
     256:     while (cp = va_arg(ap, char *))
     257:         sprintf(&cmdbuf[strlen(cmdbuf)], "%s ", cp);
     258:     va_end(ap);
     259:     newp->p_name = copystr(cmdbuf);
     260:     procs = newp;
     261:     newp->p_portpid = pid;
     262:     newp->p_pid = -1;
     263:
     264:     newbuf = do_select((Window *) 0, bufname);
     265:     newbuf->b_type = B_PROCESS;
     266:     newp->p_buffer = newbuf;
     267:     newbuf->b_process = newp;   /* sorta circular, eh? */
     268:     pop_wind(bufname, clobber, B_PROCESS);
     269:     ToLast();
     270:     if (!bolp())
     271:         LineInsert(1);
     272:     /* Pop_wind() after everything is set up; important!
     273: 	   Bindings won't work right unless newbuf->b_process is already
     274: 	   set up BEFORE NEWBUF is first SetBuf()'d. */
     275:     newp->p_mark = MakeMark(curline, curchar, M_FLOATER);
     276:
     277:     newp->p_toproc = toproc[1];
     278:     newp->p_reason = 0;
     279:     NumProcs += 1;
     280:     (void) close(toproc[0]);
     281:     SetWind(owind);
     282:     sigrelse(SIGCHLD);
     283: #ifdef SIGWINCH
     284:     sigrelse(SIGWINCH);
     285: #endif
     286: }
     287:
     288: pinit()
     289: {
     290:     int p[2];
     291:
     292:     (void) signal(SIGCHLD, proc_child);
     293:     (void) pipe(p);
     294:     ProcInput = p[0];
     295:     ProcOutput = p[1];
     296:     (void) signal(INPUT_SIG, procs_read);
     297:     sighold(INPUT_SIG); /* Released during terminal read */
     298: }
     299:
     300: doread(fd, buf, n)
     301: char    *buf;
     302: {
     303:     int nread;
     304:
     305:     if ((nread = read(fd, buf, n)) != n)
     306:         complain("Cannot read %d (got %d) bytes.", n, nread);
     307: }

#### Defined functions

ProcInt defined in line 146; never used
ProcKill defined in line 141; never used
ProcQuit defined in line 151; never used
do_rtp defined in line 171; never used
doread defined in line 300; used 2 times

- in line 120, 134

pinit defined in line 288; never used
proc_close defined in line 156; used 1 times

- in line 127

proc_pid defined in line 65; used 1 times

- in line 112

proc_strt defined in line 199; never used
procs_read defined in line 77; used 1 times

- in line 296

pstate defined in line 38; never used
read_proc defined in line 104; used 1 times

- in line 98

#### Defined variables

NumProcs defined in line 36; used 2 times

- in line 165, 279

ProcInput defined in line 34; used 6 times

- in line 92-95(2), 120, 134, 236, 294

ProcOutput defined in line 35; used 3 times

- in line 241-242(2), 295

#### Defined struct's

header defined in line 79; never used

#### Defined macros

DEAD defined in line 16; used 2 times

- in line 25-26(2)

EXITED defined in line 22; used 1 times

- in line 53

KILLED defined in line 23; never used
NEW defined in line 19; used 2 times

- in line 116, 251

RUNNING defined in line 18; used 1 times

- in line 123

STOPPED defined in line 17; never used
isdead defined in line 25; used 1 times

- in line 181

makedead defined in line 26; used 1 times

- in line 128

proc_buf defined in line 28; never used
proc_cmd defined in line 29; never used
proc_state defined in line 30; used 4 times

- in line 25-26(2), 42, 116

#### Usage of this include

iproc-pipes.c used 1 times

- in /usr/src/new/jove/iproc.c line 17

Last modified: 1988-03-15 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: ?E00 |