Annotation of 43BSDTahoe/new/jove/iproc.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: #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.