X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=xargs.c;h=c5f7b208c425cb2cebc7c168a5c7cca045779655;hb=46f44d24fcc25a5d6e13e0453485881bdf147e91;hp=be1fada78ba458c79ac1476fe577bf114345e5e7;hpb=5b17693f0a07d0fa8af08e3c0d6b43c7b826a13d;p=oweals%2Fbusybox.git diff --git a/xargs.c b/xargs.c index be1fada78..c5f7b208c 100644 --- a/xargs.c +++ b/xargs.c @@ -1,116 +1,108 @@ -/* minix xargs - Make and execute commands - * Author: Ian Nicholls: 1 Mar 90 */ - /* - * xargs - Accept words from stdin until, combined with the arguments - * given on the command line, just fit into the command line limit. - * Then, execute the result. - * e.g. ls | xargs compress - * find . -name '*.s' -print | xargs ar qv libc.a + * Mini xargs implementation for busybox + * + * Copyright (C) 2000 by Lineo, inc. + * Written by Erik Andersen , + * Remixed by Mark Whitley , * - * flags: -t Print the command just before it is run - * -l len Use len as maximum line length (default 490, max 1023) - * -e ending Append ending to the command before executing it. + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. * - * Exits with: 0 No errors. - * 1 If any system(3) call returns a nonzero status. - * 2 Usage error - * 3 Line length too short to contain some single argument. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. * - * Examples: xargs ar qv libc.a < liborder # Create a new libc.a - * find . -name '*.s' -print | xargs rm # Remove all .s files - * find . -type f ! -name '*.Z' \ # Compress old files. - * -atime +60 -print | xargs compress -v + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Bugs: If the command contains unquoted wildflags, then the system(3) call - * call may expand this to larger than the maximum line size. - * The command is not executed if nothing was read from stdin. - * xargs may give up too easily when the command returns nonzero. */ -#define USAGE "usage: xargs [-t] [-l len] [-e endargs] command [args...]\n" -#include +#include "busybox.h" +#include #include #include -#include -#include -#ifndef MAX_ARGLINE -# define MAX_ARGLINE 1023 -#endif -#ifndef min -# define min(a,b) ((a) < (b) ? (a) : (b)) -#endif +int xargs_main(int argc, char **argv) +{ + char *cmd_to_be_executed = NULL; + char *file_to_act_on = NULL; -char outlin[MAX_ARGLINE]; -char inlin[MAX_ARGLINE]; -char startlin[MAX_ARGLINE]; -char *ending = NULL; -char traceflag = 0; + /* + * No options are supported in this version of xargs; no getopt. + * + * Re: The missing -t flag: Most programs that produce output also print + * the filename, so xargs doesn't really need to do it again. Supporting + * the -t flag =greatly= bloats up the size of this app and the memory it + * uses because you have to buffer all the input file strings in memory. If + * you really want to see the filenames that xargs will act on, just run it + * once with no args and xargs will echo the filename. Simple. + */ -int xargs_main(int ac, char **av) -{ - int outlen, inlen, startlen, endlen=0, i; - char errflg = 0; - int maxlin = MAX_ARGLINE; + /* Store the command to be executed (taken from the command line) */ + if (argc == 1) { + /* default behavior is to echo all the filenames */ + cmd_to_be_executed = strdup("/bin/echo "); + } else { + /* concatenate all the arguments passed to xargs together */ + int i; + int len = 1; /* for the '\0' */ + for (i = 1; i < argc; i++) { + len += strlen(argv[i]); + len += 1; /* for the space between the args */ + cmd_to_be_executed = xrealloc(cmd_to_be_executed, len); + strcat(cmd_to_be_executed, argv[i]); + strcat(cmd_to_be_executed, " "); + } + } - while ((i = getopt(ac, av, "tl:e:")) != EOF) - switch (i) { - case 't': traceflag = 1; break; - case 'l': maxlin = min(MAX_ARGLINE, atoi(optarg)); break; - case 'e': ending = optarg; break; - case '?': errflg++; break; - } - if (errflg) { - fprintf(stderr, USAGE); - exit(2); - } + /* Now, read in one line at a time from stdin, and store this + * line to be used later as an argument to the command */ + while ((file_to_act_on = get_line_from_file(stdin)) !=NULL) { - startlin[0] = 0; - if (optind == ac) { - strcat(startlin, "echo "); - } - else for ( ; optind < ac; optind++) { - strcat(startlin, av[optind]); - strcat(startlin, " "); - } - startlen = strlen(startlin); - if (ending) endlen = strlen(ending); - maxlin = maxlin - 1 - endlen; /* Pre-compute */ + FILE *cmd_output = NULL; + char *output_line = NULL; + char *execstr = NULL; - strcpy(outlin, startlin); - outlen = startlen; + /* eat the newline off the filename. */ + if (file_to_act_on[strlen(file_to_act_on)-1] == '\n') + file_to_act_on[strlen(file_to_act_on)-1] = '\0'; - while (gets(inlin) != NULL) { - inlen = strlen(inlin); - if (maxlin <= (outlen + inlen)) { - if (outlen == startlen) { - fprintf(stderr, "%s: Line length too short to process '%s'\n", - av[0], inlin); - exit(3); - } - if (ending) strcat(outlin, ending); - if (traceflag) fputs(outlin,stderr); - errno = 0; - if (0 != system(outlin)) { - if (errno != 0) perror("xargs"); - exit(1); - } - strcpy(outlin, startlin); - outlen = startlen; - } - strcat(outlin, inlin); - strcat(outlin, " "); - outlen = outlen + inlen + 1; - } - if (outlen != startlen) { - if (ending) strcat(outlin, ending); - if (traceflag) fputs(outlin,stderr); - errno = 0; - if (0 != system(outlin)) { - if (errno != 0) perror("xargs"); - exit(1); - } - } - return 0; + /* eat blank lines */ + if (strlen(file_to_act_on) == 0) + continue; + + /* assemble the command and execute it */ + execstr = xcalloc(strlen(cmd_to_be_executed) + + strlen(file_to_act_on) + 1, sizeof(char)); + strcat(execstr, cmd_to_be_executed); + strcat(execstr, file_to_act_on); + cmd_output = popen(execstr, "r"); + if (cmd_output == NULL) { + perror("popen"); + exit(1); + } + + /* harvest the output */ + while ((output_line = get_line_from_file(cmd_output)) != NULL) { + fputs(output_line, stdout); + free(output_line); + } + + /* clean up */ + pclose(cmd_output); + free(execstr); + free(file_to_act_on); + } + +#ifdef BB_FEATURE_CLEAN_UP + free(cmd_to_be_executed); +#endif + + return 0; } + +/* vi: set sw=4 ts=4: */