diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-10-04 14:44:27 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-10-04 14:44:27 +0000 |
commit | add3eadc4691a1870980abb925a7424e13fde344 (patch) | |
tree | 707e6582eb47c29f223d3ef5ce35ad49059e868b /findutils/xargs.c | |
parent | 42c25735e6be3b4af504ae098cf287d259f6b37c (diff) | |
download | busybox-w32-add3eadc4691a1870980abb925a7424e13fde344.tar.gz busybox-w32-add3eadc4691a1870980abb925a7424e13fde344.tar.bz2 busybox-w32-add3eadc4691a1870980abb925a7424e13fde344.zip |
Add the x, n, s and E options, remove -r as its expected behaviour.
Diffstat (limited to 'findutils/xargs.c')
-rw-r--r-- | findutils/xargs.c | 129 |
1 files changed, 115 insertions, 14 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c index 298c000dc..27f83350f 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Only "-prt" options are supported in this version of xargs. | 3 | * Only "-prt" options are supported in this version of xargs. |
4 | * | 4 | * |
5 | * (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru> | 5 | * (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru> |
6 | * (C) 2003 by Glenn McGrath <bug1@optushome.com.au> | ||
6 | * | 7 | * |
7 | * Special thanks Mark Whitley for stimul to rewrote :) | 8 | * Special thanks Mark Whitley for stimul to rewrote :) |
8 | * | 9 | * |
@@ -20,12 +21,28 @@ | |||
20 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
22 | * | 23 | * |
23 | * BUGS: -p doesnt accept user input | 24 | * |
25 | * Reference: | ||
26 | * http://www.opengroup.org/onlinepubs/007904975/utilities/xargs.html | ||
27 | * | ||
28 | * | ||
29 | * BUGS: | ||
30 | * p option doesnt accept user input, should read input from /dev/tty | ||
31 | * | ||
32 | * E option doesnt allow spaces before argument | ||
33 | * | ||
34 | * xargs should terminate if an invocation of a constructed command line | ||
35 | * returns an exit status of 255. | ||
36 | * | ||
37 | * exit value of isnt correct | ||
38 | * | ||
39 | * doesnt print quoted string properly | ||
24 | * | 40 | * |
25 | */ | 41 | */ |
26 | 42 | ||
27 | #include <stdio.h> | 43 | #include <stdio.h> |
28 | #include <stdlib.h> | 44 | #include <stdlib.h> |
45 | #include <string.h> | ||
29 | #include <unistd.h> | 46 | #include <unistd.h> |
30 | #include <getopt.h> | 47 | #include <getopt.h> |
31 | #include <errno.h> | 48 | #include <errno.h> |
@@ -33,7 +50,6 @@ | |||
33 | #include <sys/wait.h> | 50 | #include <sys/wait.h> |
34 | #include "busybox.h" | 51 | #include "busybox.h" |
35 | 52 | ||
36 | |||
37 | /* | 53 | /* |
38 | This function have special algorithm. | 54 | This function have special algorithm. |
39 | Don`t use fork and include to main! | 55 | Don`t use fork and include to main! |
@@ -65,17 +81,42 @@ static void xargs_exec(char * const * args) | |||
65 | 81 | ||
66 | #define OPT_VERBOSE 0x2 | 82 | #define OPT_VERBOSE 0x2 |
67 | #define OPT_INTERACTIVE 0x4 | 83 | #define OPT_INTERACTIVE 0x4 |
68 | #define OPT_NO_EMPTY 0x8 | 84 | #define OPT_TERMINATE 0x8 |
85 | #define OPT_UPTO_NUMBER 0x10 | ||
86 | #define OPT_UPTO_SIZE 0x20 | ||
87 | #define OPT_EOF_STRING 0x40 | ||
69 | 88 | ||
70 | int xargs_main(int argc, char **argv) | 89 | int xargs_main(int argc, char **argv) |
71 | { | 90 | { |
72 | char *file_to_act_on; | 91 | char *s_max_args = NULL; |
73 | char **args; | 92 | char *s_line_size = NULL; |
74 | int i, a; | ||
75 | unsigned long flg; | 93 | unsigned long flg; |
76 | 94 | ||
95 | char *eof_string = "_"; | ||
96 | int line_size = LINE_MAX; | ||
97 | unsigned int max_args = LINE_MAX / 2; | ||
98 | |||
99 | char *line_buffer = NULL; | ||
100 | char *line_buffer_ptr_ptr; | ||
101 | char *old_arg = NULL; | ||
102 | |||
103 | char **args; | ||
104 | char *args_entry_ptr; | ||
105 | |||
106 | int i; | ||
107 | int a; | ||
108 | |||
109 | |||
77 | bb_opt_complementaly = "pt"; | 110 | bb_opt_complementaly = "pt"; |
78 | flg = bb_getopt_ulflags(argc, argv, "+tpr"); | 111 | |
112 | flg = bb_getopt_ulflags(argc, argv, "+tpxn:s:E::", &s_max_args, &s_line_size, &eof_string); | ||
113 | |||
114 | if (s_max_args) { | ||
115 | max_args = bb_xgetularg10(s_max_args); | ||
116 | } | ||
117 | if (s_line_size) { | ||
118 | line_size = bb_xgetularg10(s_line_size); | ||
119 | } | ||
79 | 120 | ||
80 | a = argc - optind; | 121 | a = argc - optind; |
81 | argv += optind; | 122 | argv += optind; |
@@ -88,20 +129,81 @@ int xargs_main(int argc, char **argv) | |||
88 | args = xcalloc(a + 2, sizeof(char *)); | 129 | args = xcalloc(a + 2, sizeof(char *)); |
89 | 130 | ||
90 | /* Store the command to be executed (taken from the command line) */ | 131 | /* Store the command to be executed (taken from the command line) */ |
91 | for (i = 0; i < a; i++) | 132 | for (i = 0; i < a; i++) { |
133 | line_size -= strlen(*argv) + 1; | ||
92 | args[i] = *argv++; | 134 | args[i] = *argv++; |
135 | } | ||
136 | if (line_size < 1) { | ||
137 | bb_error_msg_and_die("can not fit single argument within argument list size limit"); | ||
138 | } | ||
139 | |||
140 | args[i] = xmalloc(line_size); | ||
141 | args_entry_ptr = args[i]; | ||
93 | 142 | ||
94 | /* Now, read in one line at a time from stdin, and store this | 143 | /* Now, read in one line at a time from stdin, and store this |
95 | * line to be used later as an argument to the command */ | 144 | * line to be used later as an argument to the command */ |
96 | while ((file_to_act_on = bb_get_chomped_line_from_file(stdin)) != NULL) { | 145 | do { |
97 | if(file_to_act_on[0] != 0 || (flg & OPT_NO_EMPTY) == 0) { | 146 | char *line_buffer_ptr = NULL; |
98 | args[a] = file_to_act_on[0] ? file_to_act_on : NULL; | 147 | unsigned int arg_count = 0; |
148 | unsigned int arg_size = 0; | ||
149 | |||
150 | *args_entry_ptr = '\0'; | ||
151 | |||
152 | /* Get the required number of entries from stdin */ | ||
153 | do { | ||
154 | /* (Re)fill the line buffer */ | ||
155 | if (line_buffer == NULL) { | ||
156 | line_buffer = bb_get_chomped_line_from_file(stdin); | ||
157 | if (line_buffer == NULL) { | ||
158 | /* EOF, exit outer loop */ | ||
159 | break; | ||
160 | } | ||
161 | line_buffer_ptr = strtok_r(line_buffer, " \t", &line_buffer_ptr_ptr); | ||
162 | } else { | ||
163 | if (old_arg) { | ||
164 | line_buffer_ptr = old_arg; | ||
165 | old_arg = NULL; | ||
166 | } else { | ||
167 | line_buffer_ptr = strtok_r(NULL, " \t", &line_buffer_ptr_ptr); | ||
168 | } | ||
169 | } | ||
170 | /* If no arguments left go back and get another line */ | ||
171 | if (line_buffer_ptr == NULL) { | ||
172 | free(line_buffer); | ||
173 | line_buffer = NULL; | ||
174 | continue; | ||
175 | } | ||
176 | |||
177 | if (eof_string && (strcmp(line_buffer_ptr, eof_string) == 0)) { | ||
178 | /* logical EOF, exit outer loop */ | ||
179 | line_buffer = NULL; | ||
180 | break; | ||
181 | } | ||
182 | |||
183 | /* Check the next argument will fit */ | ||
184 | arg_size += 1 + strlen(line_buffer_ptr); | ||
185 | if (arg_size > line_size) { | ||
186 | if ((arg_count == 0) || ((flg & OPT_TERMINATE) && (arg_count != max_args))){ | ||
187 | bb_error_msg_and_die("argument line too long"); | ||
188 | } | ||
189 | old_arg = line_buffer_ptr; | ||
190 | break; | ||
191 | } | ||
192 | |||
193 | /* Add the entry to our pre-allocated space */ | ||
194 | strcat(args_entry_ptr, line_buffer_ptr); | ||
195 | strcat(args_entry_ptr, " "); | ||
196 | arg_count++; | ||
197 | } while (arg_count < max_args); | ||
198 | |||
199 | if (*args_entry_ptr != '\0') { | ||
99 | if(flg & (OPT_VERBOSE | OPT_INTERACTIVE)) { | 200 | if(flg & (OPT_VERBOSE | OPT_INTERACTIVE)) { |
100 | for(i=0; args[i]; i++) { | 201 | for(i=0; args[i]; i++) { |
101 | if(i) | 202 | if(i) |
102 | fputc(' ', stderr); | 203 | fputc(' ', stderr); |
103 | fputs(args[i], stderr); | 204 | fputs(args[i], stderr); |
104 | } | 205 | } |
206 | |||
105 | fputs(((flg & OPT_INTERACTIVE) ? " ?..." : "\n"), stderr); | 207 | fputs(((flg & OPT_INTERACTIVE) ? " ?..." : "\n"), stderr); |
106 | } | 208 | } |
107 | 209 | ||
@@ -109,9 +211,8 @@ int xargs_main(int argc, char **argv) | |||
109 | xargs_exec(args); | 211 | xargs_exec(args); |
110 | } | 212 | } |
111 | } | 213 | } |
112 | /* clean up */ | 214 | } while (line_buffer); |
113 | free(file_to_act_on); | 215 | |
114 | } | ||
115 | #ifdef CONFIG_FEATURE_CLEAN_UP | 216 | #ifdef CONFIG_FEATURE_CLEAN_UP |
116 | free(args); | 217 | free(args); |
117 | #endif | 218 | #endif |