⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iproc-pipes.c

📁 早期freebsd实现
💻 C
字号:
/*************************************************************************** * This program is Copyright (C) 1986, 1987, 1988 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.                                              * ***************************************************************************//* NOTE WELL: * This file is "included" into iproc.c -- it is not compiled separately! */#include <signal.h>#include <sgtty.h>#include "wait.h"#define DEAD	1	/* Dead but haven't informed user yet */#define STOPPED	2	/* Job stopped */#define RUNNING	3	/* Just running */#define NEW	4	/* This process is brand new *//* If process is dead, flags says how. */#define EXITED	1#define KILLED	2#define isdead(p)	((p) == NULL || proc_state((p)) == DEAD || (p)->p_toproc == -1)#define makedead(p)	{ proc_state((p)) = DEAD; }#define proc_buf(p)	((p)->p_buffer->b_name)#define proc_cmd(p)	((p)->p_name)#define proc_state(p)	((p)->p_state)private Process	*procs = NULL;File	*ProcInput;int	ProcOutput,	kbd_pid = 0,	NumProcs = 0;private Process *proc_pid(pid)int	pid;{	register Process	*p;	for (p = procs; p != NULL; p = p->p_next)		if (p->p_portpid == pid)			break;	return p;}voidread_proc(pid, nbytes)int	pid;register int	nbytes;{	register Process	*p;	char	ibuf[512];	if ((p = proc_pid(pid)) == NULL) {		writef("\riproc: unknown pid (%d)", pid);		return;	}	if (proc_state(p) == NEW) {		int	rpid;		/* pid of real child, not of portsrv */		(void) f_readn(ProcInput, (char *) &rpid, sizeof (int));		p->p_pid = rpid;		p->p_state = RUNNING;		return;	}	if (nbytes == EOF) {		/* okay to clean up this process */		union wait	status;		int	pid;		(void) f_readn(ProcInput, &status.w_status, sizeof (int));		do {			pid = wait((int *)NULL);			if (pid < 0)				break;			kill_off(pid, status);		} while (pid != p->p_portpid);		proc_close(p);		makedead(p);		return;	}	while (nbytes > 0) {		size_t n = f_readn(ProcInput, ibuf, min((sizeof ibuf) - 1, nbytes));		ibuf[n] = '\0';	/* Null terminate for convenience */		nbytes -= n;		proc_rec(p, ibuf);	}}voidProcKill(){	proc_kill(curbuf->b_process, SIGKILL);}voidProcInt(){	proc_kill(curbuf->b_process, SIGINT);}voidProcQuit(){	proc_kill(curbuf->b_process, SIGQUIT);}private voidproc_close(p)Process	*p;{	if (p->p_toproc >= 0) {		(void) close(p->p_toproc);		p->p_toproc = -1;	/* writes will fail */		NumProcs -= 1;	}}voidproc_write(p, buf, nbytes)Process	*p;char	*buf;size_t	nbytes;{	(void) write(p->p_toproc, buf, nbytes);}#ifdef	STDARGSprivate voidproc_strt(char *bufname, int clobber, ...)#elseprivate /*VARARGS3*/ voidproc_strt(bufname, clobber, va_alist)	char	*bufname;	int	clobber;	va_dcl#endif{	Window	*owind = curwind;	int	toproc[2],		pid;	Process	*newp;	Buffer	*newbuf;	char	*argv[32],		*cp,		foo[10],		cmdbuf[LBSIZE];	int	i;	va_list	ap;	isprocbuf(bufname);	/* make sure BUFNAME is either nonexistant				   or is of type B_PROCESS */	if (access(Portsrv, X_OK) < 0) {		complain("[Couldn't access %s: %s]", Portsrv, strerror(errno));		/* NOTREACHED */	}	dopipe(toproc);	switch (pid = fork()) {	case -1:		pipeclose(toproc);		complain("[Fork failed: %s]", strerror(errno));	case 0:		argv[0] = "portsrv";		va_init(ap, clobber);		make_argv(&argv[1], ap);		va_end(ap);		(void) dup2(toproc[0], 0);		(void) dup2(ProcOutput, 1);		(void) dup2(ProcOutput, 2);		pipeclose(toproc);		jcloseall();		execv(Portsrv, argv);		raw_complain("execl failed: %s\n", strerror(errno));		_exit(1);	}	newp = (Process *) malloc(sizeof *newp);	/* ??? better check for newp == NULL -- DHR */	newp->p_next = procs;	newp->p_state = NEW;	cmdbuf[0] = '\0';	va_init(ap, clobber);	while (cp = va_arg(ap, char *)) {		size_t	pl = strlen(cmdbuf);		swritef(&cmdbuf[pl], sizeof(cmdbuf)-pl, "%s ", cp);	}	va_end(ap);	va_init(ap, clobber);	newp->p_name = copystr(cmdbuf);	procs = newp;	newp->p_portpid = pid;	newp->p_pid = -1;	newbuf = do_select((Window *)NULL, bufname);	newbuf->b_type = B_PROCESS;	newp->p_buffer = newbuf;	newbuf->b_process = newp;	/* sorta circular, eh? */	pop_wind(bufname, clobber, B_PROCESS);	ToLast();	if (!bolp())		LineInsert(1);	/* Pop_wind() after everything is set up; important!	   Bindings won't work right unless newbuf->b_process is already	   set up BEFORE NEWBUF is first SetBuf()'d. */	newp->p_mark = MakeMark(curline, curchar, M_FLOATER);	newp->p_dbx_mode = NO;	newp->p_toproc = toproc[1];	newp->p_reason = 0;	NumProcs += 1;	if (NumProcs == 1)		(void) kbd_strt();	(void) close(toproc[0]);	SetWind(owind);}voidpinit(){	int	p[2];	(void) pipe(p);	ProcInput = fd_open("process-input", F_READ|F_LOCKED, p[0],			    (char *)NULL, 512);	ProcOutput = p[1];	if ((kbd_pid = fork()) == -1) {		raw_complain("Cannot fork kbd process! %s\n", strerror(errno));		finish(SIGHUP);	}	if (kbd_pid == 0) {		signal(SIGINT, SIG_IGN);		signal(SIGALRM, SIG_IGN);		close(1);		dup(ProcOutput);		jcloseall();		execl(Kbd_Proc, "kbd", (char *)NULL);		raw_complain("kbd exec failed: %s\n", strerror(errno));		exit(-1);	}}private int	kbd_state = OFF;/* kbd_strt() and kbd_stop() return true if they changed the state   of the keyboard process.  E.g., kbd_strt() returns TRUE if the   kbd process was previously stopped.  This is so kbd starting and   stopping in pairs works - see finish() in jove.c. */kbd_strt(){	if (kbd_state == OFF) {		kbd_state = ON;		kill(kbd_pid, KBDSIG);		return TRUE;	}	return FALSE;}kbd_stop(){	if (kbd_state == ON) {		kbd_state = OFF;		kill(kbd_pid, KBDSIG);		return TRUE;	}	return FALSE;}kbd_kill(){	if (kbd_pid != 0) {		kill(kbd_pid, SIGKILL);		kbd_pid = 0;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -