Annotation of 43BSDTahoe/new/jove/iproc-pipes.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

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