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

unix.superglobalmegacorp.com

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