4.3BSD/usr/contrib/jove/iproc.c

Compare this file to the similar file:
Show the results in this format:

/*************************************************************************
 * 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