home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume8 / jove / part04 / iproc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-02-02  |  6.3 KB  |  330 lines

  1. /************************************************************************
  2.  * This program is Copyright (C) 1986 by Jonathan Payne.  JOVE is       *
  3.  * 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 <varargs.h>
  10.  
  11. #ifdef IPROCS
  12.  
  13. int    proc_child();
  14.  
  15. #ifdef PIPEPROCS
  16. #   include "iproc-pipes.c"
  17. #else
  18. #   include "iproc-ptys.c"
  19. #endif
  20.  
  21. char    proc_prompt[80] = "% ";
  22.  
  23. KillProcs()
  24. {
  25.     register Process    *p;
  26.     register int    killem = -1;        /* -1 means undetermined */
  27.     register char    *yorn;
  28.  
  29.     for (p = procs; p != 0; p = p->p_next)
  30.         if (!isdead(p)) {
  31.             if (killem == -1) {
  32.                 yorn = ask("y", "Should I kill your i-processes? ");
  33.                 killem = (Upper(*yorn) == 'Y');
  34.             }
  35.             if (killem)
  36.                 proc_kill(p, SIGKILL);
  37.         }
  38. }
  39.  
  40. pbuftiedp(b)
  41. register Buffer    *b;
  42. {
  43.     register Process    *p = b->b_process;
  44.  
  45.     if (!isdead(p))
  46.         complain("Process %s, attached to %b, is %s.",
  47.              proc_cmd(p), b, pstate(p));
  48. }
  49.  
  50. /* Process receive: receives the characters in buf, and appends them to
  51.    the buffer associated with p. */
  52.  
  53. static
  54. proc_rec(p, buf)
  55. register Process    *p;
  56. char    *buf;
  57. {
  58.     Buffer    *saveb = curbuf;
  59.     register Window    *w;
  60.     register Mark    *savepoint;
  61.     int    sameplace = 0,
  62.         do_disp = 0;
  63.  
  64.     if (curwind->w_bufp == p->p_buffer)
  65.         w = curwind;
  66.     else
  67.         w = windbp(p->p_buffer);    /* Is this window visible? */
  68.     if (w != 0)
  69.         do_disp = (in_window(w, p->p_mark->m_line) != -1);
  70.     SetBuf(p->p_buffer);
  71.     savepoint = MakeMark(curline, curchar, FLOATER);
  72.     ToMark(p->p_mark);    /* Where output last stopped. */
  73.     if (savepoint->m_line == curline && savepoint->m_char == curchar)
  74.         sameplace++;
  75.  
  76.     ins_str(buf, YES);
  77.     if (do_disp) {
  78.         w->w_line = curline;
  79.         w->w_char = curchar;
  80.         redisplay();
  81.     }
  82.     MarkSet(p->p_mark, curline, curchar);
  83.     if (!sameplace)
  84.         ToMark(savepoint);    /* Back to where we were. */
  85.     DelMark(savepoint);
  86.     SetBuf(saveb);
  87. }
  88.  
  89. proc_kill(p, sig)
  90. register Process    *p;
  91. {
  92.     if (isdead(p))
  93.         return;
  94.     if (killpg(p->p_pid, sig) == -1)
  95.         s_mess("Cannot kill %s!", proc_buf(p));
  96. }
  97.  
  98. /* Deal with a process' death.  proc_rec turns on the FREEUP bit when it
  99.    it gets the "EOF" from portsrv.  FREEUP'd processes get unlinked from
  100.    the list, and the proc stucture and proc_buf(p) get free'd up, here. */
  101.  
  102. private
  103. DealWDeath()
  104. {
  105.     register Process    *p,
  106.                 *next,
  107.                 *prev = 0;
  108.     
  109.     for (p = procs; p != 0; p = next) {
  110.         next = p->p_next;
  111.         if (!p->p_eof) {
  112.             prev = p;
  113.             continue;
  114.         }
  115.         proc_close(p);
  116.         PopPBs();            /* not a process anymore */
  117.         p->p_buffer->b_process = 0;    /* we're killing ourself */
  118.         free((char *) p->p_name);
  119.         free((char *) p);
  120.         if (prev)
  121.             prev->p_next = next;
  122.         else
  123.             procs = next;
  124.     }
  125. }
  126.  
  127. ProcList()
  128. {
  129.     register Process    *p;
  130.     char    *fmt = "%-15s  %-15s  %-8s %s",
  131.         pidstr[10];
  132.  
  133.     if (procs == 0) {
  134.         message("[No subprocesses]");
  135.         return;
  136.     }
  137.     TOstart("Process list", TRUE);
  138.  
  139.     Typeout(fmt, "Buffer", "Status", "Pid ", "Command");
  140.     Typeout(fmt, "------", "------", "--- ", "-------");
  141.     for (p = procs; p != 0; p = p->p_next) {
  142.         sprintf(pidstr, "%d", p->p_pid);
  143.         Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name);
  144.     }
  145.     DealWDeath();
  146.     TOstop();
  147. }
  148.  
  149. ProcNewline()
  150. {
  151.     SendData(YES);
  152. }
  153.  
  154. ProcSendData()
  155. {
  156.     SendData(NO);
  157. }
  158.  
  159. private
  160. SendData(newlinep)
  161. {
  162.     register Process    *p = curbuf->b_process;
  163.  
  164.     if (isdead(p))
  165.         return;
  166.     if (lastp(curline)) {
  167.         Eol();
  168.         if (newlinep)
  169.             LineInsert(1);
  170.         do_rtp(p->p_mark);
  171.         MarkSet(p->p_mark, curline, curchar);
  172.     } else {
  173.         Bol();
  174.         while (LookingAt(proc_prompt, linebuf, curchar))
  175.             SetDot(dosearch(proc_prompt, 1, 1));
  176.         strcpy(genbuf, linebuf + curchar);
  177.         ToLast();
  178.         ins_str(genbuf, NO);
  179.     }
  180. }
  181.  
  182. ShellProc()
  183. {
  184.     char    *shbuf = "*shell*";
  185.     register Buffer    *b;
  186.  
  187.     b = buf_exists(shbuf);
  188.     if (b == 0 || isdead(b->b_process))
  189.         proc_strt(shbuf, NO, Shell, "-i", (char *) 0);
  190.     pop_wind(shbuf, NO, -1);
  191. }
  192.  
  193. Iprocess()
  194. {
  195.     extern char    ShcomBuf[100],
  196.             *MakeName();
  197.     register char    *command;
  198.  
  199.     command = ask(ShcomBuf, ProcFmt);
  200.     null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1);
  201.     proc_strt(MakeName(command), YES, Shell, ShFlags, command, (char *) 0);
  202. }
  203.  
  204. proc_child()
  205. {
  206.     union wait    w;
  207.     register int    pid;
  208.  
  209.     for (;;) {
  210. #ifndef VMUNIX
  211.         pid = wait2(&w.w_status, (WNOHANG | WUNTRACED));
  212. #else
  213.         pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0);
  214. #endif
  215.         if (pid <= 0)
  216.             break;
  217.         kill_off(pid, w);
  218.     }
  219. }
  220.  
  221. kill_off(pid, w)
  222. register int    pid;
  223. union wait    w;
  224. {
  225.     char    str[128];
  226.     register Process    *child;
  227.  
  228.     if ((child = proc_pid(pid)) == 0)
  229.         return;
  230.  
  231.     if (WIFSTOPPED(w))
  232.         child->p_state = STOPPED;
  233.     else {
  234.         child->p_state = DEAD;
  235.         if (WIFEXITED(w))
  236.             child->p_howdied = EXITED;
  237.         else if (WIFSIGNALED(w)) {
  238.             child->p_reason = w.w_termsig;
  239.             child->p_howdied = KILLED;
  240.         }
  241.         proc_close(child);
  242.     }
  243.     sprintf(str, "[Process %s: %s]\n",
  244.         proc_cmd(child),
  245.         pstate(child));
  246.     proc_rec(child, str);
  247. }
  248.  
  249. /* Push/pod process bindings.  I openly acknowledge that this is a
  250.    kludge, but I can't be bothered making it right. */
  251.  
  252. struct proc_bind {
  253.     int        pb_key;
  254.     data_obj    **pb_map;
  255.     data_obj    *pb_push;
  256.     data_obj    *pb_cmd;
  257.     struct proc_bind *pb_next;
  258. };
  259.  
  260. struct proc_bind *PBinds = 0;
  261.  
  262. PopPBs()
  263. {
  264.     register struct proc_bind *p;
  265.  
  266.     for (p = PBinds; p != 0; p = p->pb_next)
  267.         p->pb_map[p->pb_key] = p->pb_push;
  268. }
  269.  
  270. PushPBs()
  271. {
  272.     register struct proc_bind *p;
  273.  
  274.     for (p = PBinds; p != 0; p = p->pb_next) {
  275.         p->pb_push = p->pb_map[p->pb_key];
  276.         p->pb_map[p->pb_key] = p->pb_cmd;
  277.     }
  278. }
  279. /* VARARGS0 */
  280.  
  281. ProcBind()
  282. {
  283.     register data_obj    *d;
  284.  
  285.     if ((d = findcom(ProcFmt)) == 0)
  286.         return;
  287.     s_mess(": %f %s ", d->Name);
  288.     ProcB2(mainmap, EOF, d);
  289. }
  290.  
  291. ProcB2(map, lastkey, cmd)
  292. data_obj    **map,
  293.         *cmd;
  294. {
  295.     register struct proc_bind *p;
  296.     register data_obj    **nextmap;
  297.     int    c;
  298.  
  299.     c = addgetc();
  300.     if (c == EOF) {
  301.         if (lastkey == EOF)
  302.             complain("[Empty key sequence]");
  303.         complain("[Unexpected end-of-line]");
  304.     } else {
  305.         if (nextmap = IsPrefix(map[c]))
  306.             ProcB2(nextmap, c, cmd);
  307.         else {
  308.             if (curbuf->b_process)
  309.                 PopPBs();
  310.  
  311.             for (p = PBinds; p != 0; p = p->pb_next)
  312.                 if (p->pb_key == c && p->pb_map == map)
  313.                     break;
  314.             if (p == 0) {
  315.                 p = (struct proc_bind *) emalloc(sizeof *p);
  316.                 p->pb_next = PBinds;
  317.                 PBinds = p;
  318.             }
  319.             p->pb_map = map;
  320.             p->pb_key = c;
  321.             p->pb_cmd = cmd;
  322.  
  323.             if (curbuf->b_process)
  324.                 PushPBs();
  325.         }
  326.     }
  327. }
  328.  
  329. #endif IPROCS
  330.