Add the x, n, s and E options, remove -r as its expected behaviour.
This commit is contained in:
		| @@ -3,6 +3,7 @@ | |||||||
|  * Only "-prt" options are supported in this version of xargs. |  * Only "-prt" options are supported in this version of xargs. | ||||||
|  * |  * | ||||||
|  * (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru> |  * (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru> | ||||||
|  |  * (C) 2003 by Glenn McGrath <bug1@optushome.com.au> | ||||||
|  * |  * | ||||||
|  * Special thanks Mark Whitley for stimul to rewrote :) |  * Special thanks Mark Whitley for stimul to rewrote :) | ||||||
|  * |  * | ||||||
| @@ -20,12 +21,28 @@ | |||||||
|  * along with this program; if not, write to the Free Software |  * along with this program; if not, write to the Free Software | ||||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
|  * |  * | ||||||
|  * BUGS: -p doesnt accept user input |  * | ||||||
|  |  * Reference: | ||||||
|  |  *	http://www.opengroup.org/onlinepubs/007904975/utilities/xargs.html | ||||||
|  |  * | ||||||
|  |  * | ||||||
|  |  * BUGS: | ||||||
|  |  *	p option doesnt accept user input, should read input from /dev/tty | ||||||
|  |  * | ||||||
|  |  *	E option doesnt allow spaces before argument | ||||||
|  |  * | ||||||
|  |  *	xargs should terminate if an invocation of a constructed command line | ||||||
|  |  *  returns an exit status of 255. | ||||||
|  |  * | ||||||
|  |  *  exit value of isnt correct  | ||||||
|  |  * | ||||||
|  |  *  doesnt print quoted string properly | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
|  | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <getopt.h> | #include <getopt.h> | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
| @@ -33,7 +50,6 @@ | |||||||
| #include <sys/wait.h> | #include <sys/wait.h> | ||||||
| #include "busybox.h" | #include "busybox.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|    This function have special algorithm. |    This function have special algorithm. | ||||||
|    Don`t use fork and include to main! |    Don`t use fork and include to main! | ||||||
| @@ -65,17 +81,42 @@ static void xargs_exec(char * const * args) | |||||||
|  |  | ||||||
| #define OPT_VERBOSE	0x2 | #define OPT_VERBOSE	0x2 | ||||||
| #define OPT_INTERACTIVE	0x4 | #define OPT_INTERACTIVE	0x4 | ||||||
| #define OPT_NO_EMPTY	0x8 | #define OPT_TERMINATE	0x8 | ||||||
|  | #define OPT_UPTO_NUMBER	0x10 | ||||||
|  | #define OPT_UPTO_SIZE	0x20 | ||||||
|  | #define OPT_EOF_STRING	0x40 | ||||||
|  |  | ||||||
| int xargs_main(int argc, char **argv) | int xargs_main(int argc, char **argv) | ||||||
| { | { | ||||||
| 	char *file_to_act_on; | 	char *s_max_args = NULL; | ||||||
| 	char **args; | 	char *s_line_size = NULL; | ||||||
| 	int  i, a; |  | ||||||
| 	unsigned long flg; | 	unsigned long flg; | ||||||
|  |  | ||||||
|  | 	char *eof_string = "_"; | ||||||
|  | 	int line_size = LINE_MAX; | ||||||
|  | 	unsigned int max_args = LINE_MAX / 2; | ||||||
|  |  | ||||||
|  | 	char *line_buffer = NULL; | ||||||
|  | 	char *line_buffer_ptr_ptr; | ||||||
|  | 	char *old_arg = NULL; | ||||||
|  |  | ||||||
|  | 	char **args; | ||||||
|  | 	char *args_entry_ptr; | ||||||
|  |  | ||||||
|  | 	int i; | ||||||
|  | 	int a; | ||||||
|  |  | ||||||
|  | 	 | ||||||
| 	bb_opt_complementaly = "pt"; | 	bb_opt_complementaly = "pt"; | ||||||
| 	flg = bb_getopt_ulflags(argc, argv, "+tpr"); |  | ||||||
|  | 	flg = bb_getopt_ulflags(argc, argv, "+tpxn:s:E::", &s_max_args, &s_line_size, &eof_string); | ||||||
|  |  | ||||||
|  | 	if (s_max_args) { | ||||||
|  | 		max_args = bb_xgetularg10(s_max_args); | ||||||
|  | 	} | ||||||
|  | 	if (s_line_size) { | ||||||
|  | 		line_size = bb_xgetularg10(s_line_size); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	a = argc - optind; | 	a = argc - optind; | ||||||
| 	argv += optind; | 	argv += optind; | ||||||
| @@ -88,20 +129,81 @@ int xargs_main(int argc, char **argv) | |||||||
| 	args = xcalloc(a + 2, sizeof(char *)); | 	args = xcalloc(a + 2, sizeof(char *)); | ||||||
|  |  | ||||||
| 	/* Store the command to be executed (taken from the command line) */ | 	/* Store the command to be executed (taken from the command line) */ | ||||||
| 	for (i = 0; i < a; i++) | 	for (i = 0; i < a; i++) { | ||||||
|  | 		line_size -= strlen(*argv) + 1; | ||||||
| 		args[i] = *argv++; | 		args[i] = *argv++; | ||||||
|  | 	} | ||||||
|  | 	if (line_size < 1) { | ||||||
|  | 		bb_error_msg_and_die("can not fit single argument within argument list size limit"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	args[i] = xmalloc(line_size); | ||||||
|  | 	args_entry_ptr = args[i]; | ||||||
|  |  | ||||||
| 	/* Now, read in one line at a time from stdin, and store this  | 	/* Now, read in one line at a time from stdin, and store this  | ||||||
| 	 * line to be used later as an argument to the command */ | 	 * line to be used later as an argument to the command */ | ||||||
| 	while ((file_to_act_on = bb_get_chomped_line_from_file(stdin)) != NULL) { | 	do { | ||||||
| 		if(file_to_act_on[0] != 0 || (flg & OPT_NO_EMPTY) == 0) { | 		char *line_buffer_ptr = NULL; | ||||||
| 			args[a] = file_to_act_on[0] ? file_to_act_on : NULL; | 		unsigned int arg_count = 0; | ||||||
|  | 		unsigned int arg_size = 0; | ||||||
|  |  | ||||||
|  | 		*args_entry_ptr = '\0'; | ||||||
|  |  | ||||||
|  | 		/* Get the required number of entries from stdin */ | ||||||
|  | 		do { | ||||||
|  | 			/* (Re)fill the line buffer */ | ||||||
|  | 			if (line_buffer == NULL) { | ||||||
|  | 				line_buffer = bb_get_chomped_line_from_file(stdin); | ||||||
|  | 				if (line_buffer == NULL) { | ||||||
|  | 					/* EOF, exit outer loop */ | ||||||
|  | 					break; | ||||||
|  | 				} | ||||||
|  | 				line_buffer_ptr = strtok_r(line_buffer, " \t", &line_buffer_ptr_ptr); | ||||||
|  | 			} else { | ||||||
|  | 				if (old_arg) { | ||||||
|  | 					line_buffer_ptr = old_arg; | ||||||
|  | 					old_arg = NULL; | ||||||
|  | 				} else { | ||||||
|  | 					line_buffer_ptr = strtok_r(NULL, " \t", &line_buffer_ptr_ptr); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			/* If no arguments left go back and get another line */ | ||||||
|  | 			if (line_buffer_ptr == NULL) { | ||||||
|  | 				free(line_buffer); | ||||||
|  | 				line_buffer = NULL; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			if (eof_string && (strcmp(line_buffer_ptr, eof_string) == 0)) { | ||||||
|  | 				/* logical EOF, exit outer loop */ | ||||||
|  | 				line_buffer = NULL; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			/* Check the next argument will fit */ | ||||||
|  | 			arg_size += 1 + strlen(line_buffer_ptr); | ||||||
|  | 			if (arg_size > line_size) { | ||||||
|  | 				if ((arg_count == 0) || ((flg & OPT_TERMINATE) && (arg_count != max_args))){ | ||||||
|  | 					bb_error_msg_and_die("argument line too long"); | ||||||
|  | 				} | ||||||
|  | 				old_arg = line_buffer_ptr; | ||||||
|  | 				break; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			/* Add the entry to our pre-allocated space */ | ||||||
|  | 			strcat(args_entry_ptr, line_buffer_ptr); | ||||||
|  | 			strcat(args_entry_ptr, " "); | ||||||
|  | 			arg_count++; | ||||||
|  | 		} while (arg_count < max_args); | ||||||
|  |  | ||||||
|  | 		if (*args_entry_ptr != '\0') { | ||||||
| 			if(flg & (OPT_VERBOSE | OPT_INTERACTIVE)) { | 			if(flg & (OPT_VERBOSE | OPT_INTERACTIVE)) { | ||||||
| 				for(i=0; args[i]; i++) { | 				for(i=0; args[i]; i++) { | ||||||
| 					if(i) | 					if(i) | ||||||
| 						fputc(' ', stderr); | 						fputc(' ', stderr); | ||||||
| 					fputs(args[i], stderr); | 					fputs(args[i], stderr); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
| 				fputs(((flg & OPT_INTERACTIVE) ? " ?..." : "\n"), stderr); | 				fputs(((flg & OPT_INTERACTIVE) ? " ?..." : "\n"), stderr); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -109,9 +211,8 @@ int xargs_main(int argc, char **argv) | |||||||
| 				xargs_exec(args); | 				xargs_exec(args); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		/* clean up */ | 	} while (line_buffer); | ||||||
| 		free(file_to_act_on); |  | ||||||
| 	} |  | ||||||
| #ifdef CONFIG_FEATURE_CLEAN_UP | #ifdef CONFIG_FEATURE_CLEAN_UP | ||||||
| 	free(args); | 	free(args); | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user