Annotation of 43BSDReno/contrib/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 "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.