BSD 4_3 development
[unix-history] / usr / contrib / jove / iproc.c
/*************************************************************************
* This program is copyright (C) 1985, 1986 by Jonathan Payne. It is *
* provided to you without charge for use only on a licensed Unix *
* system. You may copy JOVE provided that this notice is included with *
* the copy. You may not sell copies of this program or versions *
* modified for use on microcomputer systems, unless the copies are *
* included with a Unix system distribution and the source is provided. *
*************************************************************************/
#include "jove.h"
#ifdef IPROCS
int proc_child();
#ifdef PIPEPROCS
# include "iproc-pipes.c"
#else
# include "iproc-ptys.c"
#endif
KillProcs()
{
register Process *p;
int killem = -1; /* -1 means undetermined */
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);
}
}
static Process *
proc_exists(name)
char *name;
{
register Process *p;
for (p = procs; p != 0; p = p->p_next)
if (strcmp(proc_buf(p), name) == 0) {
(void) pstate(p);
if (p->p_eof) {
DealWDeath();
return 0;
}
break;
}
return p;
}
assign_p()
{
register Process *p;
for (p = procs; p != 0; p = p->p_next)
if (p->p_buffer == curbuf) {
cur_proc = p;
break;
}
}
pbuftiedp(b)
Buffer *b;
{
register Process *p;
for (p = procs; p != 0; p = p->p_next)
if (p->p_buffer == b && !p->p_eof)
complain("[There is a process tied to %s]", proc_buf(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;
Window *w;
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)
Process *p;
{
if (p == 0 || p->p_state == DEAD)
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. */
static
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;
}
if (cur_proc == p)
cur_proc = next ? next : prev;
proc_close(p);
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()
{
if (isdead(cur_proc))
return;
if (lastp(curline)) {
Eol();
LineInsert();
do_rtp(cur_proc->p_mark);
MarkSet(cur_proc->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);
}
}
IShell()
{
char shell[30];
int number = 1;
do
sprintf(shell, "shell-%d", number++);
while (proc_exists(shell));
proc_strt(shell, "i-shell", Shell, basename(Shell), "-i", 0);
SetWind(windlook(shell));
}
Iprocess()
{
extern char ShcomBuf[100],
*MakeName();
char *command;
command = ask(ShcomBuf, ProcFmt);
null_ncpy(ShcomBuf, command, (sizeof ShcomBuf) - 1);
proc_strt(MakeName(command), command, Shell, basename(Shell), ShFlags, command, 0);
}
proc_child()
{
union wait w;
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)
int pid;
union wait w;
{
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);
}
s_mess("%s [%s] %s", pstate(child), proc_buf(child), proc_cmd(child));
}
/* 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()
{
data_obj *d;
if ((d = findcom(ProcFmt, NOTHING)) == 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;
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_type == B_IPROCESS)
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_type == B_IPROCESS)
PushPBs();
}
}
}
#endif IPROCS