📄 filter.c
字号:
#ifndef lintstatic char *sccsid = "@(#)filter.c 4.2 ULTRIX 10/16/90";#endif/************************************************************************ * * * Copyright (c) 1988 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * filter.c -- filter argument collection and execution * * Description: * This file is the implementation of an object to * describe filter programs to be run as sub-shells. * * A filter is a pipeline of simple commands. * Each simple command can be specified with * an arbitrary number of arguments. * There is a restriction on the number of simple * commands that may be specified in a pipeline. * * Four calls are provided to add arguments to a * particular component of a filter: fc_add_arg* * See below for details. * # The filter is run with fc_plumb_and_run. * `Plumb' refers to setting up pipes if necessary. * The call has arguments for passing the 3 file * descriptors to be dup'ed for file descriptors 0, 1 and 2 * in the filter. * A special value FC_MAKEPIPE can be specified * for any of these to indicate that a pipe should * be set up to communicate with this file descriptor * in the filter from the parent. * The parent can find the file descriptor of such a * pipe in the fc_fds field of the filter structure * after fc_plumb_and_run has been called. *//* SCCS history beginning * *************************************************************** * -- Revision History -- * *************************************************************** * * 1.1 10/03/88 -- thoms * date and time created 88/03/10 14:01:09 by thoms * * *************************************************************** * * 1.2 22/03/88 -- thoms * Filter environment is inherited one except for PATH (from lp.local.h) * * * *************************************************************** * * 1.3 30/03/88 -- thoms * Basic PostScript job building and execution working * * * *************************************************************** * * 1.4 25/04/88 -- thoms * Additional check in filter stop code, more debug logging in fc_run * * * *************************************************************** * * 1.5 29/04/88 -- thoms * More debugging in fc_wait() * * * *************************************************************** * * 1.6 03/05/88 -- thoms * Fixed and stable, minimal PS functionality. * * * *************************************************************** * * 1.7 20/05/88 -- thoms * fc_pout_run now has dofork argument to determine behaviour on * repeated fork failure * * * *************************************************************** * * 1.8 15/07/88 -- thoms * Added copyright notice and modification history, more comments * Improved some names * * *************************************************************** * * 1.9 19/07/88 -- thoms * Fixed a typo * * *************************************************************** * * 1.10 28/07/88 -- thoms * Generalised piping to filters and replaced the exported * calls fc_run and fc_pout_run with generalised function * fc_plumb_and_run which opens up pipes as required to * the spawned filter. * Added code to fc_init, fc_delete and fc_wait to cope * with parasitic linked on filter. Needed for pt_lps_v3. * * *************************************************************** * * 1.11 01/09/88 -- thoms * Added fc_start function to restart filters, tidied up fc_stop * Cleaned up and improved diagnostics in fc_wait * * *************************************************************** * * 1.12 09/09/88 -- thoms * Added more debug logging to in fc_wait * * *************************************************************** * * 1.13 09/09/88 -- thoms * Fixed status zeroing bug in fc_wait * * *************************************************************** * * 1.14 2/08/89 -- Giles Atkinson * Added calls to monitor progress while printing. * * SCCS history end */#include "lp.h"/* Declaration of local function */static char **chenv(/* char **env, envstr */);static void fc_run(/* register FCP fcp; int fork_action; */);static int dofork(/* int action_on_fail */);/* for exported functions declarations see filter.h *//* * dofork - fork with retries on failure */static intdofork(action)int action;{ register int i, pid; for (i = 0; i < DOFORK_NRETRIES; i++) { if ((pid = fork()) < 0) { sleep((unsigned)(i*i)); continue; } /* * Child should run as daemon instead of root */ if (pid == 0) if (setuid(DU) < 0) { log("setuid to %d failed", DU); exit(1); } return(pid); } log("can't fork"); switch (action) { case DORETURN: return (-1); default: log("bad action (%d) to dofork", action); /*FALL THRU*/ case DOABORT: exit(1); } /*NOTREACHED*/}/* * strsave -- save string using malloc, spotting null pointers */char *strsave(str)char *str;{ register char *saved; static char *null_string = "<null-string>"; if (!str) { str = null_string; } saved = malloc((unsigned)strlen(str) + 1); strcpy(saved, str); return saved;}/* * printv -- print a vector of strings in a standard format to stderr */voidprintv(argv)char **argv;{ while (*argv) fprintf(stderr, "\"%s\" ", *argv++);}/* * chenv -- replace an environment string * * This should only be called in a sub-process and * only after fork, not vfork * * Return values: * Returns pointer to environ vector on success * 0 on failure to find particular env variable * Future improvement: * Could build new environment vector to add new * environment variables */static char **chenv(env, envstr)char **env;char *envstr;{ register char *vardelim; register char **envp; register int envstrlen; if (!(vardelim = strchr(envstr, '='))) return 0; envstrlen = vardelim - envstr; for (envp = env; *envp; envp++) { if (!strncmp(*envp, envstr, envstrlen)) { *envp = envstr; return env; } } /* could extend env vector by mallocing one day */ return 0;}/* * parse_prog -- perform shell-like parsing of string into filter * * Return values: * Returns pointer to next non-white or 0 if end of string */char *parse_prog(fcp, prog_str)register FCP fcp; /* resulting args put here */char *prog_str; /* input string */{ register char *retp, *s, *prog = strsave(prog_str); if (retp = strchr(prog, '|')) { *retp++ = '\0'; while (isspace(*retp)) retp++; if (!*retp) { retp = 0; } else { /* fix up to point into supplied string */ retp -= (prog - prog_str); } } for (s=strtok(prog, " \t"); s; s=strtok(NULL, " \t")) { fc_add_arg(fcp, s); } fc_end_filter(fcp); free(prog); return retp;}/* * fc_grow -- make room for more arguments in filter object */static voidfc_grow(fcp)register FCP fcp;{ register char **p, **plim; register unsigned newsiz = (fcp->fc_i + FC_CLICK); newsiz /= FC_CLICK; newsiz *= FC_CLICK; fcp->fc_argv[fcp->fc_nf] = ((fcp->fc_argv[fcp->fc_nf]) ? (char **)realloc((char *)fcp->fc_argv[fcp->fc_nf], newsiz*sizeof(char *)) : (char **)malloc(newsiz*sizeof(char *))); plim = &fcp->fc_argv[fcp->fc_nf][newsiz]; for (p = &fcp->fc_argv[fcp->fc_nf][fcp->fc_max]; p < plim; p++) { *p = 0; } fcp->fc_max = newsiz;}/* * fc_next_simple_command_init -- init next filter component description */static voidfc_next_simple_command_init(fcp)register FCP fcp;{ fcp->fc_i = 0; fcp->fc_max = 0; fc_grow(fcp);}/* * fc_init -- initialise filter chain structure */void fc_init(fcp)register FCP fcp;{ register int i; memset(fcp, '\0', sizeof(*fcp)); for (i = 0; i < 3; i++) { fcp->fc_fds[i] = FC_FD_CLOSED; } for (i = 0; i < FC_MAX_SIMPLE_COMMANDS; i++ ) { fcp->fc_pid[i] = -1; } fc_next_simple_command_init(fcp);}/* * new_fc -- allocate filter object and initialise */FCPnew_fc(){ register FCP new_fcp; new_fcp = (FCP)malloc(sizeof(*new_fcp)); fc_init(new_fcp); return new_fcp;}/* * fc_delete -- delete filter object */void fc_delete(fcp, on_heap)FCP fcp;int on_heap; /* was malloc'ed if non-zero */{ register int i; /* * If we had any pipes set up to the filter make * sure they're closed down */ for (i=0; i < 3; i++) { if (fcp->fc_is_pipe & (1<<i) && fcp->fc_fds[i] >= 0) { (void) close(fcp->fc_fds[i]); fcp->fc_fds[i] = FC_FD_CLOSED; } } for (i = 0; i <= fcp->fc_nf; i++) { register char **p, **pv; if (!(pv = fcp->fc_argv[i])) continue; for (p = pv; *p; p++) free(*p); free((char *)pv); } if (fcp->fc_next) fc_delete(fcp->fc_next, 1); if (on_heap) free((char *)fcp);}/* * fc_end_filter -- terminate current simple command description */voidfc_end_filter(fcp)register FCP fcp;{ assert(fcp->fc_nf <= FC_MAX_SIMPLE_COMMANDS); if (fcp->fc_i >= fcp->fc_max) { fc_grow(fcp); } fcp->fc_argv[fcp->fc_nf++][fcp->fc_i] = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -