Annotation of 43BSDTahoe/new/jove/iproc.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: #include "jove.h"
        !             9: #include "re.h"
        !            10: #include <varargs.h>
        !            11: 
        !            12: #ifdef IPROCS
        !            13: 
        !            14: int    proc_child();
        !            15: 
        !            16: #ifdef PIPEPROCS
        !            17: #   include "iproc-pipes.c"
        !            18: #else
        !            19: #   include "iproc-ptys.c"
        !            20: #endif
        !            21: 
        !            22: char   proc_prompt[128] = "% ";
        !            23: 
        !            24: KillProcs()
        !            25: {
        !            26:        register Process        *p;
        !            27:        register int    killem = -1;            /* -1 means undetermined */
        !            28:        register char   *yorn;
        !            29: 
        !            30:        for (p = procs; p != 0; p = p->p_next)
        !            31:                if (!isdead(p)) {
        !            32:                        if (killem == -1) {
        !            33:                                yorn = ask("y", "Should I kill your i-processes? ");
        !            34:                                killem = (CharUpcase(*yorn) == 'Y');
        !            35:                        }
        !            36:                        if (killem)
        !            37:                                proc_kill(p, SIGKILL);
        !            38:                }
        !            39: }
        !            40: 
        !            41: pbuftiedp(b)
        !            42: register Buffer        *b;
        !            43: {
        !            44:        register Process        *p = b->b_process;
        !            45: 
        !            46:        if (!isdead(p))
        !            47:                complain("Process %s, attached to %b, is %s.",
        !            48:                         proc_cmd(p), b, pstate(p));
        !            49: }
        !            50: 
        !            51: /* Process receive: receives the characters in buf, and appends them to
        !            52:    the buffer associated with p. */
        !            53: 
        !            54: private
        !            55: proc_rec(p, buf)
        !            56: register Process       *p;
        !            57: char   *buf;
        !            58: {
        !            59:        Buffer  *saveb = curbuf;
        !            60:        register Window *w;
        !            61:        register Mark   *savepoint;
        !            62:        int     sameplace = NO,
        !            63:                do_disp = NO;
        !            64: 
        !            65:        if (curwind->w_bufp == p->p_buffer)
        !            66:                w = curwind;
        !            67:        else
        !            68:                w = windbp(p->p_buffer);        /* Is this window visible? */
        !            69:        if (w != 0)
        !            70:                do_disp = (in_window(w, p->p_mark->m_line) != -1);
        !            71:        SetBuf(p->p_buffer);
        !            72:        savepoint = MakeMark(curline, curchar, M_FLOATER);
        !            73:        ToMark(p->p_mark);              /* where output last stopped */
        !            74:        if (savepoint->m_line == curline && savepoint->m_char == curchar)
        !            75:                sameplace = YES;
        !            76: 
        !            77:        ins_str(buf, YES);
        !            78:        MarkSet(p->p_mark, curline, curchar);
        !            79:        if (!sameplace)
        !            80:                ToMark(savepoint);      /* back to where we were */
        !            81:        DelMark(savepoint);
        !            82:        /* redisplay now, instead of right after the ins_str, so that
        !            83:           we don't get a bouncing effect if point is not the same as
        !            84:           the process output position */
        !            85:        if (do_disp) {
        !            86:                w->w_line = curline;
        !            87:                w->w_char = curchar;
        !            88:                redisplay();
        !            89:        }
        !            90:        SetBuf(saveb);
        !            91: }
        !            92: 
        !            93: proc_kill(p, sig)
        !            94: register Process       *p;
        !            95: {
        !            96:        if (isdead(p))
        !            97:                return;
        !            98:        if (killpg(p->p_pid, sig) == -1)
        !            99:                s_mess("Cannot kill %s!", proc_buf(p));
        !           100: }
        !           101: 
        !           102: /* Free process CHILD.  Do all the necessary cleaning up (closing fd's,
        !           103:    etc.). */
        !           104: 
        !           105: free_proc(child)
        !           106: Process        *child;
        !           107: {
        !           108:        register Process        *p,
        !           109:                                *prev = 0;
        !           110: 
        !           111:        if (!isdead(child))
        !           112:                return; 
        !           113:        for (p = procs; p != child; prev = p, p = p->p_next)
        !           114:                ;
        !           115:        if (prev == 0)
        !           116:                procs = child->p_next;
        !           117:        else
        !           118:                prev->p_next = child->p_next;
        !           119:        proc_close(child);              /* if not already closed */
        !           120:        
        !           121:        /* It's possible that the buffer has been given another process
        !           122:           between the time CHILD dies and CHILD's death is noticed (via
        !           123:           list-processes).  So we only set it the buffer's process to
        !           124:           0 if CHILD is still the controlling process. */
        !           125:        if (child->p_buffer->b_process == child) {
        !           126:                child->p_buffer->b_process = 0;
        !           127:                if (curbuf == child->p_buffer)
        !           128:                        PopPBs();
        !           129:        }
        !           130:        {
        !           131:                Buffer  *old = curbuf;
        !           132: 
        !           133:                SetBuf(child->p_buffer);
        !           134:                DelMark(child->p_mark);
        !           135:                SetBuf(old);
        !           136:        }
        !           137:        free((char *) child->p_name);
        !           138:        free((char *) child);
        !           139: }
        !           140: 
        !           141: ProcList()
        !           142: {
        !           143:        register Process        *p,
        !           144:                                *next;
        !           145:        char    *fmt = "%-15s  %-15s  %-8s %s",
        !           146:                pidstr[16];
        !           147: 
        !           148:        if (procs == 0) {
        !           149:                message("[No subprocesses]");
        !           150:                return;
        !           151:        }
        !           152:        TOstart("Process list", TRUE);
        !           153: 
        !           154:        Typeout(fmt, "Buffer", "Status", "Pid ", "Command");
        !           155:        Typeout(fmt, "------", "------", "--- ", "-------");
        !           156:        for (p = procs; p != 0; p = next) {
        !           157:                next = p->p_next;
        !           158:                sprintf(pidstr, "%d", p->p_pid);
        !           159:                Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name);
        !           160:                if (isdead(p)) {
        !           161:                        free_proc(p);
        !           162:                        UpdModLine = YES;
        !           163:                }
        !           164:        }
        !           165:        TOstop();
        !           166: }
        !           167: 
        !           168: ProcNewline()
        !           169: {
        !           170: #ifdef ABBREV
        !           171:        MaybeAbbrevExpand();
        !           172: #endif
        !           173:        SendData(YES);
        !           174: }
        !           175: 
        !           176: ProcSendData()
        !           177: {
        !           178: #ifdef ABBREV
        !           179:        MaybeAbbrevExpand();
        !           180: #endif
        !           181:        SendData(NO);
        !           182: }
        !           183: 
        !           184: private
        !           185: SendData(newlinep)
        !           186: {
        !           187:        register Process        *p = curbuf->b_process;
        !           188:        register char   *lp,
        !           189:                        *gp;    /* JF fix for better prompt handling */
        !           190: 
        !           191:        if (isdead(p))
        !           192:                return;
        !           193:        /* If the process mark was involved in a big deletion, because
        !           194:           the user hit ^W or something, then let's do some magic with
        !           195:           the process mark.  Problem is that if the user yanks back the
        !           196:           text he deleted, the mark stays at the beginning of the region,
        !           197:           and so the next time SendData() is called the entire region
        !           198:           will be sent.  That's not good.  So, to deal with that we reset
        !           199:           the mark to the last line, after skipping over the prompt, etc. */
        !           200:        if (p->p_mark->m_flags & M_BIG_DELETE) {
        !           201:                Bufpos  bp;
        !           202: 
        !           203:                p->p_mark->m_flags &= ~M_BIG_DELETE;
        !           204: 
        !           205:                DOTsave(&bp);
        !           206:                ToLast();
        !           207:                Bol();
        !           208:                /* While we're looking at a prompt, and while we're
        !           209:                   moving forward.  This is for people who accidently
        !           210:                   set their process-prompt to ">*" which will always
        !           211:                   match! */
        !           212:                while ((LookingAt(proc_prompt, linebuf, curchar)) &&
        !           213:                       (REeom > curchar))
        !           214:                        curchar = REeom;
        !           215:                MarkSet(p->p_mark, curline, curchar);
        !           216:                SetDot(&bp);
        !           217:        }
        !           218: 
        !           219:        if (lastp(curline)) {
        !           220:                Eol();
        !           221:                if (newlinep)
        !           222:                        LineInsert(1);
        !           223:                do_rtp(p->p_mark);
        !           224:                MarkSet(p->p_mark, curline, curchar);
        !           225:        } else {
        !           226:                /* Either we're looking at a prompt, or we're not, in
        !           227:                   which case we want to strip off the beginning of the
        !           228:                   line anything that looks like what the prompt at the
        !           229:                   end of the file is.  In other words, if "(dbx) stop in
        !           230:                   ProcessNewline" is the line we're on, and the last
        !           231:                   line in the buffer is "(dbx) ", then we strip off the
        !           232:                   leading "(dbx) " from this line, because we know it's
        !           233:                   part of the prompt.  But this only happens if "(dbx) "
        !           234:                   isn't one of the process prompts ... follow what I'm
        !           235:                   saying? */
        !           236:                Bol();
        !           237:                if (LookingAt(proc_prompt, linebuf, curchar)) {
        !           238:                        do
        !           239:                                curchar = REeom;
        !           240:                        while ((LookingAt(proc_prompt, linebuf, curchar)) &&
        !           241:                               (REeom > curchar));
        !           242:                        strcpy(genbuf, linebuf + curchar);
        !           243:                        Eof();
        !           244:                        ins_str(genbuf, NO);
        !           245:                } else {
        !           246:                        strcpy(genbuf, linebuf + curchar);
        !           247:                        Eof();
        !           248:                        gp = genbuf;
        !           249:                        lp = linebuf;
        !           250:                        while (*lp == *gp && *lp != '\0') {
        !           251:                                lp += 1;
        !           252:                                gp += 1;
        !           253:                        }
        !           254:                        ins_str(gp, NO);
        !           255:                }
        !           256:        }
        !           257: }
        !           258: 
        !           259: ShellProc()
        !           260: {
        !           261:        char    *shbuf = "*shell*";
        !           262:        register Buffer *b;
        !           263: 
        !           264:        b = buf_exists(shbuf);
        !           265:        if (b == 0 || isdead(b->b_process))
        !           266:                proc_strt(shbuf, NO, Shell, "-i", (char *) 0);
        !           267:        pop_wind(shbuf, NO, -1);
        !           268: }
        !           269: 
        !           270: Iprocess()
        !           271: {
        !           272:        extern char     ShcomBuf[100],
        !           273:                        *MakeName();
        !           274:        register char   *command;
        !           275:        char    scratch[64],
        !           276:                *bufname;
        !           277:        int     cnt = 1;
        !           278:        Buffer  *bp;
        !           279: 
        !           280:        command = ask(ShcomBuf, ProcFmt);
        !           281:        null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1);
        !           282:        bufname = MakeName(command);
        !           283:        strcpy(scratch, bufname);
        !           284:        while ((bp = buf_exists(scratch)) && !isdead(bp->b_process))
        !           285:                sprintf(scratch, "%s.%d", bufname, cnt++);
        !           286:        proc_strt(scratch, YES, Shell, ShFlags, command, (char *) 0);
        !           287: }
        !           288: 
        !           289: proc_child()
        !           290: {
        !           291:        union wait      w;
        !           292:        register int    pid;
        !           293: 
        !           294:        for (;;) {
        !           295: #ifndef BSD4_2
        !           296:                pid = wait2(&w.w_status, (WNOHANG | WUNTRACED));
        !           297: #else
        !           298:                pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0);
        !           299: #endif
        !           300:                if (pid <= 0)
        !           301:                        break;
        !           302:                kill_off(pid, w);
        !           303:        }
        !           304: }
        !           305: 
        !           306: kill_off(pid, w)
        !           307: register int   pid;
        !           308: union wait     w;
        !           309: {
        !           310:        register Process        *child;
        !           311: 
        !           312:        if ((child = proc_pid(pid)) == 0)
        !           313:                return;
        !           314: 
        !           315:        UpdModLine = YES;               /* we're changing state ... */
        !           316:        if (WIFSTOPPED(w))
        !           317:                child->p_state = STOPPED;
        !           318:        else {
        !           319:                child->p_state = DEAD;
        !           320:                if (WIFEXITED(w))
        !           321:                        child->p_howdied = EXITED;
        !           322:                else if (WIFSIGNALED(w)) {
        !           323:                        child->p_reason = w.w_termsig;
        !           324:                        child->p_howdied = KILLED;
        !           325:                }
        !           326:                {
        !           327:                        Buffer  *save = curbuf;
        !           328:                        char    mesg[128];
        !           329: 
        !           330:                        /* insert status message now */
        !           331:                        sprintf(mesg, "[Process %s: %s]\n",
        !           332:                                proc_cmd(child),
        !           333:                                pstate(child));
        !           334:                        SetBuf(child->p_buffer);
        !           335:                        ins_str(mesg, NO);
        !           336:                        SetBuf(save);
        !           337:                        redisplay();
        !           338:                }
        !           339:        }
        !           340: }
        !           341: 
        !           342: /* Push/pod process bindings.  I openly acknowledge that this is a
        !           343:    kludge, but I can't be bothered making it right. */
        !           344: 
        !           345: struct proc_bind {
        !           346:        int             pb_key;
        !           347:        data_obj        **pb_map;
        !           348:        data_obj        *pb_push;
        !           349:        data_obj        *pb_cmd;
        !           350:        struct proc_bind *pb_next;
        !           351: };
        !           352: 
        !           353: struct proc_bind *PBinds = 0;
        !           354: 
        !           355: PopPBs()
        !           356: {
        !           357:        register struct proc_bind *p;
        !           358: 
        !           359:        for (p = PBinds; p != 0; p = p->pb_next)
        !           360:                p->pb_map[p->pb_key] = p->pb_push;
        !           361: }
        !           362: 
        !           363: PushPBs()
        !           364: {
        !           365:        register struct proc_bind *p;
        !           366: 
        !           367:        for (p = PBinds; p != 0; p = p->pb_next) {
        !           368:                p->pb_push = p->pb_map[p->pb_key];
        !           369:                p->pb_map[p->pb_key] = p->pb_cmd;
        !           370:        }
        !           371: }
        !           372: /* VARARGS0 */
        !           373: 
        !           374: ProcBind()
        !           375: {
        !           376:        register data_obj       *d;
        !           377: 
        !           378:        if ((d = findcom(ProcFmt)) == 0)
        !           379:                return;
        !           380:        s_mess(": %f %s ", d->Name);
        !           381:        ProcB2(mainmap, EOF, d);
        !           382: }
        !           383: 
        !           384: ProcB2(map, lastkey, cmd)
        !           385: data_obj       **map,
        !           386:                *cmd;
        !           387: {
        !           388:        register struct proc_bind *p;
        !           389:        register data_obj       **nextmap;
        !           390:        int     c;
        !           391: 
        !           392:        c = addgetc();
        !           393:        if (c == EOF) {
        !           394:                if (lastkey == EOF)
        !           395:                        complain("[Empty key sequence]");
        !           396:                complain("[Unexpected end-of-line]");
        !           397:        } else {
        !           398:                if (nextmap = IsPrefix(map[c]))
        !           399:                        ProcB2(nextmap, c, cmd);
        !           400:                else {
        !           401:                        if (curbuf->b_process)
        !           402:                                PopPBs();
        !           403: 
        !           404:                        for (p = PBinds; p != 0; p = p->pb_next)
        !           405:                                if (p->pb_key == c && p->pb_map == map)
        !           406:                                        break;
        !           407:                        if (p == 0) {
        !           408:                                p = (struct proc_bind *) emalloc(sizeof *p);
        !           409:                                p->pb_next = PBinds;
        !           410:                                PBinds = p;
        !           411:                        }
        !           412:                        p->pb_map = map;
        !           413:                        p->pb_key = c;
        !           414:                        p->pb_cmd = cmd;
        !           415: 
        !           416:                        if (curbuf->b_process)
        !           417:                                PushPBs();
        !           418:                }
        !           419:        }
        !           420: }
        !           421: 
        !           422: #endif /* IPROCS */
        !           423: 

unix.superglobalmegacorp.com

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