# 2.11BSD#431 - /usr/src/new/jove/proc.c

##### Functions

    AddError          X
    DoShell           X
    ErrFree           X
    ErrParse          X
    FilterRegion      X
    MakeErrors        X
    MakeName          X
    NextError         X
    PrevError         X
    RegToUnix         X
    ShNoBuf           X
    ShToBuf           X
    ShellCom          X
    ShowErr           X
    Shtypeout         X
    SpelBuffer        X
    SpelParse         X
    SpelWords         X
    ToError           X
    UnixToBuf         X
    closepipe         X
    com_finish        X
    dowait            X
    isprocbuf         X
    okay_error        X
    openforpipe       X
    reopenforpipe     X
    set_wsize         X
    switchar          X
    toerror           X

##### Variables

    EWSize            X
    ErrFmtStr         X
    ShcomBuf          X
    SigMask           X
    WtOnMk            X
    cur_error         X
    errbounds         X
    make_cmd          X
    perr_buf          X
    private           X

##### struct's

    error             X

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

#### Defined functions

AddError defined in line 78; used 4 times

- in line 34, 48, 146, 397

DoShell defined in line 454; used 4 times

- in line 23, 37, 418, 425

ErrFree defined in line 155; used 6 times

- in line 92, 125, 382
- in /usr/src/new/jove/buf.c line 339
- in /usr/src/new/jove/externs.h line 278, 886

ErrParse defined in line 110; used 4 times

- in line 335
- in /usr/src/new/jove/externs.h line 279, 887
- in /usr/src/new/jove/jove.c line 814

FilterRegion defined in line 725; used 4 times

- in /usr/src/new/jove/externs.h line 290, 898
- in /usr/src/new/jove/funcdefs.c line 214, 393

MakeErrors defined in line 307; used 4 times

- in /usr/src/new/jove/externs.h line 323, 931
- in /usr/src/new/jove/funcdefs.c line 67, 316

MakeName defined in line 283; used 6 times

- in line 332, 425
- in /usr/src/new/jove/externs.h line 32, 639
- in /usr/src/new/jove/iproc.c line 273, 282

NextError defined in line 189; used 4 times

- in /usr/src/new/jove/externs.h line 328, 936
- in /usr/src/new/jove/funcdefs.c line 139, 447

PrevError defined in line 195; used 4 times

- in /usr/src/new/jove/externs.h line 343, 951
- in /usr/src/new/jove/funcdefs.c line 146, 477

RegToUnix defined in line 736; used 3 times

- in line 730
- in /usr/src/new/jove/externs.h line 361, 969

ShNoBuf defined in line 428; used 2 times

- in /usr/src/new/jove/funcdefs.c line 190, 543

ShToBuf defined in line 410; used 4 times

- in /usr/src/new/jove/externs.h line 382, 990
- in /usr/src/new/jove/funcdefs.c line 192, 544

ShellCom defined in line 421; used 4 times

- in /usr/src/new/jove/externs.h line 383, 991
- in /usr/src/new/jove/funcdefs.c line 189, 542

ShowErr defined in line 237; used 7 times

- in line 150, 218, 405
- in /usr/src/new/jove/externs.h line 384, 992
- in /usr/src/new/jove/funcdefs.c line 138, 327

Shtypeout defined in line 437; used 2 times

- in /usr/src/new/jove/funcdefs.c line 191, 545

SpelBuffer defined in line 343; used 2 times

- in /usr/src/new/jove/funcdefs.c line 197, 551

SpelParse defined in line 372; used 2 times

- in line 357, 369

SpelWords defined in line 360; used 2 times

- in /usr/src/new/jove/funcdefs.c line 160, 460

ToError defined in line 212; used 4 times

- in line 192, 198
- in /usr/src/new/jove/externs.h line 396, 1004

UnixToBuf defined in line 529; used 9 times

- in line 332, 352, 433, 442, 462, 775
- in /usr/src/new/jove/externs.h line 62, 669
- in /usr/src/new/jove/io.c line 345

closepipe defined in line 847; used 5 times

- in line 26, 40, 709, 791, 843

com_finish defined in line 468; used 7 times

- in line 24, 38, 333, 434, 464, 796-798(2)

dowait defined in line 482; used 3 times

- in line 704
- in /usr/src/new/jove/extend.c line 969
- in /usr/src/new/jove/jove.c line 442

isprocbuf defined in line 802; used 5 times

- in line 555
- in /usr/src/new/jove/externs.h line 484, 1092
- in /usr/src/new/jove/iproc-pipes.c line 216
- in /usr/src/new/jove/iproc-ptys.c line 279

okay_error defined in line 201; used 4 times

- in line 29, 44, 217, 245

openforpipe defined in line 826; used 4 times

- in line 30, 43, 640, 757

reopenforpipe defined in line 835; used 4 times

- in line 31, 45, 651, 769

set_wsize defined in line 224; used 4 times

- in line 271, 565
- in /usr/src/new/jove/externs.h line 532, 1138

switchar defined in line 854; used 3 times

- in /usr/src/new/jove/externs.h line 51, 658
- in /usr/src/new/jove/jove.c line 1190

toerror defined in line 171; used 3 times

- in line 25, 39, 216

#### Defined variables

EWSize defined in line 221; used 7 times

- in line 271, 332, 352
- in /usr/src/new/jove/proc.c line 271, 332, 352
- in /usr/src/new/jove/vars.c line 40

ErrFmtStr defined in line 56; used 3 times

- in line 128
- in /usr/src/new/jove/proc.c line 128
- in /usr/src/new/jove/vars.c line 39

ShcomBuf defined in line 278; used 17 times

- in line 417, 424-425(5), 432-434(5), 441-446(6)

SigMask defined in line 51; used 3 times

- in line 613
- in /usr/src/new/jove/tune.h line 206-207(2)

WtOnMk defined in line 73; used 3 times

- in line 314
- in /usr/src/new/jove/proc.c line 314
- in /usr/src/new/jove/vars.c line 102

cur_error defined in line 69; used 17 times

- in line 93, 149, 162, 174, 185, 204-205(3), 243, 250-254(2), 263, 269-275(4), 337

errbounds defined in line 168; used 1 times

- in line 180

make_cmd defined in line 305; used 9 times

- in line 323-333(9)

perr_buf defined in line 71; used 6 times

- in line 127, 204, 249, 258-261(2), 386

pipehandle defined in line 822; used 4 times

- in line 832, 838-842(3)

pipeiname defined in line 820; used 5 times

- in line 829, 839-841(3), 851

pipeoname defined in line 821; used 4 times

- in line 830-832(2), 840, 850

private defined in line 847; never used

#### Defined struct's

error defined in line 60; used 23 times

- in line 33-34(2), 47, 65-69(4), 78-85(8), 120(2), 158(2), 174(2), 380(2)

Last modified: 1988-08-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2191 |