?? xargs.c
字號:
/* * Public Domain simplified version of the System V xargs program. * * Author: Andrew Gollan */#include <sys/param.h>#include <stdio.h>/* * Handle the ATT/BSD ideas of wait(2). */#ifdef BSD#include <sys/wait.h>typedef union wait WAIT_T;#elsetypedef int WAIT_T;#endif /* BSD *//* * Set the maximum argument list that xargs will generate. * The reason this is not just NCARGS is that NCARGS can include * the environment space as well, a really serious program would * size the environment on the fly (but you know what you can do * with that idea). This is pretty big and pretty safe. * * Also set the maximum number of arguments that we are going to cope with. * This needed so that we can allocate an array of char * for execv(). Note * that on (at least some) BSD systems NCARGS is 1MB and MAXNARGS will be * 32K. Thank the powers for virtual memory. */#define MAXCARGS (NCARGS / 2)#define MAXNARGS (MAXCARGS / 32)/* * We need to set a limit on an input line for fgets, so use the * longest pathname the system can cope with if available, otherwise * a suitably large number. */#ifdef MAXPATHLEN#define MAXARGLEN MAXPATHLEN#else#define MAXARGLEN 1024#endif /* MAXPATHLEN *//* * System error handling. */#define SYSERROR (-1)extern int errno;extern int sys_nerr;extern char *sys_errlist[];#define sysmess() (\ (errno < 0 || errno > sys_nerr) \ ? \ "Unknown Error" \ : \ sys_errlist[errno] \ )/* * Statically allocate (in the bss segment) an argument vector * and a pool for collecting the arguments in. */static char *argvector[MAXNARGS];static char arglist[MAXCARGS];static int argbase;/* * Program name for error messages. */static char *myname;/* * Read lines from the standard input and pass them on as arguments * to the provided command, making sure that the system limit on * the number of characters in an argument is not exceeded. */int xargs(){ /* * Keep reading while the standard input is valid. */ while (!(feof(stdin) || ferror(stdin))) { register int i; register int pid; register char *argptr = arglist; /* * Limit the number of discrete arguments to MAXNARGS - 1. * We need the last slot for a NULL pointer to keep * execvp(2) happy. */ for (i = argbase; i < MAXNARGS - 1; ++i) { register int len; /* * If we may run out of space or we get * EOF or an error on input, stop collecting * arguments. */ if ( argptr + MAXARGLEN >= &arglist[MAXCARGS] || fgets(argptr, MAXARGLEN, stdin) == NULL ) break; /* * Ignore empty arguments. Note that fgets leaves * the newline at the end of the string. */ if ((len = strlen(argptr)) <= 1) continue; /* * Kill the trailing newline, add this argument to * the vector and advance the buffer pointer. */ argptr[len - 1] = '\0'; argvector[i] = argptr; argptr += len; } /* * Only run the command if we have some arguments. */ if (i <= argbase) break; /* * Cap the vector with the NULL pointer needed for * execvp(2). */ argvector[i] = NULL; /* * Fork and exec the command with all the collected * arguments. Watch out for failed forks. */ switch (pid = fork()) { case SYSERROR: (void)fprintf ( stderr, "%s: Couldn't fork: %s\n", myname, sysmess() ); exit(1); /* NOTREACHED */ case 0: /* * The child just execs the command. */ (void)execvp(argvector[0], argvector); perror(argvector[0]); exit(1); default: /* * Wait for the child to return. Due * to shell handling of pipelines, it * is possible to get the pid back from wait(). */ while (wait((WAIT_T *)0) != pid) ; } } return 0;}/* * Process the arguments and call xargs(). */int main(argc, argv)int argc;char *argv[];{ register int i; /* * Get the program invocation name for error messages. */ myname = argv[0]; /* * Check the arguments for consistency. */ if (argc < 2) { (void)fprintf(stderr, "usage: %s command [arg] ...\n", myname); exit(1); } /* * Fill in the command. */ for (i = 1; i < argc; ++i) argvector[argbase++] = argv[i]; /* * Call xargs() to do the real work. */ return xargs();}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -