Annotation of 43BSDTahoe/new/jove/proc.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 "io.h"
                     10: #include "termcap.h"
                     11: 
                     12: #include <signal.h>
                     13: #include <varargs.h>
                     14: 
                     15: #ifdef MSDOS
                     16: # include <io.h>
                     17: # include <process.h>
                     18: #endif
                     19: 
                     20: 
                     21: #ifdef LINT_ARGS
                     22: private void
                     23:        DoShell(char *, char *),
                     24:        com_finish(int, char *),
                     25:        toerror(int, int),
                     26:        closepipe(void);
                     27:        
                     28: private int
                     29:        okay_error(void),
                     30:        openforpipe(void),
                     31:        reopenforpipe(void);
                     32: 
                     33: private struct error
                     34:        * AddError(struct error *, Line *, Buffer *, Line *, int);
                     35: #else
                     36: private void
                     37:        DoShell(),
                     38:        com_finish(),
                     39:        toerror(),
                     40:        closepipe();
                     41: 
                     42: private int
                     43:        openforpipe(),
                     44:        okay_error(),
                     45:        reopenforpipe();
                     46: 
                     47: private struct error
                     48:        * AddError();
                     49: #endif
                     50: 
                     51: 
                     52: /* This disgusting RE search string parses output from the GREP
                     53:    family, from the pdp11 compiler, pcc, and lint.  Jay (HACK)
                     54:    Fenlasen changed this to work for the lint errors. */
                     55: char   ErrFmtStr[256] = "^\\{\",\\}\\([^:\"( \t]*\\)\\{\"\\, line ,:,(\\} *\\([0-9][0-9]*\\)[:)]\
                     56: \\|::  *\\([^(]*\\)(\\([0-9]*\\))$\
                     57: \\|( \\([^(]*\\)(\\([0-9]*\\)) ),";
                     58: 
                     59: struct error {
                     60:        Buffer          *er_buf;        /* Buffer error is in */
                     61:        Line            *er_mess,       /* Actual error message */
                     62:                        *er_text;       /* Actual error */
                     63:        int             er_char;        /* char pos of error */
                     64:        struct error    *er_prev,       /* List of errors */
                     65:                        *er_next;
                     66: };
                     67: 
                     68: struct error   *cur_error = 0,
                     69:                *errorlist = 0;
                     70: Buffer         *perr_buf = 0;  /* Buffer with error messages */
                     71: 
                     72: int    WtOnMk = 1;             /* Write the modified files when we make */
                     73: 
                     74: /* Add an error to the end of the list of errors.  This is used for
                     75:    parse-{C,LINT}-errors and for the spell-buffer command */
                     76: 
                     77: private struct error *
                     78: AddError(laste, errline, buf, line, charpos)
                     79: struct error   *laste;
                     80: Line   *errline,
                     81:        *line;
                     82: Buffer *buf;
                     83: {
                     84:        struct error    *new = (struct error *) emalloc(sizeof *new);
                     85: 
                     86:        new->er_prev = laste;
                     87:        if (laste)
                     88:                laste->er_next = new;
                     89:        else {
                     90:                if (errorlist)          /* Free up old errors */
                     91:                        ErrFree();
                     92:                cur_error = errorlist = new;
                     93:        }
                     94:        laste = new;
                     95:        new->er_next = 0;
                     96:        new->er_buf = buf;
                     97:        new->er_text = line;
                     98:        new->er_char = charpos;
                     99:        new->er_mess = errline;
                    100: 
                    101:        return new;
                    102: }
                    103: 
                    104: /* Parse errors of the form specified in ErrFmtStr in the current
                    105:    buffer.  Do a show error of the first error.  This is neat because this
                    106:    will work for any kind of output that prints a file name and a line
                    107:    number on the same line. */
                    108: 
                    109: void
                    110: ErrParse()
                    111: {
                    112:        Bufpos  *bp;
                    113:        char    fname[FILESIZE],
                    114:                lineno[10],
                    115:                REbuf[256],
                    116:                *REalts[10];
                    117:        int     lnum,
                    118:                last_lnum = -1;
                    119:        struct error    *ep = 0;
                    120:        Buffer  *buf,
                    121:                *lastb = 0;
                    122:        Line    *err_line;      
                    123: 
                    124:        ErrFree();              /* This is important! */
                    125:        ToFirst();
                    126:        perr_buf = curbuf;
                    127:        REcompile(ErrFmtStr, 1, REbuf, REalts);
                    128:        /* Find a line with a number on it. */
                    129:        while (bp = docompiled(FORWARD, REbuf, REalts)) {
                    130:                SetDot(bp);
                    131:                putmatch(1, fname, sizeof fname);
                    132:                putmatch(2, lineno, sizeof lineno);
                    133:                buf = do_find((Window *) 0, fname, 1);
                    134:                if (buf != lastb) {
                    135:                        lastb = buf;
                    136:                        last_lnum = -1;         /* signals new file */
                    137:                        err_line = buf->b_first;
                    138:                }
                    139:                (void) chr_to_int(lineno, 10, NO, &lnum);
                    140:                if (lnum == last_lnum)  /* one error per line is nicer */
                    141:                        continue;
                    142:                if (last_lnum == -1)
                    143:                        last_lnum = 1;  /* that's where we really are */
                    144:                err_line = next_line(err_line, lnum - last_lnum);
                    145:                ep = AddError(ep, curline, buf, err_line, 0);
                    146:                last_lnum = lnum;
                    147:        }
                    148:        if (cur_error != 0)
                    149:                ShowErr();
                    150: }
                    151: 
                    152: /* Free up all the errors */
                    153: 
                    154: void
                    155: ErrFree()
                    156: {
                    157:        register struct error   *ep;
                    158: 
                    159:        for (ep = errorlist; ep != 0; ep = ep->er_next)
                    160:                free((char *) ep);
                    161:        errorlist = cur_error = 0;
                    162: }
                    163: 
                    164: /* Internal next error sets cur_error to the next error, taking the
                    165:    argument count, supplied by the user, into consideration. */
                    166: 
                    167: private char   errbounds[] = "You're at the %s error.",
                    168:                noerrs[] = "No errors!";
                    169: 
                    170: private void
                    171: toerror(forward, num)
                    172: {
                    173:        register struct error   *e = cur_error;
                    174: 
                    175:        if (e == 0)
                    176:                complain(noerrs);
                    177:        if ((forward && (e->er_next == 0)) ||
                    178:            (!forward && (e->er_prev == 0)))
                    179:                complain(errbounds, forward ? "last" : "first");
                    180: 
                    181:        while (--num >= 0) {
                    182:                if ((e = forward ? e->er_next : e->er_prev) == 0)
                    183:                        break;
                    184:                cur_error = e;
                    185:        }
                    186: }
                    187: 
                    188: void
                    189: NextError()
                    190: {
                    191:        ToError(1);
                    192: }
                    193: 
                    194: void
                    195: PrevError()
                    196: {
                    197:        ToError(0);
                    198: }
                    199: 
                    200: private int
                    201: okay_error()
                    202: {
                    203:        return ((inlist(perr_buf->b_first, cur_error->er_mess)) &&
                    204:                (inlist(cur_error->er_buf->b_first, cur_error->er_text)));
                    205: }
                    206: 
                    207: /* Go the the next error, if there is one.  Put the error buffer in
                    208:    one window and the buffer with the error in another window.
                    209:    It checks to make sure that the error actually exists. */
                    210: 
                    211: void
                    212: ToError(forward)
                    213: {
                    214:        do {
                    215:                toerror(forward, arg_value());
                    216:        } while (!okay_error());
                    217:        ShowErr();
                    218: }
                    219: 
                    220: int    EWSize = 20;    /* percentage of screen the error window
                    221:                           should be */
                    222: 
                    223: void
                    224: set_wsize(wsize)
                    225: int    wsize;
                    226: {
                    227:        wsize = (LI * wsize) / 100;
                    228:        if (wsize >= 1 && !one_windp())
                    229:                WindSize(curwind, wsize - (curwind->w_height - 1));
                    230: }
                    231: 
                    232: /* Show the current error, i.e. put the line containing the error message
                    233:    in one window, and the buffer containing the actual error in another
                    234:    window. */
                    235: 
                    236: void
                    237: ShowErr()
                    238: {
                    239:        Window  *err_wind,
                    240:                *buf_wind;
                    241: 
                    242:        if (cur_error == 0)
                    243:                complain(noerrs);
                    244:        if (!okay_error()) {
                    245:                rbell();
                    246:                return;
                    247:        }
                    248:        err_wind = windbp(perr_buf);
                    249:        buf_wind = windbp(cur_error->er_buf);
                    250: 
                    251:        if (err_wind && !buf_wind) {
                    252:                SetWind(err_wind);
                    253:                pop_wind(cur_error->er_buf->b_name, NO, -1);
                    254:                buf_wind = curwind;
                    255:        } else if (!err_wind && buf_wind) {
                    256:                SetWind(buf_wind);
                    257:                pop_wind(perr_buf->b_name, NO, -1);
                    258:                err_wind = curwind;
                    259:        } else if (!err_wind && !buf_wind) {
                    260:                pop_wind(perr_buf->b_name, NO, -1);
                    261:                err_wind = curwind;
                    262:                pop_wind(cur_error->er_buf->b_name, NO, -1);
                    263:                buf_wind = curwind;
                    264:        }
                    265: 
                    266:        /* Put the current error message at the top of its Window */
                    267:        SetWind(err_wind);
                    268:        SetLine(cur_error->er_mess);
                    269:        SetTop(curwind, (curwind->w_line = cur_error->er_mess));
                    270:        set_wsize(EWSize);
                    271: 
                    272:        /* now go to the the line with the error in the other window */
                    273:        SetWind(buf_wind);
                    274:        DotTo(cur_error->er_text, cur_error->er_char);
                    275: }
                    276: 
                    277: char   ShcomBuf[128] = {0};
                    278: 
                    279: /* Make a buffer name given the command `command', i.e. "fgrep -n foo *.c"
                    280:    will return the buffer name "fgrep".  */
                    281: 
                    282: char *
                    283: MakeName(command)
                    284: char   *command;
                    285: {
                    286:        static char     bufname[50];
                    287:        register char   *cp = bufname,
                    288:                        c;
                    289: 
                    290:        while ((c = *command++) && (c == ' ' || c == '\t'))
                    291:                ;
                    292:        do
                    293:                *cp++ = c;
                    294:        while ((c = *command++) && (c != ' ' && c != '\t'));
                    295:        *cp = 0;
                    296:        strcpy(bufname, basename(bufname));
                    297: 
                    298:        return bufname;
                    299: }
                    300: 
                    301: /* Run make, first writing all the modified buffers (if the WtOnMk flag is
                    302:    non-zero), parse the errors, and go the first error. */
                    303: 
                    304: char   make_cmd[128] = "make";
                    305: 
                    306: void
                    307: MakeErrors()
                    308: {
                    309:        Window  *old = curwind;
                    310:        int     status,
                    311:                compilation;
                    312:        
                    313:        if (WtOnMk)
                    314:                put_bufs(0);
                    315:        /* When we're not doing make or cc (i.e., the last command
                    316:           was probably a grep or something) and the user just types
                    317:           C-X C-E, he probably (possibly, hopefully, usually (in my
                    318:           case)) doesn't want to do the grep again but rather wants
                    319:           to do a make again; so we ring the bell and insert the
                    320:           default command and let the person decide. */
                    321: 
                    322:        compilation = (sindex("make", make_cmd) || sindex("cc", make_cmd));
                    323:        if (is_an_arg() || !compilation) {
                    324:                if (!compilation) {
                    325:                        rbell();
                    326:                        Inputp = make_cmd;      /* insert the default for the user */
                    327:                }
                    328:                null_ncpy(make_cmd, ask(make_cmd, "Compilation command: "),
                    329:                                sizeof (make_cmd) - 1);
                    330:        }
                    331:        status = UnixToBuf(MakeName(make_cmd), YES, EWSize, YES, Shell, ShFlags, make_cmd, (char *) 0);
                    332:        com_finish(status, make_cmd);
                    333: 
                    334:        ErrParse();
                    335: 
                    336:        if (!cur_error)
                    337:                SetWind(old);
                    338: }
                    339: 
                    340: #ifdef SPELL
                    341: 
                    342: void
                    343: SpelBuffer()
                    344: {
                    345:        char    *Spell = "Spell",
                    346:                com[100];
                    347:        Window  *savewp = curwind;
                    348: 
                    349:        put_bufs(0);
                    350:        sprintf(com, "spell %s", curbuf->b_fname);
                    351:        (void) UnixToBuf(Spell, YES, EWSize, YES, Shell, ShFlags, com, (char *) 0);
                    352:        message("[Delete the irrelevant words and then type C-X C-C]");
                    353:        ToFirst();
                    354:        Recur();
                    355:        SetWind(savewp);
                    356:        SpelParse(Spell);
                    357: }
                    358: 
                    359: void
                    360: SpelWords()
                    361: {
                    362:        char    *buftospel;
                    363:        Buffer  *wordsb = curbuf;
                    364: 
                    365:        if ((buftospel = ask_buf((Buffer *) 0)) == 0)
                    366:                return;
                    367:        SetBuf(do_select(curwind, buftospel));
                    368:        SpelParse(wordsb->b_name);
                    369: }
                    370: 
                    371: void
                    372: SpelParse(bname)
                    373: char   *bname;
                    374: {
                    375:        Buffer  *buftospel,
                    376:                *wordsb;
                    377:        char    wordspel[100];
                    378:        Bufpos  *bp;
                    379:        struct error    *ep = 0;
                    380: 
                    381:        ErrFree();              /* This is important! */
                    382: 
                    383:        buftospel = curbuf;
                    384:        wordsb = buf_exists(bname);
                    385:        perr_buf = wordsb;      /* This is important (buffer containing
                    386:                                   error messages) */
                    387:        SetBuf(wordsb);
                    388:        ToFirst();
                    389:        f_mess("Finding misspelled words ... ");
                    390:        while (!lastp(curline)) {
                    391:                sprintf(wordspel, "\\<%s\\>", linebuf);
                    392:                SetBuf(buftospel);
                    393:                ToFirst();
                    394:                while (bp = dosearch(wordspel, 1, 1)) {
                    395:                        SetDot(bp);
                    396:                        ep = AddError(ep, wordsb->b_dot, buftospel,
                    397:                                          curline, curchar);
                    398:                }
                    399:                SetBuf(wordsb);
                    400:                line_move(FORWARD, 1, NO);
                    401:        }
                    402:        add_mess("Done.");
                    403:        SetBuf(buftospel);
                    404:        ShowErr();
                    405: }
                    406: 
                    407: #endif /* SPELL */
                    408: 
                    409: void
                    410: ShToBuf()
                    411: {
                    412:        char    bufname[128],
                    413:                cmd[128];
                    414: 
                    415:        strcpy(bufname, ask((char *) 0, "Buffer: "));
                    416:        strcpy(cmd, ask(ShcomBuf, "Command: "));
                    417:        DoShell(bufname, cmd);
                    418: }
                    419: 
                    420: void
                    421: ShellCom()
                    422: {
                    423:        null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1);
                    424:        DoShell(MakeName(ShcomBuf), ShcomBuf);
                    425: }
                    426: 
                    427: ShNoBuf()
                    428: {
                    429:        int     status;
                    430: 
                    431:        null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1);
                    432:        status = UnixToBuf((char *) 0, NO, 0, NO, Shell, ShFlags, ShcomBuf, (char *) 0);
                    433:        com_finish(status, ShcomBuf);
                    434: }
                    435: 
                    436: Shtypeout()
                    437: {
                    438:        int     status;
                    439: 
                    440:        null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1);
                    441:        status = UnixToBuf((char *) 0, YES, 0, NO, Shell, ShFlags, ShcomBuf, (char *) 0);
                    442:        if (status == 0)
                    443:                Typeout("[%s: completed successfully]", ShcomBuf);
                    444:        else
                    445:                Typeout("[%s: exited (%d)]", ShcomBuf, status);
                    446:        TOstop();
                    447: }
                    448: 
                    449: /* Run the shell command into `bufname'.  Empty the buffer except when we
                    450:    give a numeric argument, in which case it inserts the output at the
                    451:    current position in the buffer.  */
                    452: 
                    453: private void
                    454: DoShell(bufname, command)
                    455: char   *bufname,
                    456:        *command;
                    457: {
                    458:        Window  *savewp = curwind;
                    459:        int     status;
                    460: 
                    461:        status = UnixToBuf(bufname, YES, 0, !is_an_arg(), Shell,
                    462:                           ShFlags, command, (char *) 0);
                    463:        com_finish(status, command);
                    464:        SetWind(savewp);
                    465: }
                    466: 
                    467: private void
                    468: com_finish(status, cmd)
                    469: int    status;
                    470: char   *cmd;
                    471: {
                    472:        s_mess("[%s: ", cmd);
                    473:        if (status == 0)
                    474:                add_mess("completed successfully");
                    475:        else
                    476:                add_mess("exited (%d)", status);
                    477:        add_mess("]");
                    478: }
                    479: 
                    480: #ifndef MSDOS
                    481: void
                    482: dowait(pid, status)
                    483: int    pid,
                    484:        *status;
                    485: {
                    486: # ifndef IPROCS
                    487: 
                    488:        int     rpid;
                    489: 
                    490:        while ((rpid = wait(status)) != pid)
                    491:                ;
                    492: # else
                    493: 
                    494: #  ifdef BSD4_2
                    495: #   include <sys/wait.h>
                    496: #  else
                    497: #   include <wait.h>
                    498: #  endif
                    499: 
                    500:        union wait      w;
                    501:        int     rpid;
                    502: 
                    503:        for (;;) {
                    504: #  ifndef BSD4_2
                    505:                rpid = wait2(&w.w_status, 0);
                    506: #  else
                    507:                rpid = wait3(&w, 0, (struct rusage *) 0);
                    508: #  endif
                    509:                if (rpid == pid) {
                    510:                        if (status)
                    511:                                *status = w.w_status;
                    512:                        break;
                    513:                } else
                    514:                        kill_off(rpid, w);
                    515:        }
                    516: # endif /* IPROCS */
                    517: }
                    518: #endif /* MSDOS */
                    519: 
                    520: /* Run the command to bufname, erase the buffer if clobber is non-zero,
                    521:    and redisplay if disp is non-zero.  Leaves current buffer in `bufname'
                    522:    and leaves any windows it creates lying around.  It's up to the caller
                    523:    to fix everything up after we're done.  (Usually there's nothing to
                    524:    fix up.) */
                    525: 
                    526: /* VARARGS5 */
                    527: 
                    528: int
                    529: UnixToBuf(bufname, disp, wsize, clobber, va_alist)
                    530: char   *bufname;
                    531: va_dcl
                    532: {
                    533: #ifndef MSDOS
                    534:        int     p[2],
                    535:                pid,
                    536:                status,
                    537: #else /* MSDOS */
                    538:        int     p0,
                    539:                oldo,
                    540:                olde,
                    541:                retcode,
                    542: #endif /* MSDOS */
                    543:                eof;
                    544:        va_list ap;
                    545:        char    *argv[32],
                    546:                *mess;
                    547:        File    *fp;
                    548:        int     (*old_int)();
                    549: 
                    550:        va_start(ap);
                    551:        make_argv(argv, ap);
                    552:        va_end(ap);
                    553:        if (bufname != 0 && clobber == YES)
                    554:                isprocbuf(bufname);
                    555:        if (disp) {
                    556:                if (bufname != 0)
                    557:                        message("Starting up...");
                    558:                else {
                    559:                        TOstart(argv[0], TRUE);
                    560:                        Typeout("Starting up...");
                    561:                }
                    562:                if (bufname != 0) {
                    563:                        pop_wind(bufname, clobber, clobber ? B_PROCESS : B_FILE);
                    564:                        set_wsize(wsize);
                    565:                        redisplay();
                    566:                }
                    567:        }
                    568:        /* Now I will attempt to describe how I deal with signals during
                    569:           the execution of the shell command.  My desire was to be able
                    570:           to interrupt the shell command AS SOON AS the window pops up.
                    571:           So, if we have JOB_CONTROL (i.e., the new signal mechanism) I
                    572:           hold SIGINT, meaning if we interrupt now, we will eventually
                    573:           see the interrupt, but not before we are ready for it.  We
                    574:           fork, the child releases the interrupt, it then sees the
                    575:           interrupt, and so exits.  Meanwhile the parent ignores the
                    576:           signal, so if there was a pending one, it's now lost.
                    577: 
                    578:           With no JOB_CONTROL, the best behavior you can expect is, when
                    579:           you type ^] too very quickly after the window pops up, it may
                    580:           be ignored.  The behavior BEFORE was that it would interrupt
                    581:           JOVE and then you would have to continue JOVE and wait a
                    582:           little while longer before trying again.  Now that is fixed,
                    583:           in that you just have to type it twice. */
                    584: 
                    585: #ifndef MSDOS
                    586: # ifdef IPROCS
                    587:        sighold(SIGCHLD);
                    588: # endif
                    589: # ifdef JOB_CONTROL
                    590:        sighold(SIGINT);
                    591: # else
                    592:        old_int = signal(SIGINT, SIG_IGN),
                    593: # endif
                    594:        dopipe(p);
                    595:        pid = fork();
                    596:        if (pid == -1) {
                    597:                pclose(p);
                    598:                complain("[Fork failed]");
                    599:        }
                    600:        if (pid == 0) {
                    601: # ifdef IPROCS
                    602:                sigrelse(SIGCHLD);   /* don't know if this matters */
                    603: # endif /* IPROCS */
                    604:                (void) signal(SIGINT, SIG_DFL);
                    605: # ifdef JOB_CONTROL
                    606:                sigrelse(SIGINT);
                    607: # endif
                    608:                (void) close(0);
                    609:                (void) open("/dev/null", 0);
                    610:                (void) close(1);
                    611:                (void) close(2);
                    612:                (void) dup(p[1]);
                    613:                (void) dup(p[1]);
                    614:                pclose(p);
                    615:                execv(argv[0], &argv[1]);
                    616:                (void) write(1, "Execl failed.\n", 14);
                    617:                _exit(1);
                    618:        }
                    619: # ifdef JOB_CONTROL
                    620:        old_int = signal(SIGINT, SIG_IGN);
                    621: # endif        
                    622:        (void) close(p[1]);
                    623:        fp = fd_open(argv[1], F_READ, p[0], iobuff, LBSIZE);
                    624: #else /* MSDOS */
                    625:        if ((p0 = openforpipe()) < 0)
                    626:           complain("cannot make pipe for filter");
                    627: 
                    628:        oldo = dup(1);
                    629:        olde = dup(2);
                    630:        close(1);
                    631:        close(2);
                    632:        dup(p0);
                    633:        dup(1);
                    634:        close(p0);
                    635:        retcode = spawnv(0, argv[0], &argv[1]);
                    636:        p0 = reopenforpipe();
                    637:        close(1);
                    638:        close(2);
                    639:        dup(oldo);
                    640:        dup(olde);
                    641:        close(oldo);
                    642:        close(olde);
                    643: 
                    644:        if (retcode < 0)
                    645:                complain("[Spawn failed]");
                    646: 
                    647:        fp = fd_open(argv[1], F_READ, p0, iobuff, LBSIZE);
                    648: #endif /* MSDOS */
                    649:        do {
                    650: #ifndef MSDOS
                    651:                inIOread = 1;
                    652: #endif
                    653:                eof = f_gets(fp, genbuf, LBSIZE);
                    654: #ifndef MSDOS
                    655:                inIOread = 0;
                    656: #endif
                    657:                if (bufname != 0) {
                    658:                        ins_str(genbuf, YES);
                    659:                        if (!eof)
                    660:                                LineInsert(1);
                    661:                } else if (disp == YES)
                    662:                        Typeout("%s", genbuf);
                    663:                if (bufname != 0 && disp != 0 && fp->f_cnt <= 0) {
                    664: #ifdef LOAD_AV
                    665:                    {
                    666:                        double  theavg;
                    667: 
                    668:                        get_la(&theavg);
                    669:                        if (theavg < 2.0)
                    670:                                mess = "Screaming along...";
                    671:                        else if (theavg < 5.0)
                    672:                                mess = "Chugging along...";
                    673:                        else
                    674:                                mess = "Crawling along...";
                    675:                    }
                    676: #else
                    677:                        mess = "Chugging along...";
                    678: #endif /* LOAD_AV */
                    679:                        if (bufname != 0) {
                    680:                                message(mess);
                    681:                                redisplay();
                    682:                        }
                    683:                }
                    684:        } while (!eof);
                    685:        if (disp)
                    686:                DrawMesg(NO);
                    687:        close_file(fp);
                    688: #ifndef MSDOS
                    689:        dowait(pid, &status);
                    690: # ifdef JOB_CONTROL
                    691:        (void) sigrelse(SIGINT);
                    692: # endif
                    693: #else /* MSDOS */
                    694:        closepipe();
                    695: #endif /* MSDOS */
                    696:        (void) signal(SIGINT, old_int);
                    697: #ifndef MSDOS
                    698: # ifdef IPROCS
                    699:        sigrelse(SIGCHLD);
                    700: # endif
                    701:        return status;
                    702: #else /* MSDOS */
                    703: # ifdef CHDIR
                    704:        getCWD();
                    705: # endif        
                    706:        return retcode;
                    707: #endif /* MSDOS */
                    708: }
                    709: 
                    710: #ifndef MSDOS
                    711: #ifdef BSD4_2
                    712: 
                    713: private long   SigMask = 0;
                    714: 
                    715: #ifndef sigmask
                    716: #      define  sigmask(s)      (1L << ((s)-1))
                    717: #endif
                    718: 
                    719: sighold(sig)
                    720: {
                    721:        (void) sigblock(SigMask |= sigmask(sig));
                    722: }
                    723: 
                    724: sigrelse(sig)
                    725: {
                    726:        (void) sigsetmask(SigMask &= ~sigmask(sig));
                    727: }
                    728: 
                    729: #endif
                    730: 
                    731: #endif /* MSDOS */
                    732: 
                    733: void
                    734: FilterRegion()
                    735: {
                    736:        char    *cmd = ask((char *) 0, ": %f (through command) ", ProcFmt);
                    737: 
                    738:        RegToUnix(curbuf, cmd);
                    739: }
                    740: 
                    741: /* Send the current region to CMD and insert the output from the
                    742:    command into OUT_BUF. */
                    743: 
                    744: void
                    745: RegToUnix(outbuf, cmd)
                    746: Buffer *outbuf;
                    747: char   *cmd;
                    748: {
                    749:        Mark    *m = CurMark();
                    750: #ifndef MSDOS
                    751:        char    *tname = mktemp("/tmp/jfilterXXXXXX"),
                    752:                combuf[128];
                    753: #endif /* MSDOS */
                    754:        Window  *save_wind = curwind;
                    755:        int     status,
                    756:                error = NO;
                    757: #ifdef MSDOS
                    758:        int p0, oldi;
                    759: #endif /* MSDOS */
                    760:        File    *fp;
                    761: 
                    762: #ifndef MSDOS
                    763:        fp = open_file(tname, iobuff, F_WRITE, COMPLAIN, QUIET);
                    764: #else /* MSDOS */
                    765:        p0 = openforpipe();
                    766: #endif /* MSDOS */
                    767:     CATCH
                    768: #ifdef MSDOS
                    769:        fp = fd_open(cmd, F_WRITE, p0, iobuff, LBSIZE);
                    770: #endif /* MSDOS */
                    771:        putreg(fp, m->m_line, m->m_char, curline, curchar, YES);
                    772:        DelReg();
                    773: #ifndef MSDOS
                    774:        sprintf(combuf, "%s < %s", cmd, tname);
                    775: #else /* MSDOS */
                    776:        f_close(fp);
                    777:        p0 = reopenforpipe();
                    778:     oldi = dup(0);
                    779:        close(0);
                    780:        dup(p0);
                    781:        close(p0);
                    782: #endif /* MSDOS */
                    783:        status = UnixToBuf(outbuf->b_name, NO, 0, outbuf->b_type == B_SCRATCH,
                    784: #ifndef MSDOS
                    785:                           Shell, ShFlags, combuf, (char *) 0);
                    786: #else /* MSDOS */
                    787:                           Shell, ShFlags, cmd, (char *) 0);
                    788: #endif /* MSDOS */
                    789:     ONERROR
                    790:        error = YES;
                    791:     ENDCATCH
                    792: #ifndef MSDOS
                    793:        f_close(fp);
                    794:        (void) unlink(tname);
                    795: #else /* MSDOS */
                    796:        close(0);
                    797:        open("con", 0); /* dup(oldi);   */
                    798:        close(oldi);
                    799:        closepipe();
                    800: #endif /* MSDOS */
                    801:        SetWind(save_wind);
                    802:        if (error == NO)
                    803: #ifndef MSDOS
                    804:                com_finish(status, combuf);
                    805: #else
                    806:                com_finish(status, cmd);
                    807: #endif
                    808: }
                    809: 
                    810: void
                    811: isprocbuf(bufname)
                    812: char   *bufname;
                    813: {
                    814:        Buffer  *bp;
                    815: 
                    816:        if ((bp = buf_exists(bufname)) != 0 && bp->b_type != B_PROCESS)
                    817:                confirm("Over-write buffer %s?", bufname);
                    818: }
                    819: 
                    820: #ifdef MSDOS
                    821: /*     msdos specific hacks to allow for pipes */
                    822: 
                    823: #include <dos.h>
                    824: #include <fcntl.h>
                    825: #include <sys/types.h>
                    826: #include <sys/stat.h>
                    827: 
                    828: static char pipeiname[64];
                    829: static char pipeoname[64];
                    830: static int  pipehandle;
                    831: 
                    832: extern char TmpFilePath[];
                    833: 
                    834: private int
                    835: openforpipe()
                    836: {
                    837:    sprintf(pipeiname, "%s/%s", TmpFilePath, "Jove-I");
                    838:    sprintf(pipeoname, "%s/%s", TmpFilePath, "Jove-O");
                    839: 
                    840:    return(pipehandle = creat(pipeoname, S_IWRITE|S_IREAD));
                    841: }
                    842: 
                    843: private int
                    844: reopenforpipe()
                    845: {                     
                    846:    close(pipehandle);
                    847:    unlink(pipeiname);
                    848:    rename(pipeoname, pipeiname);
                    849:    if ((pipehandle = open(pipeiname, 0)) >= 0)
                    850:       return(pipehandle);
                    851:    closepipe();
                    852:    return(-1);
                    853: }
                    854: 
                    855: private void
                    856: closepipe()
                    857: {       
                    858:    unlink(pipeoname);
                    859:    unlink(pipeiname);
                    860: }
                    861:          
                    862: char 
                    863: switchar()
                    864: {
                    865:   union REGS regs;
                    866:   
                    867:   regs.h.ah = 0x37;
                    868:   regs.h.al = 0;   
                    869:   intdos(&regs, &regs);
                    870:   return(regs.h.dl);
                    871: }
                    872: #endif /* MSDOS */

unix.superglobalmegacorp.com

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