aboutsummaryrefslogtreecommitdiff
path: root/findutils/xargs.c
diff options
context:
space:
mode:
authorMark Whitley <markw@lineo.com>2000-11-14 22:43:21 +0000
committerMark Whitley <markw@lineo.com>2000-11-14 22:43:21 +0000
commite2e2c29ea13213974a4014fa726f1a506cc6705f (patch)
tree5b2c1a9a9a07ce9e540387388010e0fed6ab64e3 /findutils/xargs.c
parent3c5ee9a379dd837962041b63537e84c148143997 (diff)
downloadbusybox-w32-e2e2c29ea13213974a4014fa726f1a506cc6705f.tar.gz
busybox-w32-e2e2c29ea13213974a4014fa726f1a506cc6705f.tar.bz2
busybox-w32-e2e2c29ea13213974a4014fa726f1a506cc6705f.zip
Brand new version of xargs. Tested thoroughly by Kent Robotti. (Domo arigato,
Mr. Robotti...) Closes bug #1065.
Diffstat (limited to 'findutils/xargs.c')
-rw-r--r--findutils/xargs.c173
1 files changed, 61 insertions, 112 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c
index 433567b77..c5f7b208c 100644
--- a/findutils/xargs.c
+++ b/findutils/xargs.c
@@ -1,9 +1,9 @@
1/* vi: set sw=4 ts=4: */
2/* 1/*
3 * Mini xargs implementation for busybox 2 * Mini xargs implementation for busybox
4 * 3 *
5 * Copyright (C) 2000 by Lineo, inc. 4 * Copyright (C) 2000 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> 5 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
6 * Remixed by Mark Whitley <markw@lineo.com>, <markw@enol.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -22,138 +22,87 @@
22 */ 22 */
23 23
24#include "busybox.h" 24#include "busybox.h"
25#include <stdlib.h>
26#include <stdio.h> 25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h> 27#include <string.h>
28#include <errno.h>
29#include <getopt.h>
30#include <ctype.h>
31#include <sys/types.h>
32#include <sys/wait.h>
33
34 28
35int xargs_main(int argc, char **argv) 29int xargs_main(int argc, char **argv)
36{ 30{
37 char *in_from_stdin = NULL;
38 char *args = NULL;
39 char *cmd_to_be_executed = NULL; 31 char *cmd_to_be_executed = NULL;
40 char traceflag = 0; 32 char *file_to_act_on = NULL;
41 int len_args=0, len_cmd_to_be_executed, opt; 33
42 pid_t pid; 34 /*
43 int wpid, status; 35 * No options are supported in this version of xargs; no getopt.
44 36 *
45 /* Note that we do not use getopt here, since 37 * Re: The missing -t flag: Most programs that produce output also print
46 * we only want to interpret initial options, 38 * the filename, so xargs doesn't really need to do it again. Supporting
47 * not options passed to commands */ 39 * the -t flag =greatly= bloats up the size of this app and the memory it
48 while (--argc && **(++argv) == '-') { 40 * uses because you have to buffer all the input file strings in memory. If
49 while (*++(*argv)) { 41 * you really want to see the filenames that xargs will act on, just run it
50 switch (**argv) { 42 * once with no args and xargs will echo the filename. Simple.
51 case 't': 43 */
52 traceflag=1;
53 break;
54 default:
55 fatalError(xargs_usage);
56 }
57 }
58 }
59 44
60 /* Store the command to be executed (taken from the command line) */ 45 /* Store the command to be executed (taken from the command line) */
61 if (argc == 0) { 46 if (argc == 1) {
62 len_cmd_to_be_executed=6; 47 /* default behavior is to echo all the filenames */
63 cmd_to_be_executed = xmalloc(len_cmd_to_be_executed); 48 cmd_to_be_executed = strdup("/bin/echo ");
64 strcat(cmd_to_be_executed, "echo");
65 } else { 49 } else {
66 opt=strlen(*argv); 50 /* concatenate all the arguments passed to xargs together */
67 len_cmd_to_be_executed = (opt > 10)? opt : 10; 51 int i;
68 cmd_to_be_executed = xcalloc(len_cmd_to_be_executed, sizeof(char)); 52 int len = 1; /* for the '\0' */
69 strcat(cmd_to_be_executed, *argv); 53 for (i = 1; i < argc; i++) {
54 len += strlen(argv[i]);
55 len += 1; /* for the space between the args */
56 cmd_to_be_executed = xrealloc(cmd_to_be_executed, len);
57 strcat(cmd_to_be_executed, argv[i]);
58 strcat(cmd_to_be_executed, " ");
59 }
70 } 60 }
71 61
72 //args=xrealloc(args, len_args);
73// strcpy(args, " ");
74
75 /* Now, read in one line at a time from stdin, and store this 62 /* Now, read in one line at a time from stdin, and store this
76 * line to be used later as an argument to the command */ 63 * line to be used later as an argument to the command */
77 in_from_stdin = get_line_from_file(stdin); 64 while ((file_to_act_on = get_line_from_file(stdin)) !=NULL) {
78 for (;in_from_stdin!=NULL;) { 65
79 char *tmp; 66 FILE *cmd_output = NULL;
80 opt = strlen(in_from_stdin); 67 char *output_line = NULL;
81 len_args += opt + 3; 68 char *execstr = NULL;
82 args=xrealloc(args, len_args); 69
83 70 /* eat the newline off the filename. */
84 /* Strip out the final \n */ 71 if (file_to_act_on[strlen(file_to_act_on)-1] == '\n')
85 in_from_stdin[opt-1]=' '; 72 file_to_act_on[strlen(file_to_act_on)-1] = '\0';
86 73
87 /* Replace any tabs with spaces */ 74 /* eat blank lines */
88 while( (tmp = strchr(in_from_stdin, '\t')) != NULL ) 75 if (strlen(file_to_act_on) == 0)
89 *tmp=' '; 76 continue;
90 77
91 /* Strip out any extra intra-word spaces */ 78 /* assemble the command and execute it */
92 while( (tmp = strstr(in_from_stdin, " ")) != NULL ) { 79 execstr = xcalloc(strlen(cmd_to_be_executed) +
93 opt = strlen(in_from_stdin); 80 strlen(file_to_act_on) + 1, sizeof(char));
94 memmove(tmp, tmp+1, opt-(tmp-in_from_stdin)); 81 strcat(execstr, cmd_to_be_executed);
82 strcat(execstr, file_to_act_on);
83 cmd_output = popen(execstr, "r");
84 if (cmd_output == NULL) {
85 perror("popen");
86 exit(1);
95 } 87 }
96 88
97 /* trim trailing whitespace */ 89 /* harvest the output */
98 opt = strlen(in_from_stdin) - 1; 90 while ((output_line = get_line_from_file(cmd_output)) != NULL) {
99 while (isspace(in_from_stdin[opt])) 91 fputs(output_line, stdout);
100 opt--; 92 free(output_line);
101 in_from_stdin[++opt] = 0;
102
103 /* Strip out any leading whitespace */
104 tmp=in_from_stdin;
105 while(isspace(*tmp))
106 tmp++;
107
108 strcat(args, tmp);
109 strcat(args, " ");
110
111 free(in_from_stdin);
112 in_from_stdin = get_line_from_file(stdin);
113 }
114
115 if ((pid = fork()) == 0) {
116 char *cmd[255];
117 int i=1;
118
119 if (traceflag==1) {
120 fprintf(stderr, "%s ", cmd_to_be_executed);
121 } 93 }
122 cmd[0] = cmd_to_be_executed;
123 while (--argc && ++argv && *argv ) {
124 if (traceflag==1) {
125 fprintf(stderr, "%s ", *argv);
126 }
127 cmd[i++]=*argv;
128 }
129 if (traceflag==1) {
130 fprintf(stderr, "%s\n", args);
131 }
132 cmd[i++] = args;
133 cmd[i] = NULL;
134 execvp(cmd_to_be_executed, cmd);
135 94
136 /* What? Still here? Exit with an error */ 95 /* clean up */
137 fatalError("%s: %s\n", cmd_to_be_executed, strerror(errno)); 96 pclose(cmd_output);
97 free(execstr);
98 free(file_to_act_on);
138 } 99 }
139 /* Wait for a child process to exit */
140 wpid = wait(&status);
141
142 100
143#ifdef BB_FEATURE_CLEAN_UP 101#ifdef BB_FEATURE_CLEAN_UP
144 free(args);
145 free(cmd_to_be_executed); 102 free(cmd_to_be_executed);
146#endif 103#endif
147 104
148 if (wpid > 0) 105 return 0;
149 return (WEXITSTATUS(status));
150 else
151 return EXIT_FAILURE;
152} 106}
153/* 107
154Local Variables: 108/* vi: set sw=4 ts=4: */
155c-file-style: "linux"
156c-basic-offset: 4
157tab-width: 4
158End:
159*/