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

unix.superglobalmegacorp.com

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