|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 6421 (0x1915) Types: TextFile Names: »iproc.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec1/jove/iproc.c«
/************************************************************************ * This program is Copyright (C) 1986 by Jonathan Payne. JOVE is * * provided to you without charge, and with no warranty. You may give * * away copies of JOVE, including sources, provided that this notice is * * included in all the files. * ************************************************************************/ #include "jove.h" #include <varargs.h> #ifdef IPROCS int proc_child(); #ifdef PIPEPROCS # include "iproc-pipes.c" #else # include "iproc-ptys.c" #endif char proc_prompt[80] = "% "; KillProcs() { register Process *p; register int killem = -1; /* -1 means undetermined */ register char *yorn; for (p = procs; p != 0; p = p->p_next) if (!isdead(p)) { if (killem == -1) { yorn = ask("y", "Should I kill your i-processes? "); killem = (Upper(*yorn) == 'Y'); } if (killem) proc_kill(p, SIGKILL); } } pbuftiedp(b) register Buffer *b; { register Process *p = b->b_process; if (!isdead(p)) complain("Process %s, attached to %b, is %s.", proc_cmd(p), b, pstate(p)); } /* Process receive: receives the characters in buf, and appends them to the buffer associated with p. */ static proc_rec(p, buf) register Process *p; char *buf; { Buffer *saveb = curbuf; register Window *w; register Mark *savepoint; int sameplace = 0, do_disp = 0; if (curwind->w_bufp == p->p_buffer) w = curwind; else w = windbp(p->p_buffer); /* Is this window visible? */ if (w != 0) do_disp = (in_window(w, p->p_mark->m_line) != -1); SetBuf(p->p_buffer); savepoint = MakeMark(curline, curchar, FLOATER); ToMark(p->p_mark); /* Where output last stopped. */ if (savepoint->m_line == curline && savepoint->m_char == curchar) sameplace++; ins_str(buf, YES); if (do_disp) { w->w_line = curline; w->w_char = curchar; redisplay(); } MarkSet(p->p_mark, curline, curchar); if (!sameplace) ToMark(savepoint); /* Back to where we were. */ DelMark(savepoint); SetBuf(saveb); } proc_kill(p, sig) register Process *p; { if (isdead(p)) return; if (killpg(p->p_pid, sig) == -1) s_mess("Cannot kill %s!", proc_buf(p)); } /* Deal with a process' death. proc_rec turns on the FREEUP bit when it it gets the "EOF" from portsrv. FREEUP'd processes get unlinked from the list, and the proc stucture and proc_buf(p) get free'd up, here. */ private DealWDeath() { register Process *p, *next, *prev = 0; for (p = procs; p != 0; p = next) { next = p->p_next; if (!p->p_eof) { prev = p; continue; } proc_close(p); PopPBs(); /* not a process anymore */ p->p_buffer->b_process = 0; /* we're killing ourself */ free((char *) p->p_name); free((char *) p); if (prev) prev->p_next = next; else procs = next; } } ProcList() { register Process *p; char *fmt = "%-15s %-15s %-8s %s", pidstr[10]; if (procs == 0) { message("[No subprocesses]"); return; } TOstart("Process list", TRUE); Typeout(fmt, "Buffer", "Status", "Pid ", "Command"); Typeout(fmt, "------", "------", "--- ", "-------"); for (p = procs; p != 0; p = p->p_next) { sprintf(pidstr, "%d", p->p_pid); Typeout(fmt, proc_buf(p), pstate(p), pidstr, p->p_name); } DealWDeath(); TOstop(); } ProcNewline() { SendData(YES); } ProcSendData() { SendData(NO); } private SendData(newlinep) { register Process *p = curbuf->b_process; if (isdead(p)) return; if (lastp(curline)) { Eol(); if (newlinep) LineInsert(1); do_rtp(p->p_mark); MarkSet(p->p_mark, curline, curchar); } else { Bol(); while (LookingAt(proc_prompt, linebuf, curchar)) SetDot(dosearch(proc_prompt, 1, 1)); strcpy(genbuf, linebuf + curchar); ToLast(); ins_str(genbuf, NO); } } ShellProc() { char *shbuf = "*shell*"; register Buffer *b; b = buf_exists(shbuf); if (b == 0 || isdead(b->b_process)) proc_strt(shbuf, NO, Shell, "-i", (char *) 0); pop_wind(shbuf, NO, -1); } Iprocess() { extern char ShcomBuf[100], *MakeName(); register char *command; command = ask(ShcomBuf, ProcFmt); null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1); proc_strt(MakeName(command), YES, Shell, ShFlags, command, (char *) 0); } proc_child() { union wait w; register int pid; for (;;) { #ifndef VMUNIX pid = wait2(&w.w_status, (WNOHANG | WUNTRACED)); #else pid = wait3(&w, (WNOHANG | WUNTRACED), (struct rusage *) 0); #endif if (pid <= 0) break; kill_off(pid, w); } } kill_off(pid, w) register int pid; union wait w; { char str[128]; register Process *child; if ((child = proc_pid(pid)) == 0) return; if (WIFSTOPPED(w)) child->p_state = STOPPED; else { child->p_state = DEAD; if (WIFEXITED(w)) child->p_howdied = EXITED; else if (WIFSIGNALED(w)) { child->p_reason = w.w_termsig; child->p_howdied = KILLED; } proc_close(child); } sprintf(str, "[Process %s: %s]\n", proc_cmd(child), pstate(child)); proc_rec(child, str); } /* Push/pod process bindings. I openly acknowledge that this is a kludge, but I can't be bothered making it right. */ struct proc_bind { int pb_key; data_obj **pb_map; data_obj *pb_push; data_obj *pb_cmd; struct proc_bind *pb_next; }; struct proc_bind *PBinds = 0; PopPBs() { register struct proc_bind *p; for (p = PBinds; p != 0; p = p->pb_next) p->pb_map[p->pb_key] = p->pb_push; } PushPBs() { register struct proc_bind *p; for (p = PBinds; p != 0; p = p->pb_next) { p->pb_push = p->pb_map[p->pb_key]; p->pb_map[p->pb_key] = p->pb_cmd; } } /* VARARGS0 */ ProcBind() { register data_obj *d; if ((d = findcom(ProcFmt)) == 0) return; s_mess(": %f %s ", d->Name); ProcB2(mainmap, EOF, d); } ProcB2(map, lastkey, cmd) data_obj **map, *cmd; { register struct proc_bind *p; register data_obj **nextmap; int c; c = addgetc(); if (c == EOF) { if (lastkey == EOF) complain("[Empty key sequence]"); complain("[Unexpected end-of-line]"); } else { if (nextmap = IsPrefix(map[c])) ProcB2(nextmap, c, cmd); else { if (curbuf->b_process) PopPBs(); for (p = PBinds; p != 0; p = p->pb_next) if (p->pb_key == c && p->pb_map == map) break; if (p == 0) { p = (struct proc_bind *) emalloc(sizeof *p); p->pb_next = PBinds; PBinds = p; } p->pb_map = map; p->pb_key = c; p->pb_cmd = cmd; if (curbuf->b_process) PushPBs(); } } } #endif IPROCS