aboutsummaryrefslogtreecommitdiff
path: root/findutils/xargs.c
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2003-10-09 11:06:45 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2003-10-09 11:06:45 +0000
commit99825960c18de59afb6906ba05df5671793edaf0 (patch)
tree8a762c0b3f953ccc91786c09b03fe55862169c4b /findutils/xargs.c
parent29c77f71ba788fe9d63893e555c239d45905ebbc (diff)
downloadbusybox-w32-99825960c18de59afb6906ba05df5671793edaf0.tar.gz
busybox-w32-99825960c18de59afb6906ba05df5671793edaf0.tar.bz2
busybox-w32-99825960c18de59afb6906ba05df5671793edaf0.zip
Bugfix for xargs
Diffstat (limited to 'findutils/xargs.c')
-rw-r--r--findutils/xargs.c157
1 files changed, 99 insertions, 58 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c
index 27f83350f..1af42384b 100644
--- a/findutils/xargs.c
+++ b/findutils/xargs.c
@@ -27,17 +27,9 @@
27 * 27 *
28 * 28 *
29 * BUGS: 29 * BUGS:
30 * p option doesnt accept user input, should read input from /dev/tty 30 * - E option doesnt allow spaces before argument
31 * 31 * - exit value of isnt correct
32 * E option doesnt allow spaces before argument 32 * - doesnt print quoted string properly
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
40 *
41 */ 33 */
42 34
43#include <stdio.h> 35#include <stdio.h>
@@ -48,53 +40,77 @@
48#include <errno.h> 40#include <errno.h>
49#include <sys/types.h> 41#include <sys/types.h>
50#include <sys/wait.h> 42#include <sys/wait.h>
43
51#include "busybox.h" 44#include "busybox.h"
52 45
53/* 46/*
54 This function have special algorithm. 47 This function have special algorithm.
55 Don`t use fork and include to main! 48 Don`t use fork and include to main!
56*/ 49*/
57static void xargs_exec(char * const * args) 50static int xargs_exec(char **args)
58{ 51{
59 int p; 52 pid_t p;
60 int common[4]; /* shared vfork stack */ 53 volatile int exec_errno; /* shared vfork stack */
61 54
62 common[0] = 0; 55 exec_errno = 0;
63 if ((p = vfork()) >= 0) { 56 p = vfork();
64 if (p == 0) { 57 if (p < 0) {
65 /* vfork -- child */ 58 bb_perror_msg_and_die("vfork");
66 execvp(args[0], args); 59 } else if (p == 0) {
67 common[0] = errno; /* set error to shared stack */ 60 /* vfork -- child */
68 _exit(1); 61 execvp(args[0], args);
69 } else { 62 exec_errno = errno; /* set error to shared stack */
70 /* vfork -- parent */ 63 _exit(1);
71 wait(NULL); 64 } else {
72 if(common[0]) { 65 /* vfork -- parent */
73 errno = common[0]; 66 int status;
74 bb_perror_msg_and_die("%s", args[0]); 67
68 while (wait(&status) == (pid_t) - 1) {
69 if (errno != EINTR) {
70 break;
75 } 71 }
76 } 72 }
77 } else { 73
78 bb_perror_msg_and_die("vfork"); 74 if (exec_errno) {
75 errno = exec_errno;
76 bb_perror_msg("%s", args[0]);
77 return exec_errno == ENOENT ? 127 : 126;
78 } else if (WEXITSTATUS(status) == 255) {
79 bb_error_msg("%s: exited with status 255; aborting", args[0]);
80 return 124;
81 } else if (WIFSTOPPED(status)) {
82 bb_error_msg("%s: stopped by signal %d", args[0],
83 WSTOPSIG(status));
84 return 125;
85 } else if (WIFSIGNALED(status)) {
86 bb_error_msg("%s: terminated by signal %d", args[0],
87 WTERMSIG(status));
88 return 125;
89 } else if (WEXITSTATUS(status)) {
90 return 123;
91 } else {
92 return 0;
93 }
79 } 94 }
80} 95}
81 96
82#define OPT_VERBOSE 0x2 97#define OPT_VERBOSE 0x1
83#define OPT_INTERACTIVE 0x4 98#define OPT_TERMINATE 0x2
84#define OPT_TERMINATE 0x8 99#define OPT_UPTO_NUMBER 0x4
85#define OPT_UPTO_NUMBER 0x10 100#define OPT_UPTO_SIZE 0x8
86#define OPT_UPTO_SIZE 0x20 101#define OPT_EOF_STRING 0x10
87#define OPT_EOF_STRING 0x40
88 102
89int xargs_main(int argc, char **argv) 103int xargs_main(int argc, char **argv)
90{ 104{
105#ifdef CONFIG_FEATURE_XARGS_FANCY
91 char *s_max_args = NULL; 106 char *s_max_args = NULL;
92 char *s_line_size = NULL; 107 char *s_line_size = NULL;
108#endif
109 char *eof_string = "_";
93 unsigned long flg; 110 unsigned long flg;
94 111
95 char *eof_string = "_"; 112 int line_size;
96 int line_size = LINE_MAX; 113 unsigned int max_args = LINE_MAX;
97 unsigned int max_args = LINE_MAX / 2;
98 114
99 char *line_buffer = NULL; 115 char *line_buffer = NULL;
100 char *line_buffer_ptr_ptr; 116 char *line_buffer_ptr_ptr;
@@ -106,21 +122,35 @@ int xargs_main(int argc, char **argv)
106 int i; 122 int i;
107 int a; 123 int a;
108 124
125#if 0
126 /* Default to maximum line length */
127 if (LINE_MAX > ARG_MAX - 2048) {
128 /* Minimum command line length */
129 line_size = LINE_MAX;
130 } else {
131 /* Maximum command line length */
132 line_size = ARG_MAX = 2048;
133 }
134#else
135 line_size = LINE_MAX;
136#endif
109 137
110 bb_opt_complementaly = "pt"; 138#ifndef CONFIG_FEATURE_XARGS_FANCY
111 139 flg = bb_getopt_ulflags(argc, argv, "+t");
112 flg = bb_getopt_ulflags(argc, argv, "+tpxn:s:E::", &s_max_args, &s_line_size, &eof_string); 140#else
141 flg = bb_getopt_ulflags(argc, argv, "+txn:s:E::", &s_max_args, &s_line_size, &eof_string);
113 142
143 if (s_line_size) {
144 line_size = bb_xgetularg10_bnd(s_max_args, 1, line_size);
145 }
114 if (s_max_args) { 146 if (s_max_args) {
115 max_args = bb_xgetularg10(s_max_args); 147 max_args = bb_xgetularg10(s_max_args);
116 } 148 }
117 if (s_line_size) { 149#endif
118 line_size = bb_xgetularg10(s_line_size);
119 }
120 150
121 a = argc - optind; 151 a = argc - optind;
122 argv += optind; 152 argv += optind;
123 if(a==0) { 153 if (a == 0) {
124 /* default behavior is to echo all the filenames */ 154 /* default behavior is to echo all the filenames */
125 *argv = "echo"; 155 *argv = "echo";
126 a++; 156 a++;
@@ -158,13 +188,15 @@ int xargs_main(int argc, char **argv)
158 /* EOF, exit outer loop */ 188 /* EOF, exit outer loop */
159 break; 189 break;
160 } 190 }
161 line_buffer_ptr = strtok_r(line_buffer, " \t", &line_buffer_ptr_ptr); 191 line_buffer_ptr =
192 strtok_r(line_buffer, " \t", &line_buffer_ptr_ptr);
162 } else { 193 } else {
163 if (old_arg) { 194 if (old_arg) {
164 line_buffer_ptr = old_arg; 195 line_buffer_ptr = old_arg;
165 old_arg = NULL; 196 old_arg = NULL;
166 } else { 197 } else {
167 line_buffer_ptr = strtok_r(NULL, " \t", &line_buffer_ptr_ptr); 198 line_buffer_ptr =
199 strtok_r(NULL, " \t", &line_buffer_ptr_ptr);
168 } 200 }
169 } 201 }
170 /* If no arguments left go back and get another line */ 202 /* If no arguments left go back and get another line */
@@ -174,7 +206,11 @@ int xargs_main(int argc, char **argv)
174 continue; 206 continue;
175 } 207 }
176 208
209#ifdef CONFIG_FEATURE_XARGS_FANCY
177 if (eof_string && (strcmp(line_buffer_ptr, eof_string) == 0)) { 210 if (eof_string && (strcmp(line_buffer_ptr, eof_string) == 0)) {
211#else
212 if (strcmp(line_buffer_ptr, eof_string) == 0) {
213#endif
178 /* logical EOF, exit outer loop */ 214 /* logical EOF, exit outer loop */
179 line_buffer = NULL; 215 line_buffer = NULL;
180 break; 216 break;
@@ -183,7 +219,12 @@ int xargs_main(int argc, char **argv)
183 /* Check the next argument will fit */ 219 /* Check the next argument will fit */
184 arg_size += 1 + strlen(line_buffer_ptr); 220 arg_size += 1 + strlen(line_buffer_ptr);
185 if (arg_size > line_size) { 221 if (arg_size > line_size) {
186 if ((arg_count == 0) || ((flg & OPT_TERMINATE) && (arg_count != max_args))){ 222 if ((arg_count == 0)
223#ifdef CONFIG_FEATURE_XARGS_FANCY
224 || ((flg & OPT_TERMINATE) && (arg_count != max_args))) {
225#else
226 ) {
227#endif
187 bb_error_msg_and_die("argument line too long"); 228 bb_error_msg_and_die("argument line too long");
188 } 229 }
189 old_arg = line_buffer_ptr; 230 old_arg = line_buffer_ptr;
@@ -196,20 +237,20 @@ int xargs_main(int argc, char **argv)
196 arg_count++; 237 arg_count++;
197 } while (arg_count < max_args); 238 } while (arg_count < max_args);
198 239
240 /* Remove the last space */
241 args_entry_ptr[arg_size - 1] = '\0';
242
199 if (*args_entry_ptr != '\0') { 243 if (*args_entry_ptr != '\0') {
200 if(flg & (OPT_VERBOSE | OPT_INTERACTIVE)) { 244 if (flg & OPT_VERBOSE) {
201 for(i=0; args[i]; i++) { 245 for (i = 0; args[i]; i++) {
202 if(i) 246 if (i) {
203 fputc(' ', stderr); 247 fputc(' ', stderr);
248 }
204 fputs(args[i], stderr); 249 fputs(args[i], stderr);
205 } 250 }
206 251 fputc('\n', stderr);
207 fputs(((flg & OPT_INTERACTIVE) ? " ?..." : "\n"), stderr);
208 }
209
210 if((flg & OPT_INTERACTIVE) == 0 || bb_ask_confirmation() != 0 ) {
211 xargs_exec(args);
212 } 252 }
253 xargs_exec(args);
213 } 254 }
214 } while (line_buffer); 255 } while (line_buffer);
215 256