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

unix.superglobalmegacorp.com

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