Annotation of 43BSDReno/contrib/jove/iproc-ptys.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: /* NOTE WELL:
                      9:  * This file is "included" into iproc.c -- it is not compiled separately!
                     10:  */
                     11: 
                     12: #include <sys/time.h>
                     13: #include <fcntl.h>
                     14: #include <signal.h>
                     15: #include <sgtty.h>
                     16: #include <errno.h>
                     17: #include "wait.h"
                     18: 
                     19: #ifdef USE_OLD_TTY
                     20: # define gtty(fd, buf) ioctl(fd, TIOCGETP, buf)
                     21: # define stty(fd, buf) ioctl(fd, TIOCSETP, buf)
                     22: #endif
                     23: 
                     24: #define DEAD   1       /* dead but haven't informed user yet */
                     25: #define STOPPED        2       /* job stopped */
                     26: #define RUNNING        3       /* just running */
                     27: #define NEW    4       /* brand new, never been ... received no input */
                     28: 
                     29: /* If process is dead, flags says how. */
                     30: #define EXITED 1
                     31: #define KILLED 2
                     32: 
                     33: #define isdead(p)      ((p) == NULL || proc_state((p)) == DEAD || (p)->p_fd == -1)
                     34: #define makedead(p)    { proc_state((p)) = DEAD; }
                     35: 
                     36: #define proc_buf(p)    ((p)->p_buffer->b_name)
                     37: #define proc_cmd(p)    ((p)->p_name)
                     38: #define proc_state(p)  ((p)->p_state)
                     39: 
                     40: private Process        *procs = 0;
                     41: 
                     42: long   global_fd = 1;
                     43: int    NumProcs = 0;
                     44: 
                     45: #include "ttystate.h"
                     46: 
                     47: private Process *
                     48: proc_pid(pid)
                     49: int    pid;
                     50: {
                     51:        register Process        *p;
                     52: 
                     53:        for (p = procs; p != 0; p = p->p_next)
                     54:                if (p->p_pid == pid)
                     55:                        break;
                     56: 
                     57:        return p;
                     58: }
                     59: 
                     60: void
                     61: read_proc(fd)
                     62: register int   fd;
                     63: {
                     64:        register Process        *p;
                     65:        int     n;
                     66:        char    ibuf[1024];
                     67: 
                     68:        for (p = procs; p != 0; p = p->p_next)
                     69:                if (p->p_fd == fd)
                     70:                        break;
                     71: 
                     72:        if (p == 0) {
                     73:                writef("\riproc: unknown fd %d", fd);
                     74:                return;
                     75:        }
                     76: 
                     77:        n = read(fd, ibuf, sizeof(ibuf) - 1);
                     78:        if (n == -1 && (errno == EIO || errno == EWOULDBLOCK)) {
                     79:                if (proc_state(p) == NEW)
                     80:                        return;
                     81:                proc_close(p);
                     82:                makedead(p);
                     83:                return;
                     84:        } else {
                     85:                if (proc_state(p) != RUNNING) {
                     86:                        proc_state(p) = RUNNING;
                     87:                        UpdModLine = YES;
                     88:                }
                     89:        }
                     90:        if (n <= 0) {
                     91:                if (n == 0)
                     92:                        strcpy(ibuf, "[Process EOF]");
                     93:                else
                     94:                        swritef(ibuf, "\n[pty read error: %d]\n", errno);
                     95:        } else
                     96:                ibuf[n] = '\0';
                     97:        proc_rec(p, ibuf);
                     98: }
                     99: 
                    100: void
                    101: ProcKill()
                    102: {
                    103:        register Buffer *b;
                    104:        char    *bname;
                    105: 
                    106:        bname = ask_buf(curbuf);
                    107: 
                    108:        if ((b = buf_exists(bname)) == 0)
                    109:                complain("[No such buffer]");
                    110:        if (b->b_process == 0)
                    111:                complain("%s not tied to a process.", bname);
                    112:        proc_kill(b->b_process, SIGKILL);
                    113: }
                    114: 
                    115: void
                    116: ProcCont()
                    117: {
                    118:        Process *p;
                    119: 
                    120:        if ((p = curbuf->b_process) == 0)
                    121:                complain("[No process]");
                    122:        if (p->p_state != DEAD) {
                    123:                proc_kill(p, SIGCONT);
                    124:                UpdModLine = YES;
                    125:                p->p_state = RUNNING;
                    126:        }
                    127: }
                    128: 
                    129: private void
                    130: send_p(c)
                    131: char   c;
                    132: {
                    133:        Process *p;
                    134:        char    buf[2];
                    135: 
                    136:        if ((p = curbuf->b_process) == 0)
                    137:                complain("[No process]");
                    138:        ToLast();
                    139:        buf[0] = c;
                    140:        buf[1] = '\0';
                    141:        proc_rec(p, buf);
                    142:        (void) write(p->p_fd, &c, (size_t) 1);
                    143: }
                    144: 
                    145: void
                    146: ProcEof()
                    147: {
                    148:        send_p(tc[OFF].t_eofc);
                    149: }
                    150: 
                    151: void
                    152: ProcInt()
                    153: {
                    154:        send_p(tc[OFF].t_intrc);
                    155: }
                    156: 
                    157: void
                    158: ProcQuit()
                    159: {
                    160:        send_p(tc[OFF].t_quitc);
                    161: }
                    162: 
                    163: void
                    164: ProcStop()
                    165: {
                    166:        send_p(ls[OFF].t_suspc);
                    167: }
                    168: 
                    169: void
                    170: ProcDStop()
                    171: {
                    172:        send_p(ls[OFF].t_dsuspc);
                    173: }
                    174: 
                    175: private void
                    176: proc_close(p)
                    177: Process *p;
                    178: {
                    179:        SigHold(SIGCHLD);       /* be mutually exclusive */
                    180: 
                    181:        if (p->p_fd >= 0) {
                    182:                (void) close(p->p_fd);
                    183:                global_fd &= ~(1L << p->p_fd);
                    184:                NumProcs -= 1;
                    185:                p->p_fd = -1;
                    186:        }
                    187: 
                    188:        SigRelse(SIGCHLD);
                    189: }
                    190: 
                    191: private void
                    192: proc_write(p, buf, nbytes)
                    193: Process *p;
                    194: char   *buf;
                    195: size_t nbytes;
                    196: {
                    197:        long    mask = (1 << p->p_fd);
                    198: 
                    199:        while (write(p->p_fd, buf, nbytes) <  0)
                    200:                select(p->p_fd + 1, (long *) 0, &mask, (long *) 0, (struct timeval *) 0);
                    201: }
                    202: 
                    203: #ifdef STDARGS
                    204:        private void
                    205: proc_strt(char *bufname, int clobber, ...)
                    206: #else
                    207:        private /*VARARGS2*/ void
                    208: proc_strt(bufname, clobber, va_alist)
                    209:        char    *bufname;
                    210:        int     clobber;
                    211:        va_dcl
                    212: #endif
                    213: {
                    214:        va_list ap;
                    215:        char    *argv[32],
                    216:                *cp;
                    217:        Window *owind = curwind;
                    218:        int     pid;
                    219:        Process *newp;
                    220:        Buffer  *newbuf;
                    221:        int     i,
                    222:                ptyfd,
                    223:                ttyfd,
                    224:                ldisc,
                    225:                lmode;
                    226:        register char   *s,
                    227:                        *t;
                    228:        char    ttybuf[11],
                    229:                ptybuf[11];
                    230:        char    cmdbuf[128];
                    231: #ifdef BRLUNIX
                    232:        struct sg_brl sgt;
                    233: #else
                    234:        struct sgttyb sgt;
                    235: #endif
                    236: 
                    237: #ifdef TIOCGWINSZ
                    238:        struct winsize win;
                    239: #else
                    240: #  ifdef BTL_BLIT
                    241: #  include <sys/jioctl.h>
                    242:        struct jwinsize jwin;
                    243: #  endif
                    244: #endif
                    245: 
                    246:        isprocbuf(bufname);     /* make sure BUFNAME is either nonexistant
                    247:                                   or is of type B_PROCESS */
                    248:        for (s = "pqrs"; *s; s++) {
                    249:                for (t = "0123456789abcdef"; *t; t++) {
                    250:                        swritef(ptybuf, "/dev/pty%c%c", *s, *t);
                    251:                        if ((ptyfd = open(ptybuf, 2)) >= 0) {
                    252:                                strcpy(ttybuf, ptybuf);
                    253:                                ttybuf[5] = 't';
                    254:                                /* make sure both ends are available */
                    255:                                if ((i = open(ttybuf, 2)) < 0)
                    256:                                        continue;
                    257:                                (void) close(i);
                    258:                                goto out;
                    259:                        }
                    260:                }
                    261:        }
                    262: 
                    263: out:   if (s == 0 && t == 0)
                    264:                complain("[Out of ptys!]");
                    265: 
                    266: #ifdef TIOCGETD
                    267:        (void) ioctl(0, TIOCGETD, (UnivPtr) &ldisc);
                    268: #endif
                    269: #ifdef TIOCLGET
                    270:        (void) ioctl(0, TIOCLGET, (UnivPtr) &lmode);
                    271: #endif
                    272: #ifdef TIOCGWINSZ
                    273:        (void) ioctl(0, TIOCGWINSZ, (UnivPtr) &win);
                    274: #else
                    275: #  ifdef BTL_BLIT
                    276:        (void) ioctl(0, JWINSIZE, (UnivPtr) &jwin);
                    277: #  endif /* BTL_BLIT */
                    278: #endif
                    279: 
                    280:        SigHold(SIGCHLD);
                    281: #ifdef SIGWINCH
                    282:        SigHold(SIGWINCH);
                    283: #endif
                    284:        switch (pid = fork()) {
                    285:        case -1:
                    286:                (void) close(ptyfd);
                    287:                message("[Fork failed!]");
                    288:                goto fail;
                    289: 
                    290:        case 0:
                    291:                SigRelse(SIGCHLD);
                    292: #ifdef SIGWINCH
                    293:                SigRelse(SIGWINCH);
                    294: #endif
                    295:                for (i = 0; i < 32; i++)
                    296:                        (void) close(i);
                    297: 
                    298: #ifdef TIOCNOTTY
                    299:                if ((i = open("/dev/tty", 2)) >= 0) {
                    300:                        (void) ioctl(i, TIOCNOTTY, (UnivPtr) 0);
                    301:                        (void) close(i);
                    302:                }
                    303: #endif
                    304:                if ((ttyfd = open(ttybuf, 2)) < 0)
                    305:                        exit(-1);
                    306:                (void) dup2(ttyfd, 1);
                    307:                (void) dup2(ttyfd, 2);
                    308: 
                    309: #ifdef TIOCSETD
                    310:                (void) ioctl(0, TIOCSETD, (UnivPtr) &ldisc);
                    311: #endif
                    312: #ifdef TIOCLSET
                    313:                (void) ioctl(0, TIOCLSET, (UnivPtr) &lmode);
                    314: #endif
                    315: #ifdef TIOCSETC
                    316:                (void) ioctl(0, TIOCSETC, (UnivPtr) &tc[OFF]);
                    317: #endif
                    318: #ifdef TIOCSLTC
                    319:                (void) ioctl(0, TIOCSLTC, (UnivPtr) &ls[OFF]);
                    320: #endif
                    321: 
                    322: #ifdef TIOCGWINSZ
                    323: #    ifdef SIGWINCH
                    324:                (void) signal(SIGWINCH, SIG_IGN);
                    325: #    endif
                    326:                win.ws_row = curwind->w_height;
                    327:                (void) ioctl(0, TIOCSWINSZ, (UnivPtr) &win);
                    328: #else
                    329: #  ifdef BTL_BLIT
                    330:                jwin.bytesy = curwind->w_height;
                    331:                (void) ioctl(0, JSWINSIZE, (UnivPtr) &jwin);
                    332: #  endif
                    333: #endif
                    334: 
                    335:                sgt = sg[OFF];
                    336:                sgt.sg_flags &= ~(ECHO | CRMOD | ANYP | ALLDELAY | RAW | LCASE | CBREAK | TANDEM);
                    337:                (void) stty(0, &sgt);
                    338: 
                    339:                {
                    340:                        int     on = 1;
                    341: 
                    342:                        (void) ioctl(0, TIOCREMOTE, (UnivPtr) &on);
                    343:                }
                    344: 
                    345:                i = getpid();
                    346:                (void) ioctl(0, TIOCSPGRP, (UnivPtr) &i);
                    347:                (void) setpgrp(0, i);
                    348:                va_init(ap, clobber);
                    349:                make_argv(argv, ap);
                    350:                va_end(ap);
                    351:                execv(argv[0], (const char **) &argv[1]);
                    352:                (void) write(1, "execve failed!\n", (size_t) 15);
                    353:                _exit(errno + 1);
                    354:        }
                    355: 
                    356:        newp = (Process *) emalloc(sizeof *newp);
                    357: 
                    358: #ifdef O_NDELAY
                    359:        fcntl (ptyfd, F_SETFL, O_NDELAY);
                    360: #endif
                    361:        newp->p_fd = ptyfd;
                    362:        newp->p_pid = pid;
                    363: 
                    364:        newbuf = do_select((Window *) 0, bufname);
                    365:        newbuf->b_type = B_PROCESS;
                    366:        newp->p_buffer = newbuf;
                    367:        newbuf->b_process = newp;       /* sorta circular, eh? */
                    368:        pop_wind(bufname, clobber, B_PROCESS);
                    369:        /* Pop_wind() after everything is set up; important!
                    370:           Bindings won't work right unless newbuf->b_process is already
                    371:           set up BEFORE NEWBUF is first SetBuf()'d. */
                    372:        ToLast();
                    373:        if (!bolp())
                    374:                LineInsert(1);
                    375: 
                    376:        cmdbuf[0] = '\0';
                    377:        va_init(ap, clobber);
                    378:        while ((cp = va_arg(ap, char *)) != NIL)
                    379:                swritef(&cmdbuf[strlen(cmdbuf)], "%s ", cp++);
                    380:        va_end(ap);
                    381: 
                    382:        newp->p_name = copystr(cmdbuf);
                    383:        newp->p_state = NEW;
                    384:        newp->p_reason = 0;
                    385:        newp->p_mark = MakeMark(curline, curchar, M_FLOATER);
                    386:        newp->p_dbx_mode = NO;
                    387: 
                    388:        newp->p_next = procs;
                    389:        procs = newp;
                    390:        NumProcs += 1;
                    391:        global_fd |= 1L << newp->p_fd;
                    392:        SetWind(owind);
                    393: 
                    394: fail:  SigRelse(SIGCHLD);
                    395: #ifdef SIGWINCH
                    396:        SigRelse(SIGWINCH);
                    397: #endif
                    398: }
                    399: 
                    400: void
                    401: pinit()
                    402: {
                    403:        (void) signal(SIGCHLD, proc_child);
                    404: }

unix.superglobalmegacorp.com

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