diff options
| author | Glenn L McGrath <bug1@ihug.co.nz> | 2003-10-30 22:47:16 +0000 |
|---|---|---|
| committer | Glenn L McGrath <bug1@ihug.co.nz> | 2003-10-30 22:47:16 +0000 |
| commit | 09c295a5bc40f27612cc6375c7c4de3eb16efdf0 (patch) | |
| tree | 5bbc81dd827a011c43f9afe8c9cd6ee3394dfba9 /findutils | |
| parent | 00ed36fd5248de9a612d9417918c5a44406d4644 (diff) | |
| download | busybox-w32-09c295a5bc40f27612cc6375c7c4de3eb16efdf0.tar.gz busybox-w32-09c295a5bc40f27612cc6375c7c4de3eb16efdf0.tar.bz2 busybox-w32-09c295a5bc40f27612cc6375c7c4de3eb16efdf0.zip | |
run through indent
Diffstat (limited to 'findutils')
| -rw-r--r-- | findutils/xargs.c | 779 |
1 files changed, 392 insertions, 387 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c index 8bab44623..e2e6d3abd 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
| @@ -65,52 +65,52 @@ | |||
| 65 | This function have special algorithm. | 65 | This function have special algorithm. |
| 66 | Don`t use fork and include to main! | 66 | Don`t use fork and include to main! |
| 67 | */ | 67 | */ |
| 68 | static int | 68 | static int xargs_exec(char *const *args) |
| 69 | xargs_exec (char *const *args) | ||
| 70 | { | 69 | { |
| 71 | pid_t p; | 70 | pid_t p; |
| 72 | volatile int exec_errno = 0; /* shared vfork stack */ | 71 | volatile int exec_errno = 0; /* shared vfork stack */ |
| 73 | 72 | ||
| 74 | if ((p = vfork ()) >= 0) { | 73 | if ((p = vfork()) >= 0) { |
| 75 | if (p == 0) { | 74 | if (p == 0) { |
| 76 | /* vfork -- child */ | 75 | /* vfork -- child */ |
| 77 | execvp (args[0], args); | 76 | execvp(args[0], args); |
| 78 | exec_errno = errno; /* set error to shared stack */ | 77 | exec_errno = errno; /* set error to shared stack */ |
| 79 | _exit (1); | 78 | _exit(1); |
| 80 | } else { | 79 | } else { |
| 81 | /* vfork -- parent */ | 80 | /* vfork -- parent */ |
| 82 | int status; | 81 | int status; |
| 83 | 82 | ||
| 84 | while (wait (&status) == (pid_t) - 1) | 83 | while (wait(&status) == (pid_t) - 1) |
| 85 | if (errno != EINTR) | 84 | if (errno != EINTR) |
| 86 | break; | 85 | break; |
| 87 | if (exec_errno) { | 86 | if (exec_errno) { |
| 88 | errno = exec_errno; | 87 | errno = exec_errno; |
| 89 | bb_perror_msg ("%s", args[0]); | 88 | bb_perror_msg("%s", args[0]); |
| 90 | return exec_errno == ENOENT ? 127 : 126; | 89 | return exec_errno == ENOENT ? 127 : 126; |
| 91 | } else { | 90 | } else { |
| 92 | if (WEXITSTATUS (status) == 255) { | 91 | if (WEXITSTATUS(status) == 255) { |
| 93 | bb_error_msg ("%s: exited with status 255; aborting", args[0]); | 92 | bb_error_msg("%s: exited with status 255; aborting", |
| 94 | return 124; | 93 | args[0]); |
| 95 | } | 94 | return 124; |
| 96 | if (WIFSTOPPED (status)) { | 95 | } |
| 97 | bb_error_msg ("%s: stopped by signal %d", args[0], | 96 | if (WIFSTOPPED(status)) { |
| 98 | WSTOPSIG (status)); | 97 | bb_error_msg("%s: stopped by signal %d", args[0], |
| 99 | return 125; | 98 | WSTOPSIG(status)); |
| 100 | } | 99 | return 125; |
| 101 | if (WIFSIGNALED (status)) { | 100 | } |
| 102 | bb_error_msg ("%s: terminated by signal %d", args[0], | 101 | if (WIFSIGNALED(status)) { |
| 103 | WTERMSIG (status)); | 102 | bb_error_msg("%s: terminated by signal %d", args[0], |
| 104 | return 125; | 103 | WTERMSIG(status)); |
| 104 | return 125; | ||
| 105 | } | ||
| 106 | if (WEXITSTATUS(status) != 0) | ||
| 107 | return 123; | ||
| 108 | return 0; | ||
| 109 | } | ||
| 105 | } | 110 | } |
| 106 | if (WEXITSTATUS (status) != 0) | 111 | } else { |
| 107 | return 123; | 112 | bb_perror_msg_and_die("vfork"); |
| 108 | return 0; | ||
| 109 | } | ||
| 110 | } | 113 | } |
| 111 | } else { | ||
| 112 | bb_perror_msg_and_die ("vfork"); | ||
| 113 | } | ||
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | 116 | ||
| @@ -127,207 +127,208 @@ static int eof_stdin_detected; | |||
| 127 | || (c) == '\f' || (c) == '\v') | 127 | || (c) == '\f' || (c) == '\v') |
| 128 | 128 | ||
| 129 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_QUOTES | 129 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_QUOTES |
| 130 | static xlist_t * | 130 | static xlist_t *process_stdin(xlist_t * list_arg, const char *eof_str, |
| 131 | process_stdin (xlist_t *list_arg, const char *eof_str, size_t mc, char *buf) | 131 | size_t mc, char *buf) |
| 132 | { | 132 | { |
| 133 | #define NORM 0 | 133 | #define NORM 0 |
| 134 | #define QUOTE 1 | 134 | #define QUOTE 1 |
| 135 | #define BACKSLASH 2 | 135 | #define BACKSLASH 2 |
| 136 | #define SPACE 4 | 136 | #define SPACE 4 |
| 137 | 137 | ||
| 138 | char *s = NULL; /* start word */ | 138 | char *s = NULL; /* start word */ |
| 139 | char *p = NULL; /* pointer to end word */ | 139 | char *p = NULL; /* pointer to end word */ |
| 140 | char q = 0; /* quote char */ | 140 | char q = 0; /* quote char */ |
| 141 | char state = NORM; | 141 | char state = NORM; |
| 142 | char eof_str_detected = 0; | 142 | char eof_str_detected = 0; |
| 143 | size_t line_l = 0; /* size loaded args line */ | 143 | size_t line_l = 0; /* size loaded args line */ |
| 144 | int c; /* current char */ | 144 | int c; /* current char */ |
| 145 | xlist_t *cur; | 145 | xlist_t *cur; |
| 146 | xlist_t *prev; | 146 | xlist_t *prev; |
| 147 | 147 | ||
| 148 | for(prev = cur = list_arg; cur; cur = cur->link) { | 148 | for (prev = cur = list_arg; cur; cur = cur->link) { |
| 149 | line_l += cur->lenght; /* previous allocated */ | 149 | line_l += cur->lenght; /* previous allocated */ |
| 150 | if(prev != cur) | 150 | if (prev != cur) |
| 151 | prev = prev->link; | 151 | prev = prev->link; |
| 152 | } | ||
| 153 | |||
| 154 | while(!eof_stdin_detected) { | ||
| 155 | c = getchar(); | ||
| 156 | if(c == EOF) { | ||
| 157 | eof_stdin_detected++; | ||
| 158 | if(s) | ||
| 159 | goto unexpected_eof; | ||
| 160 | break; | ||
| 161 | } | 152 | } |
| 162 | if(eof_str_detected) | 153 | |
| 163 | continue; | 154 | while (!eof_stdin_detected) { |
| 164 | if (state == BACKSLASH) { | 155 | c = getchar(); |
| 165 | state = NORM; | 156 | if (c == EOF) { |
| 166 | goto set; | 157 | eof_stdin_detected++; |
| 167 | } else if (state == QUOTE) { | 158 | if (s) |
| 168 | if (c == q) { | 159 | goto unexpected_eof; |
| 169 | q = 0; | 160 | break; |
| 170 | state = NORM; | ||
| 171 | } else { | ||
| 172 | goto set; | ||
| 173 | } | ||
| 174 | } else /* if(state == NORM) */ { | ||
| 175 | if (ISSPACE (c)) { | ||
| 176 | if (s) { | ||
| 177 | unexpected_eof: | ||
| 178 | state = SPACE; | ||
| 179 | c = 0; | ||
| 180 | goto set; | ||
| 181 | } | 161 | } |
| 182 | } else { | 162 | if (eof_str_detected) |
| 183 | if (s == NULL) | 163 | continue; |
| 184 | s = p = buf; | 164 | if (state == BACKSLASH) { |
| 185 | if (c == '\\') { | 165 | state = NORM; |
| 186 | state = BACKSLASH; | 166 | goto set; |
| 187 | } else if (c == '\'' || c == '"') { | 167 | } else if (state == QUOTE) { |
| 188 | q = c; | 168 | if (c == q) { |
| 189 | state = QUOTE; | 169 | q = 0; |
| 190 | } else { | 170 | state = NORM; |
| 191 | set: | 171 | } else { |
| 192 | if( (p-buf) >= mc) | 172 | goto set; |
| 193 | bb_error_msg_and_die ("argument line too long"); | 173 | } |
| 194 | *p++ = c; | 174 | } else { /* if(state == NORM) */ |
| 175 | |||
| 176 | if (ISSPACE(c)) { | ||
| 177 | if (s) { | ||
| 178 | unexpected_eof: | ||
| 179 | state = SPACE; | ||
| 180 | c = 0; | ||
| 181 | goto set; | ||
| 182 | } | ||
| 183 | } else { | ||
| 184 | if (s == NULL) | ||
| 185 | s = p = buf; | ||
| 186 | if (c == '\\') { | ||
| 187 | state = BACKSLASH; | ||
| 188 | } else if (c == '\'' || c == '"') { | ||
| 189 | q = c; | ||
| 190 | state = QUOTE; | ||
| 191 | } else { | ||
| 192 | set: | ||
| 193 | if ((p - buf) >= mc) | ||
| 194 | bb_error_msg_and_die("argument line too long"); | ||
| 195 | *p++ = c; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | } | ||
| 199 | if (state == SPACE) { /* word's delimiter or EOF detected */ | ||
| 200 | if (q) | ||
| 201 | bb_error_msg_and_die("unmatched %s quote", | ||
| 202 | q == '\'' ? "single" : "double"); | ||
| 203 | /* word loaded */ | ||
| 204 | if (eof_str) { | ||
| 205 | eof_str_detected = strcmp(s, eof_str) == 0; | ||
| 206 | } | ||
| 207 | if (!eof_str_detected) { | ||
| 208 | size_t lenght = (p - buf); | ||
| 209 | |||
| 210 | cur = xmalloc(sizeof(xlist_t) + lenght); | ||
| 211 | cur->data = memcpy(cur + 1, s, lenght); | ||
| 212 | cur->lenght = lenght; | ||
| 213 | cur->link = NULL; | ||
| 214 | if (prev == NULL) { | ||
| 215 | list_arg = cur; | ||
| 216 | } else { | ||
| 217 | prev->link = cur; | ||
| 218 | } | ||
| 219 | prev = cur; | ||
| 220 | line_l += lenght; | ||
| 221 | if (line_l > mc) { | ||
| 222 | /* stop memory usage :-) */ | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | } | ||
| 226 | s = NULL; | ||
| 227 | state = NORM; | ||
| 195 | } | 228 | } |
| 196 | } | ||
| 197 | } | ||
| 198 | if (state == SPACE) { /* word's delimiter or EOF detected */ | ||
| 199 | if (q) | ||
| 200 | bb_error_msg_and_die ("unmatched %s quote", | ||
| 201 | q == '\'' ? "single" : "double"); | ||
| 202 | /* word loaded */ | ||
| 203 | if(eof_str) { | ||
| 204 | eof_str_detected = strcmp(s, eof_str) == 0; | ||
| 205 | } | ||
| 206 | if(!eof_str_detected) { | ||
| 207 | size_t lenght = (p-buf); | ||
| 208 | |||
| 209 | cur = xmalloc(sizeof(xlist_t) + lenght); | ||
| 210 | cur->data = memcpy(cur + 1, s, lenght); | ||
| 211 | cur->lenght = lenght; | ||
| 212 | cur->link = NULL; | ||
| 213 | if(prev == NULL) { | ||
| 214 | list_arg = cur; | ||
| 215 | } else { | ||
| 216 | prev->link = cur; | ||
| 217 | } | ||
| 218 | prev = cur; | ||
| 219 | line_l += lenght; | ||
| 220 | if(line_l > mc) { | ||
| 221 | /* stop memory usage :-) */ | ||
| 222 | break; | ||
| 223 | } | ||
| 224 | } | ||
| 225 | s = NULL; | ||
| 226 | state = NORM; | ||
| 227 | } | 229 | } |
| 228 | } | 230 | return list_arg; |
| 229 | return list_arg; | ||
| 230 | } | 231 | } |
| 231 | #else | 232 | #else |
| 232 | /* The variant is unsupport single, double quotes and backslash */ | 233 | /* The variant is unsupport single, double quotes and backslash */ |
| 233 | static xlist_t * | 234 | static xlist_t *process_stdin(xlist_t * list_arg, const char *eof_str, |
| 234 | process_stdin (xlist_t *list_arg, const char *eof_str, size_t mc, char *buf) | 235 | size_t mc, char *buf) |
| 235 | { | 236 | { |
| 236 | 237 | ||
| 237 | int c; /* current char */ | 238 | int c; /* current char */ |
| 238 | int eof_str_detected = 0; | 239 | int eof_str_detected = 0; |
| 239 | char *s = NULL; /* start word */ | 240 | char *s = NULL; /* start word */ |
| 240 | char *p = NULL; /* pointer to end word */ | 241 | char *p = NULL; /* pointer to end word */ |
| 241 | size_t line_l = 0; /* size loaded args line */ | 242 | size_t line_l = 0; /* size loaded args line */ |
| 242 | xlist_t *cur; | 243 | xlist_t *cur; |
| 243 | xlist_t *prev; | 244 | xlist_t *prev; |
| 244 | 245 | ||
| 245 | for(prev = cur = list_arg; cur; cur = cur->link) { | 246 | for (prev = cur = list_arg; cur; cur = cur->link) { |
| 246 | line_l += cur->lenght; /* previous allocated */ | 247 | line_l += cur->lenght; /* previous allocated */ |
| 247 | if(prev != cur) | 248 | if (prev != cur) |
| 248 | prev = prev->link; | 249 | prev = prev->link; |
| 249 | } | ||
| 250 | |||
| 251 | while(!eof_stdin_detected) { | ||
| 252 | c = getchar(); | ||
| 253 | if(c == EOF) { | ||
| 254 | eof_stdin_detected++; | ||
| 255 | } | ||
| 256 | if(eof_str_detected) | ||
| 257 | continue; | ||
| 258 | if (c == EOF || ISSPACE (c)) { | ||
| 259 | if(s == NULL) | ||
| 260 | continue; | ||
| 261 | c = EOF; | ||
| 262 | } | 250 | } |
| 263 | if (s == NULL) | 251 | |
| 264 | s = p = buf; | 252 | while (!eof_stdin_detected) { |
| 265 | if( (p-buf) >= mc) | 253 | c = getchar(); |
| 266 | bb_error_msg_and_die ("argument line too long"); | 254 | if (c == EOF) { |
| 267 | *p++ = c == EOF ? 0 : c; | 255 | eof_stdin_detected++; |
| 268 | if (c == EOF) { /* word's delimiter or EOF detected */ | ||
| 269 | /* word loaded */ | ||
| 270 | if(eof_str) { | ||
| 271 | eof_str_detected = strcmp(s, eof_str) == 0; | ||
| 272 | } | ||
| 273 | if(!eof_str_detected) { | ||
| 274 | size_t lenght = (p-buf); | ||
| 275 | |||
| 276 | cur = xmalloc(sizeof(xlist_t) + lenght); | ||
| 277 | cur->data = memcpy(cur + 1, s, lenght); | ||
| 278 | cur->lenght = lenght; | ||
| 279 | cur->link = NULL; | ||
| 280 | if(prev == NULL) { | ||
| 281 | list_arg = cur; | ||
| 282 | } else { | ||
| 283 | prev->link = cur; | ||
| 284 | } | 256 | } |
| 285 | prev = cur; | 257 | if (eof_str_detected) |
| 286 | line_l += lenght; | 258 | continue; |
| 287 | if(line_l > mc) { | 259 | if (c == EOF || ISSPACE(c)) { |
| 288 | /* stop memory usage :-) */ | 260 | if (s == NULL) |
| 289 | break; | 261 | continue; |
| 262 | c = EOF; | ||
| 263 | } | ||
| 264 | if (s == NULL) | ||
| 265 | s = p = buf; | ||
| 266 | if ((p - buf) >= mc) | ||
| 267 | bb_error_msg_and_die("argument line too long"); | ||
| 268 | *p++ = c == EOF ? 0 : c; | ||
| 269 | if (c == EOF) { /* word's delimiter or EOF detected */ | ||
| 270 | /* word loaded */ | ||
| 271 | if (eof_str) { | ||
| 272 | eof_str_detected = strcmp(s, eof_str) == 0; | ||
| 273 | } | ||
| 274 | if (!eof_str_detected) { | ||
| 275 | size_t lenght = (p - buf); | ||
| 276 | |||
| 277 | cur = xmalloc(sizeof(xlist_t) + lenght); | ||
| 278 | cur->data = memcpy(cur + 1, s, lenght); | ||
| 279 | cur->lenght = lenght; | ||
| 280 | cur->link = NULL; | ||
| 281 | if (prev == NULL) { | ||
| 282 | list_arg = cur; | ||
| 283 | } else { | ||
| 284 | prev->link = cur; | ||
| 285 | } | ||
| 286 | prev = cur; | ||
| 287 | line_l += lenght; | ||
| 288 | if (line_l > mc) { | ||
| 289 | /* stop memory usage :-) */ | ||
| 290 | break; | ||
| 291 | } | ||
| 292 | s = NULL; | ||
| 293 | } | ||
| 290 | } | 294 | } |
| 291 | s = NULL; | ||
| 292 | } | ||
| 293 | } | 295 | } |
| 294 | } | 296 | return list_arg; |
| 295 | return list_arg; | ||
| 296 | } | 297 | } |
| 297 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_QUOTES */ | 298 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_QUOTES */ |
| 298 | 299 | ||
| 299 | 300 | ||
| 300 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION | 301 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION |
| 301 | /* Prompt the user for a response, and | 302 | /* Prompt the user for a response, and |
| 302 | if the user responds affirmatively, return true; | 303 | if the user responds affirmatively, return true; |
| 303 | otherwise, return false. Used "/dev/tty", not stdin. */ | 304 | otherwise, return false. Used "/dev/tty", not stdin. */ |
| 304 | static int | 305 | static int xargs_ask_confirmation(void) |
| 305 | xargs_ask_confirmation (void) | ||
| 306 | { | 306 | { |
| 307 | static FILE *tty_stream; | 307 | static FILE *tty_stream; |
| 308 | int c, savec; | 308 | int c, savec; |
| 309 | 309 | ||
| 310 | if (!tty_stream) { | 310 | if (!tty_stream) { |
| 311 | tty_stream = fopen ("/dev/tty", "r"); | 311 | tty_stream = fopen("/dev/tty", "r"); |
| 312 | if (!tty_stream) | 312 | if (!tty_stream) |
| 313 | bb_perror_msg_and_die ("/dev/tty"); | 313 | bb_perror_msg_and_die("/dev/tty"); |
| 314 | /* pranoidal security by vodz */ | 314 | /* pranoidal security by vodz */ |
| 315 | fcntl(fileno(tty_stream), F_SETFD, FD_CLOEXEC); | 315 | fcntl(fileno(tty_stream), F_SETFD, FD_CLOEXEC); |
| 316 | } | 316 | } |
| 317 | fputs (" ?...", stderr); | 317 | fputs(" ?...", stderr); |
| 318 | fflush (stderr); | 318 | fflush(stderr); |
| 319 | c = savec = getc (tty_stream); | 319 | c = savec = getc(tty_stream); |
| 320 | while (c != EOF && c != '\n') | 320 | while (c != EOF && c != '\n') |
| 321 | c = getc (tty_stream); | 321 | c = getc(tty_stream); |
| 322 | if (savec == 'y' || savec == 'Y') | 322 | if (savec == 'y' || savec == 'Y') |
| 323 | return 1; | 323 | return 1; |
| 324 | return 0; | 324 | return 0; |
| 325 | } | 325 | } |
| 326 | |||
| 326 | # define OPT_INC_P 1 | 327 | # define OPT_INC_P 1 |
| 327 | #else | 328 | #else |
| 328 | # define OPT_INC_P 0 | 329 | # define OPT_INC_P 0 |
| 329 | # define xargs_ask_confirmation() 1 | 330 | # define xargs_ask_confirmation() 1 |
| 330 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION */ | 331 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION */ |
| 331 | 332 | ||
| 332 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT | 333 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT |
| 333 | # define OPT_INC_X 1 | 334 | # define OPT_INC_X 1 |
| @@ -336,65 +337,66 @@ xargs_ask_confirmation (void) | |||
| 336 | #endif | 337 | #endif |
| 337 | 338 | ||
| 338 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM | 339 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM |
| 339 | static xlist_t * | 340 | static xlist_t *process0_stdin(xlist_t * list_arg, const char *eof_str, |
| 340 | process0_stdin (xlist_t *list_arg, const char *eof_str, size_t mc, char *buf) | 341 | size_t mc, char *buf) |
| 341 | { | 342 | { |
| 342 | int c; /* current char */ | 343 | int c; /* current char */ |
| 343 | char *s = NULL; /* start word */ | 344 | char *s = NULL; /* start word */ |
| 344 | char *p = NULL; /* pointer to end word */ | 345 | char *p = NULL; /* pointer to end word */ |
| 345 | size_t line_l = 0; /* size loaded args line */ | 346 | size_t line_l = 0; /* size loaded args line */ |
| 346 | xlist_t *cur; | 347 | xlist_t *cur; |
| 347 | xlist_t *prev; | 348 | xlist_t *prev; |
| 348 | 349 | ||
| 349 | for(prev = cur = list_arg; cur; cur = cur->link) { | 350 | for (prev = cur = list_arg; cur; cur = cur->link) { |
| 350 | line_l += cur->lenght; /* previous allocated */ | 351 | line_l += cur->lenght; /* previous allocated */ |
| 351 | if(prev != cur) | 352 | if (prev != cur) |
| 352 | prev = prev->link; | 353 | prev = prev->link; |
| 353 | } | ||
| 354 | |||
| 355 | while(!eof_stdin_detected) { | ||
| 356 | c = getchar(); | ||
| 357 | if(c == EOF) { | ||
| 358 | eof_stdin_detected++; | ||
| 359 | if(s == NULL) | ||
| 360 | break; | ||
| 361 | c = 0; | ||
| 362 | } | 354 | } |
| 363 | if (s == NULL) | 355 | |
| 364 | s = p = buf; | 356 | while (!eof_stdin_detected) { |
| 365 | if( (p-buf) >= mc) | 357 | c = getchar(); |
| 366 | bb_error_msg_and_die ("argument line too long"); | 358 | if (c == EOF) { |
| 367 | *p++ = c; | 359 | eof_stdin_detected++; |
| 368 | if (c == 0) { /* word's delimiter or EOF detected */ | 360 | if (s == NULL) |
| 369 | /* word loaded */ | 361 | break; |
| 370 | size_t lenght = (p-buf); | 362 | c = 0; |
| 371 | |||
| 372 | cur = xmalloc(sizeof(xlist_t) + lenght); | ||
| 373 | cur->data = memcpy(cur + 1, s, lenght); | ||
| 374 | cur->lenght = lenght; | ||
| 375 | cur->link = NULL; | ||
| 376 | if(prev == NULL) { | ||
| 377 | list_arg = cur; | ||
| 378 | } else { | ||
| 379 | prev->link = cur; | ||
| 380 | } | 363 | } |
| 381 | prev = cur; | 364 | if (s == NULL) |
| 382 | line_l += lenght; | 365 | s = p = buf; |
| 383 | if(line_l > mc) { | 366 | if ((p - buf) >= mc) |
| 384 | /* stop memory usage :-) */ | 367 | bb_error_msg_and_die("argument line too long"); |
| 385 | break; | 368 | *p++ = c; |
| 369 | if (c == 0) { /* word's delimiter or EOF detected */ | ||
| 370 | /* word loaded */ | ||
| 371 | size_t lenght = (p - buf); | ||
| 372 | |||
| 373 | cur = xmalloc(sizeof(xlist_t) + lenght); | ||
| 374 | cur->data = memcpy(cur + 1, s, lenght); | ||
| 375 | cur->lenght = lenght; | ||
| 376 | cur->link = NULL; | ||
| 377 | if (prev == NULL) { | ||
| 378 | list_arg = cur; | ||
| 379 | } else { | ||
| 380 | prev->link = cur; | ||
| 381 | } | ||
| 382 | prev = cur; | ||
| 383 | line_l += lenght; | ||
| 384 | if (line_l > mc) { | ||
| 385 | /* stop memory usage :-) */ | ||
| 386 | break; | ||
| 387 | } | ||
| 388 | s = NULL; | ||
| 386 | } | 389 | } |
| 387 | s = NULL; | ||
| 388 | } | 390 | } |
| 389 | } | 391 | return list_arg; |
| 390 | return list_arg; | ||
| 391 | } | 392 | } |
| 393 | |||
| 392 | # define READ_ARGS(l, e, nmc, mc) (*read_args)(l, e, nmc, mc) | 394 | # define READ_ARGS(l, e, nmc, mc) (*read_args)(l, e, nmc, mc) |
| 393 | # define OPT_INC_0 1 /* future use */ | 395 | # define OPT_INC_0 1 /* future use */ |
| 394 | #else | 396 | #else |
| 395 | # define OPT_INC_0 0 /* future use */ | 397 | # define OPT_INC_0 0 /* future use */ |
| 396 | # define READ_ARGS(l, e, nmc, mc) process_stdin(l, e, nmc, mc) | 398 | # define READ_ARGS(l, e, nmc, mc) process_stdin(l, e, nmc, mc) |
| 397 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM */ | 399 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM */ |
| 398 | 400 | ||
| 399 | 401 | ||
| 400 | #define OPT_VERBOSE (1<<0) | 402 | #define OPT_VERBOSE (1<<0) |
| @@ -405,7 +407,7 @@ process0_stdin (xlist_t *list_arg, const char *eof_str, size_t mc, char *buf) | |||
| 405 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION | 407 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION |
| 406 | #define OPT_INTERACTIVE (1<<5) | 408 | #define OPT_INTERACTIVE (1<<5) |
| 407 | #else | 409 | #else |
| 408 | #define OPT_INTERACTIVE (0) /* require for algorithm &| */ | 410 | #define OPT_INTERACTIVE (0) /* require for algorithm &| */ |
| 409 | #endif | 411 | #endif |
| 410 | #define OPT_TERMINATE (1<<(5+OPT_INC_P)) | 412 | #define OPT_TERMINATE (1<<(5+OPT_INC_P)) |
| 411 | #define OPT_ZEROTERM (1<<(5+OPT_INC_P+OPT_INC_X)) | 413 | #define OPT_ZEROTERM (1<<(5+OPT_INC_P+OPT_INC_X)) |
| @@ -413,153 +415,154 @@ process0_stdin (xlist_t *list_arg, const char *eof_str, size_t mc, char *buf) | |||
| 413 | #define OPT_NEXT_OTHER (1<<(5+OPT_INC_P+OPT_INC_X+OPT_INC_0)) | 415 | #define OPT_NEXT_OTHER (1<<(5+OPT_INC_P+OPT_INC_X+OPT_INC_0)) |
| 414 | */ | 416 | */ |
| 415 | 417 | ||
| 416 | int | 418 | int xargs_main(int argc, char **argv) |
| 417 | xargs_main (int argc, char **argv) | ||
| 418 | { | 419 | { |
| 419 | char **args; | 420 | char **args; |
| 420 | int i, a, n; | 421 | int i, a, n; |
| 421 | xlist_t *list = NULL; | 422 | xlist_t *list = NULL; |
| 422 | xlist_t *cur; | 423 | xlist_t *cur; |
| 423 | int child_error = 0; | 424 | int child_error = 0; |
| 424 | char *max_args, *max_chars; | 425 | char *max_args, *max_chars; |
| 425 | int n_max_arg; | 426 | int n_max_arg; |
| 426 | size_t n_chars = 0; | 427 | size_t n_chars = 0; |
| 427 | long orig_arg_max; | 428 | long orig_arg_max; |
| 428 | const char *eof_str = "_"; | 429 | const char *eof_str = "_"; |
| 429 | unsigned long opt; | 430 | unsigned long opt; |
| 430 | size_t n_max_chars; | 431 | size_t n_max_chars; |
| 432 | |||
| 431 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM | 433 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM |
| 432 | xlist_t * (*read_args) (xlist_t *, const char *, size_t, char *) = process_stdin; | 434 | xlist_t *(*read_args) (xlist_t *, const char *, size_t, char *) = |
| 435 | process_stdin; | ||
| 433 | #endif | 436 | #endif |
| 434 | 437 | ||
| 435 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION | 438 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION |
| 436 | bb_opt_complementaly = "pt"; | 439 | bb_opt_complementaly = "pt"; |
| 437 | #endif | 440 | #endif |
| 438 | 441 | ||
| 439 | opt = bb_getopt_ulflags (argc, argv, "+trn:s:e::" | 442 | opt = bb_getopt_ulflags(argc, argv, "+trn:s:e::" |
| 440 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION | 443 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION |
| 441 | "p" | 444 | "p" |
| 442 | #endif | 445 | #endif |
| 443 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT | 446 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT |
| 444 | "x" | 447 | "x" |
| 445 | #endif | 448 | #endif |
| 446 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM | 449 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM |
| 447 | "0" | 450 | "0" |
| 448 | #endif | 451 | #endif |
| 449 | , &max_args, &max_chars, &eof_str); | 452 | , &max_args, &max_chars, &eof_str); |
| 450 | 453 | ||
| 451 | a = argc - optind; | 454 | a = argc - optind; |
| 452 | argv += optind; | 455 | argv += optind; |
| 453 | if (a == 0) { | 456 | if (a == 0) { |
| 454 | /* default behavior is to echo all the filenames */ | 457 | /* default behavior is to echo all the filenames */ |
| 455 | *argv = "echo"; | 458 | *argv = "echo"; |
| 456 | a++; | 459 | a++; |
| 457 | } | 460 | } |
| 458 | 461 | ||
| 459 | orig_arg_max = ARG_MAX; | 462 | orig_arg_max = ARG_MAX; |
| 460 | if (orig_arg_max == -1) | 463 | if (orig_arg_max == -1) |
| 461 | orig_arg_max = LONG_MAX; | 464 | orig_arg_max = LONG_MAX; |
| 462 | orig_arg_max -= 2048; /* POSIX.2 requires subtracting 2048. */ | 465 | orig_arg_max -= 2048; /* POSIX.2 requires subtracting 2048. */ |
| 463 | if ((opt & OPT_UPTO_SIZE)) { | 466 | if ((opt & OPT_UPTO_SIZE)) { |
| 464 | n_max_chars = bb_xgetularg10_bnd (max_chars, 1, orig_arg_max); | 467 | n_max_chars = bb_xgetularg10_bnd(max_chars, 1, orig_arg_max); |
| 465 | for (i = 0; i < a; i++) { | 468 | for (i = 0; i < a; i++) { |
| 466 | n_chars += strlen (*argv) + 1; | 469 | n_chars += strlen(*argv) + 1; |
| 470 | } | ||
| 471 | if (n_max_chars < n_chars) { | ||
| 472 | bb_error_msg_and_die | ||
| 473 | ("can not fit single argument within argument list size limit"); | ||
| 474 | } | ||
| 475 | n_max_chars -= n_chars; | ||
| 476 | } else { | ||
| 477 | /* Sanity check for systems with huge ARG_MAX defines (e.g., Suns which | ||
| 478 | have it at 1 meg). Things will work fine with a large ARG_MAX but it | ||
| 479 | will probably hurt the system more than it needs to; an array of this | ||
| 480 | size is allocated. */ | ||
| 481 | if (orig_arg_max > 20 * 1024) | ||
| 482 | orig_arg_max = 20 * 1024; | ||
| 483 | n_max_chars = orig_arg_max; | ||
| 467 | } | 484 | } |
| 468 | if (n_max_chars < n_chars) { | 485 | max_chars = xmalloc(n_max_chars); |
| 469 | bb_error_msg_and_die | 486 | |
| 470 | ("can not fit single argument within argument list size limit"); | 487 | if ((opt & OPT_UPTO_NUMBER)) { |
| 488 | n_max_arg = bb_xgetularg10_bnd(max_args, 1, INT_MAX); | ||
| 489 | } else { | ||
| 490 | n_max_arg = n_max_chars; | ||
| 471 | } | 491 | } |
| 472 | n_max_chars -= n_chars; | ||
| 473 | } else { | ||
| 474 | /* Sanity check for systems with huge ARG_MAX defines (e.g., Suns which | ||
| 475 | have it at 1 meg). Things will work fine with a large ARG_MAX but it | ||
| 476 | will probably hurt the system more than it needs to; an array of this | ||
| 477 | size is allocated. */ | ||
| 478 | if (orig_arg_max > 20 * 1024) | ||
| 479 | orig_arg_max = 20 * 1024; | ||
| 480 | n_max_chars = orig_arg_max; | ||
| 481 | } | ||
| 482 | max_chars = xmalloc(n_max_chars); | ||
| 483 | |||
| 484 | if ((opt & OPT_UPTO_NUMBER)) { | ||
| 485 | n_max_arg = bb_xgetularg10_bnd (max_args, 1, INT_MAX); | ||
| 486 | } else { | ||
| 487 | n_max_arg = n_max_chars; | ||
| 488 | } | ||
| 489 | 492 | ||
| 490 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM | 493 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM |
| 491 | if(opt & OPT_ZEROTERM) | 494 | if (opt & OPT_ZEROTERM) |
| 492 | read_args = process0_stdin; | 495 | read_args = process0_stdin; |
| 493 | #endif | 496 | #endif |
| 494 | 497 | ||
| 495 | while ((list = READ_ARGS(list, eof_str, n_max_chars, max_chars)) != NULL | 498 | while ((list = READ_ARGS(list, eof_str, n_max_chars, max_chars)) != NULL |
| 496 | || (opt & OPT_NO_EMPTY) == 0) { | 499 | || (opt & OPT_NO_EMPTY) == 0) { |
| 497 | opt |= OPT_NO_EMPTY; | 500 | opt |= OPT_NO_EMPTY; |
| 498 | n = 0; | 501 | n = 0; |
| 499 | n_chars = 0; | 502 | n_chars = 0; |
| 500 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT | 503 | #ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT |
| 501 | for (cur = list; cur; ) { | 504 | for (cur = list; cur;) { |
| 502 | n_chars += cur->lenght; | 505 | n_chars += cur->lenght; |
| 503 | n++; | 506 | n++; |
| 504 | cur = cur->link; | 507 | cur = cur->link; |
| 505 | if (n_chars > n_max_chars || (n == n_max_arg && cur)) { | 508 | if (n_chars > n_max_chars || (n == n_max_arg && cur)) { |
| 506 | if (opt & OPT_TERMINATE) | 509 | if (opt & OPT_TERMINATE) |
| 507 | bb_error_msg_and_die ("argument list too long"); | 510 | bb_error_msg_and_die("argument list too long"); |
| 508 | break; | 511 | break; |
| 509 | } | 512 | } |
| 510 | } | 513 | } |
| 511 | #else | 514 | #else |
| 512 | for (cur = list; cur; cur = cur->link) { | 515 | for (cur = list; cur; cur = cur->link) { |
| 513 | n_chars += cur->lenght; | 516 | n_chars += cur->lenght; |
| 514 | n++; | 517 | n++; |
| 515 | if (n_chars > n_max_chars || n == n_max_arg) { | 518 | if (n_chars > n_max_chars || n == n_max_arg) { |
| 516 | break; | 519 | break; |
| 517 | } | 520 | } |
| 518 | } | 521 | } |
| 519 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT */ | 522 | #endif /* CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT */ |
| 520 | 523 | ||
| 521 | /* allocating pointers for execvp: | 524 | /* allocating pointers for execvp: |
| 522 | a*arg, n*arg from stdin, NULL */ | 525 | a*arg, n*arg from stdin, NULL */ |
| 523 | args = xcalloc (n + a + 1, sizeof (char *)); | 526 | args = xcalloc(n + a + 1, sizeof(char *)); |
| 524 | 527 | ||
| 525 | /* Store the command to be executed | 528 | /* Store the command to be executed |
| 526 | (taken from the command line) */ | 529 | (taken from the command line) */ |
| 527 | for (i = 0; i < a; i++) | 530 | for (i = 0; i < a; i++) |
| 528 | args[i] = argv[i]; | 531 | args[i] = argv[i]; |
| 529 | /* (taken from stdin) */ | 532 | /* (taken from stdin) */ |
| 530 | for (cur = list; n; cur = cur->link) { | 533 | for (cur = list; n; cur = cur->link) { |
| 531 | args[i++] = cur->data; | 534 | args[i++] = cur->data; |
| 532 | n--; | 535 | n--; |
| 533 | } | 536 | } |
| 534 | 537 | ||
| 535 | if ((opt & (OPT_INTERACTIVE|OPT_VERBOSE))) { | 538 | if ((opt & (OPT_INTERACTIVE | OPT_VERBOSE))) { |
| 536 | for (i = 0; args[i]; i++) { | 539 | for (i = 0; args[i]; i++) { |
| 537 | if (i) | 540 | if (i) |
| 538 | fputc (' ', stderr); | 541 | fputc(' ', stderr); |
| 539 | fputs (args[i], stderr); | 542 | fputs(args[i], stderr); |
| 543 | } | ||
| 544 | if ((opt & OPT_INTERACTIVE) == 0) | ||
| 545 | fputc('\n', stderr); | ||
| 546 | } | ||
| 547 | if ((opt & OPT_INTERACTIVE) == 0 || xargs_ask_confirmation() != 0) { | ||
| 548 | child_error = xargs_exec(args); | ||
| 540 | } | 549 | } |
| 541 | if((opt & OPT_INTERACTIVE) == 0) | ||
| 542 | fputc ('\n', stderr); | ||
| 543 | } | ||
| 544 | if ((opt & OPT_INTERACTIVE) == 0 || xargs_ask_confirmation () != 0) { | ||
| 545 | child_error = xargs_exec (args); | ||
| 546 | } | ||
| 547 | 550 | ||
| 548 | /* clean up */ | 551 | /* clean up */ |
| 549 | for (i = a; args[i]; i++) { | 552 | for (i = a; args[i]; i++) { |
| 550 | cur = list; | 553 | cur = list; |
| 551 | list = list->link; | 554 | list = list->link; |
| 552 | free (cur); | 555 | free(cur); |
| 553 | } | 556 | } |
| 554 | free (args); | 557 | free(args); |
| 555 | if (child_error > 0 && child_error != 123) { | 558 | if (child_error > 0 && child_error != 123) { |
| 556 | break; | 559 | break; |
| 560 | } | ||
| 557 | } | 561 | } |
| 558 | } | ||
| 559 | #ifdef CONFIG_FEATURE_CLEAN_UP | 562 | #ifdef CONFIG_FEATURE_CLEAN_UP |
| 560 | free(max_chars); | 563 | free(max_chars); |
| 561 | #endif | 564 | #endif |
| 562 | return child_error; | 565 | return child_error; |
| 563 | } | 566 | } |
| 564 | 567 | ||
| 565 | 568 | ||
| @@ -569,12 +572,14 @@ const char *bb_applet_name = "debug stuff usage"; | |||
| 569 | 572 | ||
| 570 | void bb_show_usage(void) | 573 | void bb_show_usage(void) |
| 571 | { | 574 | { |
| 572 | fprintf(stderr, "Usage: %s [-p] [-r] [-t] -[x] [-n max_arg] [-s max_chars]\n", bb_applet_name); | 575 | fprintf(stderr, |
| 573 | exit(1); | 576 | "Usage: %s [-p] [-r] [-t] -[x] [-n max_arg] [-s max_chars]\n", |
| 577 | bb_applet_name); | ||
| 578 | exit(1); | ||
| 574 | } | 579 | } |
| 575 | 580 | ||
| 576 | int main(int argc, char **argv) | 581 | int main(int argc, char **argv) |
| 577 | { | 582 | { |
| 578 | return xargs_main(argc, argv); | 583 | return xargs_main(argc, argv); |
| 579 | } | 584 | } |
| 580 | #endif /* TEST */ | 585 | #endif /* TEST */ |
