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