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