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