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

📄 filter.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	fc_next_simple_command_init(fcp);}/*****************************************************************	functions to add new args to current simple command****************************************************************//* * fc_add_arg -- add one argument */voidfc_add_arg(fcp, arg)register FCP fcp;char *arg;{	if (fcp->fc_i >= fcp->fc_max) {		fc_grow(fcp);	}	fcp->fc_argv[fcp->fc_nf][fcp->fc_i++] = strsave(arg);}/* * fc_add_args_l -- add 0 terminated list of arguments to *	current simple command *//*VARARGS1*/voidfc_add_args_l(fcp, va_alist)register FCP fcp;va_dcl{	va_list ap;	register char *str;	va_start(ap);	while (str = va_arg(ap, char *)) {		if (fcp->fc_i >= fcp->fc_max) {			fc_grow(fcp);		}		fcp->fc_argv[fcp->fc_nf][fcp->fc_i++] = strsave(str);	}	va_end(ap);}/* * fc_add_args_v -- add a vector of arguments to current simple command */voidfc_add_args_v(fcp, argv)register FCP fcp;char **argv;{	while (*argv) {		if (fcp->fc_i >= fcp->fc_max) {			fc_grow(fcp);		}		fcp->fc_argv[fcp->fc_nf][fcp->fc_i++] = strsave(*argv++);	}}/* * fc_add_args_va -- add va_list of arguments to current simple command */voidfc_add_args_va(fcp, ap)register FCP fcp;va_list ap;{	register char *str;	while (str = va_arg(ap, char *)) {		if (fcp->fc_i >= fcp->fc_max) {			fc_grow(fcp);		}		fcp->fc_argv[fcp->fc_nf][fcp->fc_i++] = strsave(str);	}}/*****************************************************************		functions to fire up the filters****************************************************************//* * fc_run -- run a filter * * Description: *	This does the business after any necessary plumbing (pipes) *	to the file descriptors 0, 1 & 2 has been done by fc_plumb_and_run() */static voidfc_run(fcp, fork_action)register FCP fcp;int fork_action;		/* argument to dofork() */{	register int nf;	/* counter for pipe building loop */	extern char **environ;	if (fcp->fc_mon_start)		/* Start progress monitor */		(*fcp->fc_mon_start)(fcp);	if (fcp->fc_nf == 0) { /* no filters: straight copy */		register int n;		char buf[BUFSIZ];		dlog(0, "fc_run: straight copy");		while ((n = read(fcp->fc_fds[FC_STDIN], buf, BUFSIZ)) > 0) {			if (write(fcp->fc_fds[FC_STDOUT], buf, n) != n) {				fcp->fc_status.w_retcode = 1;				break;			}		}		if (fcp->fc_mon_stop)		/* Stop progress monitor */			(*fcp->fc_mon_stop)();		fcp->fc_state = fc_done;		return;	}	if (DB > 0) { /* DEBUGGING: print log message */		int i;		log("fc_run: ");		for (i = 0; i < fcp->fc_nf; ) {			printv(fcp->fc_argv[i]);			fprintf(stderr, (++i < fcp->fc_nf) ? "| " : "\n");		}	}	/*	 * Many actions in the pipe building loop	 * are conditional on the following macros which	 * determine whether the particular simple command	 * is first or last in the pipeline and therefore	 * needs to be plumbed to the outside world.	 */#define		first_in_pipeline	(nf == 0)#define		last_in_pipeline	(nf == (fcp->fc_nf-1))	for (nf = 0; nf < fcp->fc_nf; nf++) {		int pipe_fd[2];	/* pipe file descriptors */		int i;		/* index for handling vector of fd's */		if (!last_in_pipeline) pipe(pipe_fd);		if ((fcp->fc_pid[nf] = dofork(fork_action)) == 0) {			/* child */			if (!last_in_pipeline) {				fcp->fc_fds[FC_STDOUT] = pipe_fd[1];				close(pipe_fd[0]);			}			/*			 * deal with file descriptors 0, 1 & 2			 */			for (i = 0; i < 3; i++) {				if (fcp->fc_fds[i] >= 0) {					if (fcp->fc_fds[i] != i)					    (void)dup2(fcp->fc_fds[i], i);				} else {					(void) close(i);				}			}			/* close rest of file descriptors */			for (i = 3; i < NOFILE; i++) (void) close(i);			/* set up new PATH in environment */			if (PATH_STRING &&			    !(environ = chenv(environ, PATH_STRING))) {				log("No PATH in inherited environment");				exit(3);			}			execvp(fcp->fc_argv[nf][0], fcp->fc_argv[nf]);			log("filter %s: not found\n",			    fcp->fc_argv[nf][0]);			exit(2);		} else if (fcp->fc_pid[nf] > 0) {	/* parent */			dlog(0, "fc_run: filter %d, pid %d",			     nf, fcp->fc_pid[nf]);			if (!first_in_pipeline) {				(void) close(fcp->fc_fds[FC_STDIN]);			}			if (!last_in_pipeline) {				(void) close(pipe_fd[1]);				fcp->fc_fds[FC_STDIN] = pipe_fd[0];			}			fcp->fc_state = fc_running;		} else {	/* dofork() failed */			if (!last_in_pipeline) {				(void) close(pipe_fd[0]);				(void) close(pipe_fd[1]);			}			fcp->fc_status.w_retcode = 1; /* force a retry */			fcp->fc_state = fc_done;			break;		}	}	return;}/* * fc_plumb_and_run -- Exported function to run a filter * * Description: *	We build any pipes requested and then call fc_run *	Note that the ends of the pipes of interest to *	the children are passed via the array in the filter struct. *	The ends of the pipe which interest the parent are copied *	in by this function before it returns. */extern voidfc_plumb_and_run(fcp, fork_action, fd_in, fd_out, fd_err)register FCP fcp;int fork_action;int fd_in;int fd_out;int fd_err;{	int pipe_fd[2];	int parent_fds[3];	int pipe_unwanted_fds[3];	register int i;	fcp->fc_fds[FC_STDIN] = fd_in;	fcp->fc_fds[FC_STDOUT] = fd_out;	fcp->fc_fds[FC_STDERR] = fd_err;	for (i=0; i < 3; i++) {		if (fcp->fc_fds[i] == FC_MAKEPIPE) {			fcp->fc_is_pipe |= (1<<i);			parent_fds[i] = fcp->fc_fds[i];		}	}	/*	 * If we have any pipes at all then it must not be	 * a null filter	 */	if (fcp->fc_is_pipe && fcp->fc_nf == 0) {		/* This shouldn't happen, indicates coding error */		dlog(0,"fc_plumb_and_run: Can't pipe to empty filter");		fcp->fc_is_pipe = 0;		fcp->fc_state = fc_done;	}	if (fcp->fc_is_pipe & (1<<FC_STDIN)) {		pipe(pipe_fd);		pipe_unwanted_fds[FC_STDIN] = fcp->fc_fds[FC_STDIN]		    = pipe_fd[0];		parent_fds[FC_STDIN] = pipe_fd[1];	}	if (fcp->fc_is_pipe & (1<<FC_STDOUT)) {		pipe(pipe_fd);		pipe_unwanted_fds[FC_STDOUT] = fcp->fc_fds[FC_STDOUT]		    = pipe_fd[1];		parent_fds[FC_STDOUT] = pipe_fd[0];	}	if (fcp->fc_is_pipe & (1<<FC_STDERR)) {		pipe(pipe_fd);		pipe_unwanted_fds[FC_STDERR] = fcp->fc_fds[FC_STDERR]		    = pipe_fd[1];		parent_fds[FC_STDERR] = pipe_fd[0];	}	fc_run(fcp, fork_action);	for (i=0; i < 3; i++) {		if (fcp->fc_is_pipe & (1<<i)) {			fcp->fc_fds[i] = parent_fds[i];			(void) close(pipe_unwanted_fds[i]);		} else {			fcp->fc_fds[i] = FC_FD_CLOSED;		}	}}/* * fc_wait wait for termination of filter and return exit status */union waitfc_wait(fcp)FCP fcp;{	register int pid = -1;	register int last_pid;	if (fcp->fc_state == fc_running && fcp->fc_nf > 0) {		last_pid =  fcp->fc_pid[fcp->fc_nf - 1];		dlog(0, "fc_wait: filter %d %s", last_pid,		     ((kill(last_pid, 0) < 0)		      ? "has exited" : "is still running"));		for (pid = 0; pid >= 0 && pid != last_pid; ) {			fcp->fc_status.w_status = 0;			pid = wait(&fcp->fc_status);			if (pid > 0)			    dlog(0, "fc_wait: Found process %d", pid);		}		if (fcp->fc_mon_stop)		/* Stop progress monitor */			(*fcp->fc_mon_stop)();		fcp->fc_state = fc_done;		if (pid != last_pid) {			dlog(0, "fc_wait: Couldn't find process %d", last_pid);		} else if (DB > 0){			if (WIFEXITED(fcp->fc_status)) {				log("Process %d exited status %d",				    pid, fcp->fc_status.w_retcode);			} else if (WIFSIGNALED(fcp->fc_status)) {				log("Process %d killed by signal %d%s",				    pid, fcp->fc_status.w_termsig,				    ((fcp->fc_status.w_coredump) ?				     " with core dump" : ""));			}		}	}	/* This recursive call is to clean up lpserrof */	if (fcp->fc_next) (void)fc_wait(fcp->fc_next);	return fcp->fc_status;}/*****************************************************************	functions relating to process control of filters run*	with a pipe to their standard input****************************************************************//* * fc_stop -- stop output filter with ^Y^A, then wash hands */intfc_stop(fcp)FCP fcp;{	int pid;	if (!(fcp->fc_is_pipe && (1 <<0))) {		dlog(0, "fc_stop: no input pipe");		return -1;	}	switch (fcp->fc_state) {	    default:		/* not in suitable state: error */		break;	    case fc_stopped:	/* already stopped, nothing to do */		break;	    case fc_running:	/* ok to stop */		write(fcp->fc_fds[0], "\031\1", 2);		while ((pid=wait3(&fcp->fc_status, WUNTRACED, 0)) > 0		       && pid != fcp->fc_pid[0])		    {}		fcp->fc_state = ((WIFEXITED(fcp->fc_status))				 ? fc_done : fc_stopped);			break;	} 	return ((fcp->fc_state == fc_stopped)		? 0 : -1); /* ok if stopped, else error */}/* * fc_start -- restart output filter with SIGCONT */intfc_start(fcp)FCP fcp;{	int pid;	if (!(fcp->fc_is_pipe && (1 <<0))) {		dlog(0, "fc_start: no input pipe");		return -1;	}	switch (fcp->fc_state) {	    default:		/* not in suitable state: error */		break;	    case fc_running:	/* already running, nothing to do */		break;	    case fc_stopped:	/* ok to restart */		if (kill(fcp->fc_pid[0], SIGCONT) < 0) {			dlog(0, "fc_start: process %d died",fcp->fc_pid[0]);			fcp->fc_state = fc_done;		} else {			fcp->fc_state = fc_running;		}		break;	} 	return ((fcp->fc_state == fc_running)		? 0 : -1); /* ok if running, else error */}/* * fc_pout_kill -- kill output filter by closing stdin *	restart first if necessary */void fc_pout_kill(fcp)FCP fcp;{	register int pid;	if (fc_start(fcp) == 0) {		(void) close(fcp->fc_fds[0]);		fcp->fc_fds[0] = FC_FD_CLOSED;	} else {		dlog(0, "fc_pout_kill: error: filter in state %s",		     "ready\0runng\0done\0\0stopped"[6*(int)fcp->fc_state]);	}}

⌨️ 快捷键说明

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