DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T i

⟦afcb49405⟧ TextFile

    Length: 6421 (0x1915)
    Types: TextFile
    Names: »iproc.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/jove/iproc.c« 

TextFile

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