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
KillProcs defined in line 24; used 1 times
PopPBs defined in line 355; used 3 times
ProcB2 defined in line 384; used 2 times
ProcBind defined in line 374; used 2 times
ProcList defined in line 141; used 2 times
ProcNewline defined in line 168; used 2 times
ProcSendData defined in line 176; used 2 times
PushPBs defined in line 363; used 2 times
SendData defined in line 184; used 2 times
ShellProc defined in line 259; used 2 times
free_proc defined in line 105; used 1 times
kill_off defined in line 306; used 2 times
pbuftiedp defined in line 41; used 1 times
proc_child defined in line 289; used 1 times
  • in line 14
proc_kill defined in line 93; used 6 times
proc_rec defined in line 54; used 3 times

Defined variables

PBinds defined in line 353; used 5 times
proc_prompt defined in line 22; used 4 times

Defined struct's

proc_bind defined in line 345; used 12 times
Last modified: 1988-03-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3574
Valid CSS Valid XHTML 1.0 Strict