Annotation of 43BSD/contrib/jove/iproc-pipes.c, revision 1.1.1.1

1.1       root        1: /*************************************************************************
                      2:  * This program is copyright (C) 1985, 1986 by Jonathan Payne.  It is    *
                      3:  * provided to you without charge for use only on a licensed Unix        *
                      4:  * system.  You may copy JOVE provided that this notice is included with *
                      5:  * the copy.  You may not sell copies of this program or versions        *
                      6:  * modified for use on microcomputer systems, unless the copies are      *
                      7:  * included with a Unix system distribution and the source is provided.  *
                      8:  *************************************************************************/
                      9: 
                     10: #ifdef BSD4_2
                     11: #   include <sys/wait.h>
                     12: #else
                     13: #   include <wait.h>
                     14: #endif
                     15: #include <signal.h>
                     16: #include <sgtty.h>
                     17: 
                     18: typedef struct process Process;
                     19: 
                     20: #define DEAD   1       /* Dead but haven't informed user yet */
                     21: #define STOPPED        2       /* Job stopped */
                     22: #define RUNNING        3       /* Just running */
                     23: #define NEW    4       /* This process is brand new */
                     24: 
                     25: /* If process is dead, flags says how. */
                     26: #define EXITED 1
                     27: #define KILLED 2
                     28: 
                     29: #define isdead(p)      (p == 0 || proc_state(p) == DEAD || p->p_toproc == -1)
                     30: 
                     31: #define proc_buf(p)    (p->p_buffer->b_name)
                     32: #define proc_cmd(p)    (p->p_name)
                     33: #define proc_state(p)  (p->p_state)
                     34: 
                     35: struct process {
                     36:        Process *p_next;
                     37:        int     p_toproc,       /* read p_fromproc and write p_toproc */
                     38:                p_portpid,      /* Pid of child (the portsrv) */
                     39:                p_pid;          /* Pid of real child i.e. not portsrv */
                     40:        Buffer  *p_buffer;      /* Add output to end of this buffer */
                     41:        char    *p_name;        /* ... */
                     42:        char    p_state,        /* State */
                     43:                p_howdied,      /* Killed? or Exited? */
                     44:                p_reason,       /* If signaled, p_reason is the signal; else
                     45:                                   it is the the exit code */
                     46:                p_eof;          /* Received EOF, so can be free'd up */
                     47:        Mark    *p_mark;        /* Where output left us. */
                     48:        data_obj
                     49:                *p_cmd;         /* Command to call when process dies */
                     50: } *procs = 0,
                     51:   *cur_proc = 0;
                     52: 
                     53: char   proc_prompt[80] = "% ";
                     54: 
                     55: int    ProcInput,
                     56:        ProcOutput,
                     57:        NumProcs = 0;
                     58: 
                     59: static char *
                     60: pstate(p)
                     61: Process        *p;
                     62: {
                     63:        switch (proc_state(p)) {
                     64:        case NEW:
                     65:                return "Pre-birth";
                     66: 
                     67:        case STOPPED:
                     68:                return "Stopped";
                     69: 
                     70:        case RUNNING:
                     71:                return "Running";
                     72: 
                     73:        case DEAD:
                     74:                if (p->p_howdied == EXITED) {
                     75:                        if (p->p_reason == 0)
                     76:                                return "Done";
                     77:                        return sprint("[Exit %d]", p->p_reason);
                     78:                }
                     79:                return sprint("[Killed %d]", p->p_reason);
                     80: 
                     81:        default:
                     82:                return "Unknown state.";
                     83:        }
                     84: }
                     85: 
                     86: static Process *
                     87: proc_pid(pid)
                     88: {
                     89:        register Process        *p;
                     90: 
                     91:        for (p = procs; p != 0; p = p->p_next)
                     92:                if (p->p_portpid == pid)
                     93:                        break;
                     94: 
                     95:        return p;
                     96: }
                     97: 
                     98: procs_read()
                     99: {
                    100:        struct header {
                    101:                int     pid;
                    102:                int     nbytes;
                    103:        } header;
                    104:        int     n;
                    105:        long    nbytes;
                    106:        static int      here = 0;
                    107: 
                    108:        if (here)       
                    109:                return;
                    110:        sighold(SIGCHLD);       /* Block any other children. */
                    111:        here++;
                    112:        for (;;) {
                    113:                (void) ioctl(ProcInput, FIONREAD, (struct sgttyb *) &nbytes);
                    114:                if (nbytes < sizeof header)
                    115:                        break;
                    116:                n = read(ProcInput, (char *) &header, sizeof header);
                    117:                if (n != sizeof header)
                    118:                        finish(1);
                    119:                read_proc(header.pid, header.nbytes);
                    120:        }
                    121:        redisplay();
                    122:        here = 0;
                    123:        sigrelse(SIGCHLD);
                    124: }
                    125: 
                    126: read_proc(pid, nbytes)
                    127: int    pid;
                    128: register int   nbytes;
                    129: {
                    130:        register Process        *p;
                    131:        int     n;
                    132:        char    ibuf[512];
                    133: 
                    134:        if ((p = proc_pid(pid)) == 0) {
                    135:                printf("\riproc: unknown pid (%d)", pid);
                    136:                return;
                    137:        }
                    138:        if (proc_state(p) == NEW) {
                    139:                int     rpid;
                    140:                /* Pid of real child, not of portsrv. */
                    141: 
                    142:                doread(ProcInput, (char *) &rpid, nbytes);
                    143:                nbytes -= sizeof rpid;
                    144:                p->p_pid = rpid;
                    145:                p->p_state = RUNNING;
                    146:        }
                    147: 
                    148:        if (nbytes == EOF) {            /* Okay to clean up this process */
                    149:                p->p_eof = 1;
                    150:                NumProcs--;     /* As far as getch() in main is concerned */
                    151:                return;
                    152:        }
                    153: 
                    154:        while (nbytes > 0) {
                    155:                n = min((sizeof ibuf) - 1, nbytes);
                    156:                doread(ProcInput, ibuf, n);
                    157:                ibuf[n] = 0;    /* Null terminate for convenience */
                    158:                nbytes -= n;
                    159:                proc_rec(p, ibuf);
                    160:        }
                    161: }
                    162: 
                    163: ProcKill()
                    164: {
                    165:        proc_kill(cur_proc, SIGKILL);
                    166: }
                    167: 
                    168: ProcInt()
                    169: {
                    170:        proc_kill(cur_proc, SIGINT);
                    171: }
                    172: 
                    173: ProcQuit()
                    174: {
                    175:        proc_kill(cur_proc, SIGQUIT);
                    176: }
                    177: 
                    178: static
                    179: proc_close(p)
                    180: Process        *p;
                    181: {
                    182:        (void) close(p->p_toproc);
                    183:        p->p_toproc = -1;       /* Writes will fail. */
                    184: }
                    185: 
                    186: do_rtp(mp)
                    187: register Mark  *mp;
                    188: {
                    189:        register Process        *p = cur_proc;
                    190:        Line    *line1 = curline,
                    191:                *line2 = mp->m_line;
                    192:        int     char1 = curchar,
                    193:                char2 = mp->m_char;
                    194:        char    *gp;
                    195: 
                    196:        if (isdead(p) || p->p_buffer != curbuf)
                    197:                return;
                    198: 
                    199:        (void) fixorder(&line1, &char1, &line2, &char2);
                    200:        while (line1 != line2->l_next) {
                    201:                gp = ltobuf(line1, genbuf) + char1;
                    202:                if (line1 == line2)
                    203:                        gp[char2] = '\0';
                    204:                else
                    205:                        strcat(gp, "\n");
                    206:                (void) write(p->p_toproc, gp, strlen(gp));
                    207:                line1 = line1->l_next;
                    208:                char1 = 0;
                    209:        }
                    210: }
                    211: 
                    212: /* VARARGS2 */
                    213: 
                    214: static
                    215: proc_strt(bufname, procname, cmd)
                    216: char   *bufname,
                    217:        *procname,
                    218:        *cmd;
                    219: {
                    220:        Window  *owind = curwind;
                    221:        int     toproc[2],
                    222:                pid;
                    223:        Process *newp;
                    224:        Buffer  *bp;
                    225:        char    *args[25],
                    226:                **cp,
                    227:                foo[10],
                    228:                cmdbuf[128];
                    229:        int     i;
                    230: 
                    231:        bp = buf_exists(bufname);
                    232:        if (bp != 0 && IsModified(bp) && bp->b_type != B_IPROCESS && bp->b_type != B_PROCESS)
                    233:                complain("Command would over-write buffer %s.", procname, bufname);
                    234:        pop_wind(bufname, 1, B_IPROCESS);
                    235: 
                    236:        dopipe(toproc);
                    237: 
                    238:        switch (pid = fork()) {
                    239:        case -1:
                    240:                pclose(toproc);
                    241:                complain("[Fork failed.]");
                    242: 
                    243:        case 0:
                    244:                args[0] = "portsrv";
                    245:                args[1] = foo;
                    246:                sprintf(foo, "%d", ProcInput);
                    247:                for (i = 0, cp = &cmd; cp[i] != 0; i++)
                    248:                        args[2 + i] = cp[i];
                    249:                args[2 + i] = 0;
                    250:                (void) dup2(toproc[0], 0);
                    251:                (void) dup2(ProcOutput, 1);
                    252:                (void) dup2(ProcOutput, 2);
                    253:                pclose(toproc);
                    254:                execv(PORTSRV, args);
                    255:                printf("Execl failed.\n");
                    256:                _exit(1);
                    257:        }
                    258: 
                    259:        sighold(SIGCHLD);
                    260:        cur_proc = newp = (Process *) malloc(sizeof *newp);
                    261:        newp->p_next = procs;
                    262:        newp->p_state = NEW;
                    263:        newp->p_mark = MakeMark(curline, curchar, FLOATER);
                    264:        newp->p_cmd = 0;
                    265: 
                    266:        cp = &cmd + 1;
                    267:        cmdbuf[0] = '\0';
                    268:        while (*cp != 0)
                    269:                sprintf(&cmdbuf[strlen(cmdbuf)], "%s ", *cp++);
                    270:        newp->p_name = copystr(cmdbuf);
                    271:        procs = newp;
                    272:        newp->p_portpid = pid;
                    273:        newp->p_pid = -1;
                    274:        newp->p_buffer = curbuf;
                    275:        newp->p_toproc = toproc[1];
                    276:        newp->p_reason = 0;
                    277:        newp->p_eof = 0;
                    278:        NumProcs++;
                    279:        (void) close(toproc[0]);
                    280:        sigrelse(SIGCHLD);
                    281:        SetWind(owind);
                    282: }
                    283: 
                    284: pinit()
                    285: {
                    286:        int     p[2];
                    287: 
                    288:        (void) signal(SIGCHLD, proc_child);
                    289:        (void) pipe(p);
                    290:        ProcInput = p[0];
                    291:        ProcOutput = p[1];
                    292:        (void) signal(INPUT_SIG, procs_read);
                    293:        sighold(INPUT_SIG);     /* Released during terminal read */
                    294: }
                    295: 
                    296: doread(fd, buf, n)
                    297: char   *buf;
                    298: {
                    299:        int     nread;
                    300: 
                    301:        if ((nread = read(fd, buf, n)) != n)
                    302:                complain("Cannot read %d (got %d) bytes.", n, nread);
                    303: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.