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

##### Functions

    Iprocess          X
    KillProcs         X
    PopPBs            X
    ProcB2            X
    ProcBind          X
    ProcList          X
    ProcNewline       X
    ProcSendData      X
    PushPBs           X
    SendData          X
    ShellProc         X
    free_proc         X
    kill_off          X
    pbuftiedp         X
    proc_child        X
    proc_kill         X
    proc_rec          X

##### Variables

    PBinds            X
    proc_prompt       X

##### struct's

    proc_bind         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 "re.h"
      10: #include <varargs.h>
      11:
      12: #ifdef IPROCS
      13:
      14: int proc_child();
      15:
      16: #ifdef PIPEPROCS
      17: #   include "iproc-pipes.c"
      18: #else
      19: #   include "iproc-ptys.c"
      20: #endif
      21:
      22: char    proc_prompt[128] = "% ";
      23:
      24: KillProcs()
      25: {
      26:     register Process    *p;
      27:     register int    killem = -1;        /* -1 means undetermined */
      28:     register char   *yorn;
      29:
      30:     for (p = procs; p != 0; p = p->p_next)
      31:         if (!isdead(p)) {
      32:             if (killem == -1) {
      33:                 yorn = ask("y", "Should I kill your i-processes? ");
      34:                 killem = (CharUpcase(*yorn) == 'Y');
      35:             }
      36:             if (killem)
      37:                 proc_kill(p, SIGKILL);
      38:         }
      39: }
      40:
      41: pbuftiedp(b)
      42: register Buffer *b;
      43: {
      44:     register Process    *p = b->b_process;
      45:
      46:     if (!isdead(p))
      47:         complain("Process %s, attached to %b, is %s.",
      48:              proc_cmd(p), b, pstate(p));
      49: }
      50:
      51: /* Process receive: receives the characters in buf, and appends them to
      52:    the buffer associated with p. */
      53:
      54: private
      55: proc_rec(p, buf)
      56: register Process    *p;
      57: char    *buf;
      58: {
      59:     Buffer  *saveb = curbuf;
      60:     register Window *w;
      61:     register Mark   *savepoint;
      62:     int sameplace = NO,
      63:         do_disp = NO;
      64:
      65:     if (curwind->w_bufp == p->p_buffer)
      66:         w = curwind;
      67:     else
      68:         w = windbp(p->p_buffer);    /* Is this window visible? */
      69:     if (w != 0)
      70:         do_disp = (in_window(w, p->p_mark->m_line) != -1);
      71:     SetBuf(p->p_buffer);
      72:     savepoint = MakeMark(curline, curchar, M_FLOATER);
      73:     ToMark(p->p_mark);      /* where output last stopped */
      74:     if (savepoint->m_line == curline && savepoint->m_char == curchar)
      75:         sameplace = YES;
      76:
      77:     ins_str(buf, YES);
      78:     MarkSet(p->p_mark, curline, curchar);
      79:     if (!sameplace)
      80:         ToMark(savepoint);  /* back to where we were */
      81:     DelMark(savepoint);
      82:     /* redisplay now, instead of right after the ins_str, so that
      83: 	   we don't get a bouncing effect if point is not the same as
      84: 	   the process output position */
      85:     if (do_disp) {
      86:         w->w_line = curline;
      87:         w->w_char = curchar;
      88:         redisplay();
      89:     }
      90:     SetBuf(saveb);
      91: }
      92:
      93: proc_kill(p, sig)
      94: register Process    *p;
      95: {
      96:     if (isdead(p))
      97:         return;
      98:     if (killpg(p->p_pid, sig) == -1)
      99:         s_mess("Cannot kill %s!", proc_buf(p));
     100: }
     101:
     102: /* Free process CHILD.  Do all the necessary cleaning up (closing fd's,
     103:    etc.). */
     104:
     105: free_proc(child)
     106: Process *child;
     107: {
     108:     register Process    *p,
     109:                 *prev = 0;
     110:
     111:     if (!isdead(child))
     112:         return;
     113:     for (p = procs; p != child; prev = p, p = p->p_next)
     114:         ;
     115:     if (prev == 0)
     116:         procs = child->p_next;
     117:     else
     118:         prev->p_next = child->p_next;
     119:     proc_close(child);      /* if not already closed */
     120:
     121:     /* It's possible that the buffer has been given another process
     122: 	   between the time CHILD dies and CHILD's death is noticed (via
     123: 	   list-processes).  So we only set it the buffer's process to
     124: 	   0 if CHILD is still the controlling process. */
     125:     if (child->p_buffer->b_process == child) {
     126:         child->p_buffer->b_process = 0;
     127:         if (curbuf == child->p_buffer)
     128:             PopPBs();
     129:     }
     130:     {
     131:         Buffer  *old = curbuf;
     132:
     133:         SetBuf(child->p_buffer);
     134:         DelMark(child->p_mark);
     135:         SetBuf(old);
     136:     }
     137:     free((char *) child->p_name);
     138:     free((char *) child);
     139: }
     140:
     141: ProcList()
     142: {
     143:     register Process    *p,
     144:                 *next;
     145:     char    *fmt = "%-15s  %-15s  %-8s %s",
     146:         pidstr[16];
     147:
     148:     if (procs == 0) {
     149:         message("[No subprocesses]");
     150:         return;
     151:     }
     152:     TOstart("Process list", TRUE);
     153:
     154:     Typeout(fmt, "Buffer", "Status", "Pid ", "Command");
     155:     Typeout(fmt, "------", "------", "--- ", "-------");
     156:     for (p = procs; p != 0; p = next) {
     157:         next = p->p_next;
     158:         sprintf(pidstr, "%d", p->p_pid);
     159:         Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name);
     160:         if (isdead(p)) {
     161:             free_proc(p);
     162:             UpdModLine = YES;
     163:         }
     164:     }
     165:     TOstop();
     166: }
     167:
     168: ProcNewline()
     169: {
     170: #ifdef ABBREV
     171:     MaybeAbbrevExpand();
     172: #endif
     173:     SendData(YES);
     174: }
     175:
     176: ProcSendData()
     177: {
     178: #ifdef ABBREV
     179:     MaybeAbbrevExpand();
     180: #endif
     181:     SendData(NO);
     182: }
     183:
     184: private
     185: SendData(newlinep)
     186: {
     187:     register Process    *p = curbuf->b_process;
     188:     register char   *lp,
     189:             *gp;    /* JF fix for better prompt handling */
     190:
     191:     if (isdead(p))
     192:         return;
     193:     /* If the process mark was involved in a big deletion, because
     194: 	   the user hit ^W or something, then let's do some magic with
     195: 	   the process mark.  Problem is that if the user yanks back the
     196: 	   text he deleted, the mark stays at the beginning of the region,
     197: 	   and so the next time SendData() is called the entire region
     198: 	   will be sent.  That's not good.  So, to deal with that we reset
     199: 	   the mark to the last line, after skipping over the prompt, etc. */
     200:     if (p->p_mark->m_flags & M_BIG_DELETE) {
     201:         Bufpos  bp;
     202:
     203:         p->p_mark->m_flags &= ~M_BIG_DELETE;
     204:
     205:         DOTsave(&bp);
     206:         ToLast();
     207:         Bol();
     208:         /* While we're looking at a prompt, and while we're
     209: 		   moving forward.  This is for people who accidently
     210: 		   set their process-prompt to ">*" which will always
     211: 		   match! */
     212:         while ((LookingAt(proc_prompt, linebuf, curchar)) &&
     213:                (REeom > curchar))
     214:             curchar = REeom;
     215:         MarkSet(p->p_mark, curline, curchar);
     216:         SetDot(&bp);
     217:     }
     218:
     219:     if (lastp(curline)) {
     220:         Eol();
     221:         if (newlinep)
     222:             LineInsert(1);
     223:         do_rtp(p->p_mark);
     224:         MarkSet(p->p_mark, curline, curchar);
     225:     } else {
     226:         /* Either we're looking at a prompt, or we're not, in
     227: 		   which case we want to strip off the beginning of the
     228: 		   line anything that looks like what the prompt at the
     229: 		   end of the file is.  In other words, if "(dbx) stop in
     230: 		   ProcessNewline" is the line we're on, and the last
     231: 		   line in the buffer is "(dbx) ", then we strip off the
     232: 		   leading "(dbx) " from this line, because we know it's
     233: 		   part of the prompt.  But this only happens if "(dbx) "
     234: 		   isn't one of the process prompts ... follow what I'm
     235: 		   saying? */
     236:         Bol();
     237:         if (LookingAt(proc_prompt, linebuf, curchar)) {
     238:             do
     239:                 curchar = REeom;
     240:             while ((LookingAt(proc_prompt, linebuf, curchar)) &&
     241:                    (REeom > curchar));
     242:             strcpy(genbuf, linebuf + curchar);
     243:             Eof();
     244:             ins_str(genbuf, NO);
     245:         } else {
     246:             strcpy(genbuf, linebuf + curchar);
     247:             Eof();
     248:             gp = genbuf;
     249:             lp = linebuf;
     250:             while (*lp == *gp && *lp != '\0') {
     251:                 lp += 1;
     252:                 gp += 1;
     253:             }
     254:             ins_str(gp, NO);
     255:         }
     256:     }
     257: }
     258:
     259: ShellProc()
     260: {
     261:     char    *shbuf = "*shell*";
     262:     register Buffer *b;
     263:
     264:     b = buf_exists(shbuf);
     265:     if (b == 0 || isdead(b->b_process))
     266:         proc_strt(shbuf, NO, Shell, "-i", (char *) 0);
     267:     pop_wind(shbuf, NO, -1);
     268: }
     269:
     270: Iprocess()
     271: {
     272:     extern char ShcomBuf[100],
     273:             *MakeName();
     274:     register char   *command;
     275:     char    scratch[64],
     276:         *bufname;
     277:     int cnt = 1;
     278:     Buffer  *bp;
     279:
     280:     command = ask(ShcomBuf, ProcFmt);
     281:     null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1);
     282:     bufname = MakeName(command);
     283:     strcpy(scratch, bufname);
     284:     while ((bp = buf_exists(scratch)) && !isdead(bp->b_process))
     285:         sprintf(scratch, "%s.%d", bufname, cnt++);
     286:     proc_strt(scratch, YES, Shell, ShFlags, command, (char *) 0);
     287: }
     288:
     289: proc_child()
     290: {
     291:     union wait  w;
     292:     register int    pid;
     293:
     294:     for (;;) {
     295: #ifndef BSD4_2
     296:         pid = wait2(&w.w_status, (WNOHANG | WUNTRACED));
     297: #else
     298:         pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0);
     299: #endif
     300:         if (pid <= 0)
     301:             break;
     302:         kill_off(pid, w);
     303:     }
     304: }
     305:
     306: kill_off(pid, w)
     307: register int    pid;
     308: union wait  w;
     309: {
     310:     register Process    *child;
     311:
     312:     if ((child = proc_pid(pid)) == 0)
     313:         return;
     314:
     315:     UpdModLine = YES;       /* we're changing state ... */
     316:     if (WIFSTOPPED(w))
     317:         child->p_state = STOPPED;
     318:     else {
     319:         child->p_state = DEAD;
     320:         if (WIFEXITED(w))
     321:             child->p_howdied = EXITED;
     322:         else if (WIFSIGNALED(w)) {
     323:             child->p_reason = w.w_termsig;
     324:             child->p_howdied = KILLED;
     325:         }
     326:         {
     327:             Buffer  *save = curbuf;
     328:             char    mesg[128];
     329:
     330:             /* insert status message now */
     331:             sprintf(mesg, "[Process %s: %s]\n",
     332:                 proc_cmd(child),
     333:                 pstate(child));
     334:             SetBuf(child->p_buffer);
     335:             ins_str(mesg, NO);
     336:             SetBuf(save);
     337:             redisplay();
     338:         }
     339:     }
     340: }
     341:
     342: /* Push/pod process bindings.  I openly acknowledge that this is a
     343:    kludge, but I can't be bothered making it right. */
     344:
     345: struct proc_bind {
     346:     int     pb_key;
     347:     data_obj    **pb_map;
     348:     data_obj    *pb_push;
     349:     data_obj    *pb_cmd;
     350:     struct proc_bind *pb_next;
     351: };
     352:
     353: struct proc_bind *PBinds = 0;
     354:
     355: PopPBs()
     356: {
     357:     register struct proc_bind *p;
     358:
     359:     for (p = PBinds; p != 0; p = p->pb_next)
     360:         p->pb_map[p->pb_key] = p->pb_push;
     361: }
     362:
     363: PushPBs()
     364: {
     365:     register struct proc_bind *p;
     366:
     367:     for (p = PBinds; p != 0; p = p->pb_next) {
     368:         p->pb_push = p->pb_map[p->pb_key];
     369:         p->pb_map[p->pb_key] = p->pb_cmd;
     370:     }
     371: }
     372: /* VARARGS0 */
     373:
     374: ProcBind()
     375: {
     376:     register data_obj   *d;
     377:
     378:     if ((d = findcom(ProcFmt)) == 0)
     379:         return;
     380:     s_mess(": %f %s ", d->Name);
     381:     ProcB2(mainmap, EOF, d);
     382: }
     383:
     384: ProcB2(map, lastkey, cmd)
     385: data_obj    **map,
     386:         *cmd;
     387: {
     388:     register struct proc_bind *p;
     389:     register data_obj   **nextmap;
     390:     int c;
     391:
     392:     c = addgetc();
     393:     if (c == EOF) {
     394:         if (lastkey == EOF)
     395:             complain("[Empty key sequence]");
     396:         complain("[Unexpected end-of-line]");
     397:     } else {
     398:         if (nextmap = IsPrefix(map[c]))
     399:             ProcB2(nextmap, c, cmd);
     400:         else {
     401:             if (curbuf->b_process)
     402:                 PopPBs();
     403:
     404:             for (p = PBinds; p != 0; p = p->pb_next)
     405:                 if (p->pb_key == c && p->pb_map == map)
     406:                     break;
     407:             if (p == 0) {
     408:                 p = (struct proc_bind *) emalloc(sizeof *p);
     409:                 p->pb_next = PBinds;
     410:                 PBinds = p;
     411:             }
     412:             p->pb_map = map;
     413:             p->pb_key = c;
     414:             p->pb_cmd = cmd;
     415:
     416:             if (curbuf->b_process)
     417:                 PushPBs();
     418:         }
     419:     }
     420: }
     421:
     422: #endif /* IPROCS */

