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

unix.superglobalmegacorp.com

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