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

📄 proc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
}#endif	/* SPELL */voidShToBuf(){	char	bnm[128],		cmd[LBSIZE];	strcpy(bnm, ask((char *)NULL, "Buffer: "));	strcpy(cmd, ask(ShcomBuf, "Command: "));	DoShell(bnm, cmd);}voidShellCom(){	null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1);	DoShell(MakeName(ShcomBuf), ShcomBuf);}voidShNoBuf(){	int	status;	null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1);	status = UnixToBuf((char *)NULL, (char *)NULL, NO, 0, NO,		Shell, ShFlags, ShcomBuf,		curbuf->b_fname, curbuf->b_fname, (char *)NULL);	com_finish(status, ShcomBuf);}voidShtypeout(){	int	status;	null_ncpy(ShcomBuf, ask(ShcomBuf, ProcFmt), (sizeof ShcomBuf) - 1);	status = UnixToBuf((char *)NULL, (char *)NULL, YES, 0, NO,		Shell, ShFlags, ShcomBuf,		curbuf->b_fname, curbuf->b_fname, (char *)NULL);	if (status == 0)		Typeout("[%s: completed successfully]", ShcomBuf);	else		Typeout("[%s: exited (%d)]", ShcomBuf, status);	TOstop();}/* Run the shell command into `bnm'.  Empty the buffer except when we   give a numeric argument, in which case it inserts the output at the   current position in the buffer.  */private voidDoShell(bnm, command)char	*bnm,	*command;{	Window	*savewp = curwind;	int	status;	char	*fn = pr_name(curbuf->b_fname, NO);	/* Two copies of the file name are passed to the shell:	 * The Cshell uses the first as a definition of $1	 * Most version of the Bourne shell use the second as a definition of $1.	 */	status = UnixToBuf(bnm, (char *)NULL, YES, 0, !is_an_arg(),		Shell, ShFlags, command, fn, fn, (char *)NULL);	com_finish(status, command);	SetWind(savewp);}private voidcom_finish(status, cmd)int	status;char	*cmd;{	s_mess("[%s: ", cmd);	if (status == 0)		add_mess("completed successfully");	else		add_mess("exited (%d)", status);	add_mess("]");}#ifndef	MSDOSvoiddowait(pid, status)int	pid,	*status;{# ifndef	IPROCS	int	rpid;	do ; while ((rpid = wait(status)) != pid);# else# include "wait.h"	union wait	w;	int	rpid;	for (;;) {#  ifndef	WAIT3		rpid = wait2(&w.w_status, 0);#  else		rpid = wait3(&w, 0, (struct rusage *)NULL);#  endif		if (rpid == -1)			break;		else if (rpid == pid) {			if (status)				*status = w.w_status;			break;		} else			kill_off(rpid, w);	}# endif	/* IPROCS */}#endif	/* MSDOS *//* Run the command to bnm, erase the buffer if clobber is non-zero,   and redisplay if disp is non-zero.  Leaves current buffer in `bnm'   and leaves any windows it creates lying around.  It's up to the caller   to fix everything up after we're done.  (Usually there's nothing to   fix up.) */#ifdef	STDARGSintUnixToBuf(char *bnm, char *InFName, bool disp, int wsize, bool clobber, ...)#else/*VARARGS5*/ intUnixToBuf(bnm, InFName, disp, wsize, clobber, va_alist)	char	*bnm, *InFName;	bool	disp;	int	wsize;	bool	clobber;	va_dcl#endif{#ifndef	MSDOS	int	p[2],		pid;#else	/* MSDOS */	char	pnbuf[FILESIZE];	char	*pipename;#endif	/* MSDOS */	int	status;	bool	eof;	va_list	ap;	char	*argv[32],		*mess;	File	*fp;	SIGRESULT	(*old_int) proto((int));	va_init(ap, clobber);	make_argv(argv, ap);	va_end(ap);	if (bnm != NULL && clobber == YES)		isprocbuf(bnm);	if (access(argv[0], X_OK) != 0) {		complain("[Couldn't access %s: %s]", argv[0], strerror(errno));		/* NOTREACHED */	}	if (disp) {		if (bnm != NULL) {			message("Starting up...");			pop_wind(bnm, clobber, clobber ? B_PROCESS : B_FILE);			set_wsize(wsize);			redisplay();		} else {			TOstart(argv[0], TRUE);			Typeout("Starting up...");		}	}	/* Now I will attempt to describe how I deal with signals during	   the execution of the shell command.  My desire was to be able	   to interrupt the shell command AS SOON AS the window pops up.	   So, if we have BSD_SIGS (i.e., the new signal mechanism) I	   hold SIGINT, meaning if we interrupt now, we will eventually	   see the interrupt, but not before we are ready for it.  We	   fork, the child releases the interrupt, it then sees the	   interrupt, and so exits.  Meanwhile the parent ignores the	   signal, so if there was a pending one, it's now lost.	   With no BSD_SIGS, the best behavior you can expect is, when	   you type ^] too very quickly after the window pops up, it may	   be ignored.  The behavior BEFORE was that it would interrupt	   JOVE and then you would have to continue JOVE and wait a	   little while longer before trying again.  Now that is fixed,	   in that you just have to type it twice. */#ifndef	MSDOS# ifdef	IPROCS	SigHold(SIGCHLD);# endif# ifdef	BSD_SIGS	SigHold(SIGINT);# else	old_int = signal(SIGINT, SIG_IGN),# endif	dopipe(p);#ifdef	VFORK	pid = vfork();#else	pid = fork();#endif	if (pid == -1) {		pipeclose(p);		complain("[Fork failed: %s]", strerror(errno));	}	if (pid == 0) {# ifdef	VFORK		/*		 * We want to release SIGCHLD and SIGINT in the child,		 * but we can't use SigRelse because that would change		 * Jove's copy of the SigMask variable (because we're in		 * a vfork).  So we simply set set the mask directly.		 * There are several other forks in Jove, but this is		 * the only one we execute often enough to make it worth		 * using a vfork.  This assumes a system with vfork also		 * has BSD signals!		 */		(void) signal(SIGINT, SIG_DFL);		(void) sigsetmask(SigMask & ~(sigmask(SIGCHLD)|sigmask(SIGINT)));# else	/* !VFORK */#  ifdef	IPROCS		SigRelse(SIGCHLD);   /* don't know if this matters */#  endif	/* IPROCS */		(void) signal(SIGINT, SIG_DFL);#  ifdef	BSD_SIGS		SigRelse(SIGINT);#  endif	/* BSD_SIGS */# endif	/* !VFORK */		(void) close(0);		(void) open(InFName==NULL? "/dev/null" : InFName, 0);		(void) close(1);		(void) close(2);		(void) dup(p[1]);		(void) dup(p[1]);		pipeclose(p);		jcloseall();		execv(argv[0], (const char **) &argv[1]);		raw_complain("Execl failed: %s\n", strerror(errno));		_exit(1);	}# ifdef	BSD_SIGS	old_int = signal(SIGINT, SIG_IGN);# endif	(void) close(p[1]);	fp = fd_open(argv[1], F_READ, p[0], iobuff, LBSIZE);#else	/* MSDOS */	{		int	oldi = dup(0),			oldo = dup(1),			olde = dup(2);		bool	InFailure = FALSE;		int	ph;		swritef(pnbuf, sizeof(pnbuf), "%s/%s", TmpFilePath, "jpXXXXXX");		pipename = mktemp(pnbuf);		if ((ph = creat(pipename, S_IWRITE|S_IREAD)) < 0)			complain("cannot make pipe for filter: %s", strerror(errno));		close(1);		close(2);		dup(ph);		dup(ph);		close(0);		if (InFName == NULL)			if (open(InFName, 0) < 0)				InFailure = TRUE;		if (!InFailure)			status = spawnv(0, argv[0], &argv[1]);		close(0);		close(1);		close(2);		dup(oldi);		dup(oldo);		dup(olde);		close(oldi);		close(oldo);		close(olde);		if (InFailure)			complain("[filter input failed]");		if (status < 0)			complain("[Spawn failed]");		ph = open(pipename, 0);		if (ph < 0)			complain("[cannot reopen pipe]", strerror(errno));		fp = fd_open(argv[1], F_READ, ph, iobuff, LBSIZE);	}#endif	/* MSDOS */	do {#ifndef	MSDOS		inIOread = YES;#endif		eof = f_gets(fp, genbuf, (size_t)LBSIZE);#ifndef	MSDOS		inIOread = NO;#endif		if (bnm != NULL) {			ins_str(genbuf, YES);			if (!eof)				LineInsert(1);		} else if (disp)			Typeout("%s", genbuf);		if (bnm != NULL && disp && fp->f_cnt <= 0) {#ifdef	LOAD_AV		    {			int	la = get_la();			if (la < 200)				mess = "Screaming along...";			else if (la < 500)				mess = "Chugging along...";			else				mess = "Crawling along...";		    }#else			mess = "Chugging along...";#endif	/* LOAD_AV */			if (bnm != NULL) {				message(mess);				redisplay();			}		}	} while (!eof);	if (disp)		DrawMesg(NO);	close_file(fp);#ifndef	MSDOS	dowait(pid, &status);# ifdef	BSD_SIGS	(void) SigRelse(SIGINT);# endif# ifdef	IPROCS	SigRelse(SIGCHLD);# endif#else	/* MSDOS */	unlink(pipename);	getCWD();#endif	/* MSDOS */	(void) signal(SIGINT, old_int);	return status;}/* Send the current region to CMD and insert the output from the   command into OUT_BUF. */private voidRegToUnix(outbuf, cmd)Buffer	*outbuf;char	*cmd;{	Mark	*m = CurMark();	static char     tnambuf[FILESIZE];	char    *tname;	Window	*save_wind = curwind;	volatile int	status;	volatile int	err = NO;	File	*volatile fp;	jmp_buf	sav_jmp;	swritef(tnambuf, sizeof(tnambuf), "%s/%s", TmpFilePath, "jfXXXXXX");	tname = mktemp(tnambuf);	fp = open_file(tname, iobuff, F_WRITE, YES, YES);	push_env(sav_jmp);	if (setjmp(mainjmp) == 0) {		putreg(fp, m->m_line, m->m_char, curline, curchar, YES);		DelReg();		f_close(fp);		status = UnixToBuf(outbuf->b_name, tname, NO, 0,			outbuf->b_type==B_SCRATCH, Shell, ShFlags, cmd, (char *)NULL);	} else {		f_close(fp);		err = YES;	}	pop_env(sav_jmp);	(void) unlink(tname);	SetWind(save_wind);	if (!err)		com_finish(status, cmd);}voidFilterRegion(){	static char	FltComBuf[LBSIZE];	null_ncpy(FltComBuf, ask(FltComBuf, ": %f (through command) "),		(sizeof FltComBuf) - 1);	RegToUnix(curbuf, FltComBuf);}voidisprocbuf(bnm)char	*bnm;{	Buffer	*bp;	if ((bp = buf_exists(bnm)) != NULL && bp->b_type != B_PROCESS)		confirm("Over-write buffer %s? ", bnm);}#ifdef	MSDOS/* ??? how many of these includes are redundant?  Are they needed in RegToUnix()? */#include <dos.h>#include <fcntl.h>/* ??? Set the DOS path separator character to '/' from '\\' */charswitchar(){  union REGS regs;  regs.h.ah = 0x37;  regs.h.al = 0;  intdos(&regs, &regs);  return regs.h.dl;}#endif	/* MSDOS */

⌨️ 快捷键说明

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