Annotation of 43BSDReno/contrib/jove/iproc-ptys.c, revision 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.