Annotation of 43BSD/contrib/jove/iproc-ptys.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_fd == -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_fd,           /* File descriptor of ptyp? opened r/w */
                     38:                p_pid;          /* pid of child (the shell) */
                     39:        Buffer  *p_buffer;      /* Add output to end of this buffer */
                     40:        char    *p_name;        /* ... */
                     41:        char    p_state,        /* State */
                     42:                p_howdied,      /* Killed? or Exited? */
                     43:                p_reason,       /* If signaled, p_reason is the signal; else
                     44:                                   it is the the exit code */
                     45:                p_eof;          /* Received EOF, so can be free'd up */
                     46:        Mark    *p_mark;        /* Where output left us. */
                     47:        data_obj
                     48:                *p_cmd;         /* Command to call when process dies */
                     49: } *procs = 0,
                     50:   *cur_proc = 0;
                     51: 
                     52: char   proc_prompt[80] = "% ";
                     53: 
                     54: int    global_fd = 1,
                     55:        NumProcs = 0;
                     56: 
                     57: #ifdef BRLUNIX
                     58:        extern struct sg_brl sg1;
                     59: #else
                     60:        extern struct sgttyb sg1;
                     61: #endif
                     62: 
                     63: extern struct tchars tc1;
                     64: 
                     65: #ifdef TIOCSLTC
                     66:        extern struct ltchars ls1;
                     67: #endif
                     68: 
                     69: static char *
                     70: pstate(p)
                     71: Process        *p;
                     72: {
                     73:        switch (proc_state(p)) {
                     74:        case STOPPED:
                     75:                return "Stopped";
                     76: 
                     77:        case RUNNING:
                     78:                return "Running";
                     79: 
                     80:        case DEAD:
                     81:                if (p->p_howdied == EXITED) {
                     82:                        if (p->p_reason == 0)
                     83:                                return "Done";
                     84:                        return sprint("exit(%d)", p->p_reason);
                     85:                }
                     86:                return sprint("Killed(%d)", p->p_reason);
                     87: 
                     88:        default:
                     89:                return "Unknown state.";
                     90:        }
                     91: }
                     92: 
                     93: static Process *
                     94: proc_pid(pid)
                     95: {
                     96:        register Process        *p;
                     97: 
                     98:        for (p = procs; p != 0; p = p->p_next)
                     99:                if (p->p_pid == pid)
                    100:                        break;
                    101: 
                    102:        return p;
                    103: }
                    104: 
                    105: read_proc(fd)
                    106: register int   fd;
                    107: {
                    108:        register Process        *p;
                    109:        unsigned int    n;
                    110:        char    ibuf[1024];
                    111: 
                    112:        for (p = procs; p != 0; p = p->p_next)
                    113:                if (p->p_fd == fd)
                    114:                        break;
                    115: 
                    116:        if (p == 0) {
                    117:                printf("\riproc: unknown fd %d", fd);
                    118:                return;
                    119:        }
                    120: 
                    121:        n = read(fd, ibuf, sizeof(ibuf) - 1);
                    122: 
                    123:        if (n == 0) {
                    124:                proc_close(p);
                    125:                NumProcs--;
                    126:                return;
                    127:        }
                    128: 
                    129:        ibuf[n] = '\0';
                    130:        proc_rec(p, ibuf);
                    131:        redisplay();
                    132: }
                    133: 
                    134: ProcKill()
                    135: {
                    136:        register Buffer *b;
                    137:        register Process        *p;
                    138:        Process *buf_to_proc();
                    139:        char    *bname;
                    140: 
                    141:        bname = ask_buf(cur_proc ? cur_proc->p_buffer : (Buffer *) 0);
                    142: 
                    143:        if ((b = buf_exists(bname)) == 0)
                    144:                complain("[No such buffer]");
                    145:        if ((p = buf_to_proc(b)) == 0)
                    146:                complain("%s not tied to a process.", bname);
                    147:        proc_kill(p, SIGKILL);
                    148: }
                    149: 
                    150: Process *
                    151: buf_to_proc(b)
                    152: register Buffer *b;
                    153: {
                    154:        register Process *p;
                    155: 
                    156:        for (p = procs; p != 0; p = p->p_next)
                    157:                if (p->p_buffer == b)
                    158:                        return p;
                    159:        return 0;
                    160: }
                    161: 
                    162: ProcCont()
                    163: {
                    164:        if (cur_proc == 0)
                    165:                complain("[No processes]");
                    166:        if (cur_proc->p_state != DEAD) {
                    167:                proc_kill(cur_proc, SIGCONT);
                    168:                cur_proc->p_state = RUNNING;
                    169:        }               
                    170: }
                    171: 
                    172: ProcEof()
                    173: {
                    174:        send_p(tc1.t_eofc);
                    175: }
                    176: 
                    177: ProcInt()
                    178: {
                    179:        send_p(tc1.t_intrc);
                    180: }
                    181: 
                    182: ProcQuit()
                    183: {
                    184:        send_p(tc1.t_quitc);
                    185: }
                    186: 
                    187: #ifdef TIOCSLTC
                    188: 
                    189: ProcStop()
                    190: {
                    191:        send_p(ls1.t_suspc);
                    192: }
                    193: 
                    194: ProcDStop()
                    195: {
                    196:        send_p(ls1.t_dsuspc);
                    197: }
                    198: 
                    199: #endif
                    200: 
                    201: send_p(c)
                    202: char   c;
                    203: {
                    204:        if (cur_proc == 0)
                    205:                complain("[No processes]");
                    206:        if (cur_proc->p_buffer == curbuf)
                    207:                ToLast();
                    208:        (void) write(cur_proc->p_fd, &c, 1);
                    209: }
                    210: 
                    211: static
                    212: proc_close(p)
                    213: Process *p;
                    214: {
                    215:        (void) close(p->p_fd);
                    216:        global_fd &= ~(1 << p->p_fd);
                    217:        p->p_eof++;
                    218: }
                    219: 
                    220: do_rtp(mp)
                    221: register Mark  *mp;
                    222: {
                    223:        register Process        *p = cur_proc;
                    224:        Line    *line1 = curline,
                    225:                *line2 = mp->m_line;
                    226:        int     char1 = curchar,
                    227:                char2 = mp->m_char;
                    228:        char    *gp;
                    229: 
                    230:        if (isdead(p) || p->p_buffer != curbuf)
                    231:                return;
                    232: 
                    233:        (void) fixorder(&line1, &char1, &line2, &char2);
                    234:        while (line1 != line2->l_next) {
                    235:                gp = ltobuf(line1, genbuf) + char1;
                    236:                if (line1 == line2)
                    237:                        gp[char2] = '\0';
                    238:                else
                    239:                        strcat(gp, "\n");
                    240:                (void) write(p->p_fd, gp, strlen(gp));
                    241:                line1 = line1->l_next;
                    242:                char1 = 0;
                    243:        }
                    244: }
                    245: 
                    246: /* VARARGS2 */
                    247: 
                    248: static
                    249: proc_strt(bufname, procname, cmd)
                    250: char   *bufname,
                    251:        *procname,
                    252:        *cmd;
                    253: {
                    254:        Window *owind   = curwind;
                    255:        int     pid;
                    256:        Process *newp;
                    257:        Buffer  *bp;
                    258:        char    **cp;
                    259:        int     i,
                    260:                f,
                    261:                ttyfd;
                    262:        long    ldisc,
                    263:                lmode;
                    264:        register char   *s,
                    265:                        *t;
                    266:        extern int      errno;
                    267:        extern char     **environ;
                    268:        static char     ttybuf[11],
                    269:                        ptybuf[11];
                    270:        char    cmdbuf[128];
                    271: #ifdef BRLUNIX
                    272:        struct sg_brl sg;
                    273: #else
                    274:        struct sgttyb sg;
                    275: #endif
                    276: 
                    277: #ifdef TIOCGWINSZ
                    278:        struct winsize win;
                    279: #else
                    280: #  ifdef BTL_BLIT
                    281: #  include <sys/jioctl.h>
                    282:        struct jwinsize jwin;
                    283: #  endif
                    284: #endif
                    285: 
                    286:        bp = buf_exists(bufname);
                    287:        if (bp != 0 && IsModified(bp) && bp->b_type != B_IPROCESS && bp->b_type != B_PROCESS)
                    288:                complain("Command would over-write buffer %s.", procname, bufname);
                    289:        pop_wind(bufname, 1, B_IPROCESS);
                    290: 
                    291:        for (s = "pqrs"; *s; s++) {
                    292:                for (t = "0123456789abcdef"; *t; t++) {
                    293:                        sprintf(ptybuf, "/dev/pty%c%c", *s, *t);
                    294:                        if ((ttyfd = open(ptybuf, 2)) >= 0)
                    295:                                goto out;
                    296:                }
                    297:        }
                    298: 
                    299: out:   if (s == 0 && t == 0)
                    300:                complain("[Out of ptys!]");
                    301: 
                    302:        strcpy(ttybuf, ptybuf);
                    303:        ttybuf[5] = 't';
                    304: 
                    305: #ifdef TIOCGETD
                    306:        (void) ioctl(0, TIOCGETD, (struct sgttyb *) &ldisc);
                    307: #endif
                    308: #ifdef TIOCLGET
                    309:        (void) ioctl(0, TIOCLGET, (struct sgttyb *) &lmode);
                    310: #endif
                    311: #ifdef TIOCGWINSZ
                    312:        (void) ioctl(0, TIOCGWINSZ, (struct sgttyb *) &win);
                    313: #else
                    314: #  ifdef BTL_BLIT
                    315:        (void) ioctl(0, JWINSIZE, (struct sgttyb *) &jwin);
                    316: #  endif BTL_BLIT
                    317: #endif
                    318: 
                    319:        switch (pid = fork()) {
                    320:        case -1:
                    321:                (void) close(ttyfd);
                    322:                complain("[Fork failed!]");
                    323: 
                    324:        case 0:
                    325:                cp = &cmd;
                    326: 
                    327:                for (i = 0; i < 32; i++)
                    328:                        (void) close(i);
                    329: 
                    330: #ifdef TIOCNOTTY
                    331:                if ((i = open("/dev/tty", 2)) >= 0) {
                    332:                        (void) ioctl(i, TIOCNOTTY, (struct sgttyb *) 0);
                    333:                        (void) close(i);
                    334:                }
                    335: #endif
                    336:                i = open(ttybuf, 2);
                    337:                for (f = 0; f <= 2; f++)
                    338:                        (void) dup2(i, f);
                    339: 
                    340: #ifdef TIOCSETD
                    341:                (void) ioctl(0, TIOCSETD, (struct sgttyb *) &ldisc);
                    342: #endif
                    343: #ifdef TIOCLSET
                    344:                (void) ioctl(0, TIOCLSET, (struct sgttyb *) &lmode);
                    345: #endif
                    346: #ifdef TIOCSETC
                    347:                (void) ioctl(0, TIOCSETC, (struct sgttyb *) &tc1);
                    348: #endif
                    349: #ifdef TIOCSLTC
                    350:                (void) ioctl(0, TIOCSLTC, (struct sgttyb *) &ls1);
                    351: #endif
                    352: 
                    353: #ifdef TIOCGWINSZ
                    354: #    ifdef SIGWINCH
                    355:                (void) signal(SIGWINCH, SIG_IGN);
                    356: #    endif
                    357:                win.ws_row = curwind->w_height;
                    358:                (void) ioctl(0, TIOCSWINSZ, (struct sgttyb *) &win);
                    359: #else
                    360: #  ifdef BTL_BLIT
                    361:                jwin.bytesy = curwind->w_height;
                    362:                (void) ioctl(0, JSWINSIZE, (struct sgttyb *) &jwin);
                    363: #  endif
                    364: #endif
                    365: 
                    366:                sg = sg1;
                    367:                sg.sg_flags &= ~(ECHO | CRMOD);
                    368:                (void) stty(0, &sg);
                    369: 
                    370:                i = getpid();
                    371:                (void) ioctl(0, TIOCSPGRP, (struct sgttyb *) &i);
                    372:                (void) setpgrp(0, i);
                    373:                execve(cp[0], &cp[1], environ);
                    374:                (void) write(1, "execve failed!\n", 15);
                    375:                _exit(errno + 1);
                    376:        }
                    377: 
                    378:        sighold(SIGCHLD);
                    379: #ifdef SIGWINCH
                    380:        sighold(SIGWINCH);
                    381: #endif
                    382:        cur_proc = newp = (Process *) emalloc(sizeof *newp);
                    383: 
                    384:        newp->p_fd = ttyfd;
                    385:        newp->p_pid = pid;
                    386:        newp->p_eof = 0;
                    387:        newp->p_buffer = curbuf;
                    388: 
                    389:        cp = &cmd + 1;
                    390:        cmdbuf[0] = '\0';
                    391:        while (*cp != 0)
                    392:                (void) sprintf(&cmdbuf[strlen(cmdbuf)], "%s ", *cp++);
                    393: 
                    394:        newp->p_name = copystr(cmdbuf);
                    395:        newp->p_state = RUNNING;
                    396:        newp->p_reason = 0;
                    397:        newp->p_mark = MakeMark(curline, curchar, FLOATER);
                    398: 
                    399:        newp->p_next = procs;
                    400:        procs = newp;
                    401:        NumProcs++;
                    402:        global_fd |= 1 << newp->p_fd;
                    403:        sigrelse(SIGCHLD);
                    404:        SetWind(owind);
                    405: }
                    406:        
                    407: pinit()
                    408: {
                    409:        (void) signal(SIGCHLD, proc_child);
                    410: }

unix.superglobalmegacorp.com

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