diff options
| author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-10-04 14:44:27 +0000 |
|---|---|---|
| committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2003-10-04 14:44:27 +0000 |
| commit | 7ed0ecf1af9ac7dcd30c79d77cd98611186bf3bc (patch) | |
| tree | 707e6582eb47c29f223d3ef5ce35ad49059e868b | |
| parent | ccd195ae177f09ec729d1f8c6637e011b0c22aed (diff) | |
| download | busybox-w32-7ed0ecf1af9ac7dcd30c79d77cd98611186bf3bc.tar.gz busybox-w32-7ed0ecf1af9ac7dcd30c79d77cd98611186bf3bc.tar.bz2 busybox-w32-7ed0ecf1af9ac7dcd30c79d77cd98611186bf3bc.zip | |
Add the x, n, s and E options, remove -r as its expected behaviour.
git-svn-id: svn://busybox.net/trunk/busybox@7601 69ca8d6d-28ef-0310-b511-8ec308f3f277
| -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 |