#### Defined functions

Iprocess defined in line 270; used 2 times

- in /usr/src/new/jove/funcdefs.c line 232, 419

KillProcs defined in line 24; used 1 times

- in /usr/src/new/jove/jove.c line 981

PopPBs defined in line 355; used 3 times

- in line 128, 402
- in /usr/src/new/jove/buf.c line 706

ProcB2 defined in line 384; used 2 times

- in line 381, 399

ProcBind defined in line 374; used 2 times

- in /usr/src/new/jove/funcdefs.c line 231, 484

ProcList defined in line 141; used 2 times

- in /usr/src/new/jove/funcdefs.c line 230, 438

ProcNewline defined in line 168; used 2 times

- in /usr/src/new/jove/funcdefs.c line 229, 485

ProcSendData defined in line 176; used 2 times

- in /usr/src/new/jove/funcdefs.c line 228, 486

PushPBs defined in line 363; used 2 times

- in line 417
- in /usr/src/new/jove/buf.c line 704

SendData defined in line 184; used 2 times

- in line 173, 181

ShellProc defined in line 259; used 2 times

- in /usr/src/new/jove/funcdefs.c line 218, 539

free_proc defined in line 105; used 1 times

- in line 161

kill_off defined in line 306; used 2 times

- in line 302
- in /usr/src/new/jove/proc.c line 515

pbuftiedp defined in line 41; used 1 times

- in /usr/src/new/jove/buf.c line 317

proc_child defined in line 289; used 1 times

- in line 14

proc_kill defined in line 93; used 6 times

- in line 37
- in /usr/src/new/jove/iproc-pipes.c line 143-153(3)
- in /usr/src/new/jove/iproc-ptys.c line 140, 150

proc_rec defined in line 54; used 3 times

- in /usr/src/new/jove/iproc-pipes.c line 137
- in /usr/src/new/jove/iproc-ptys.c line 125, 191

#### Defined variables

PBinds defined in line 353; used 5 times

- in line 359, 367, 404-410(3)

proc_prompt defined in line 22; used 4 times

- in line 212, 237-240(2)
- in /usr/src/new/jove/vars.c line 74

#### Defined struct's

proc_bind defined in line 345; used 12 times

- in line 350-357(6), 365(2), 388(2), 408(2)

Last modified: 1988-03-15 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1427 |