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. | ||||
|  * | ||||
|  * (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 :) | ||||
|  * | ||||
| @@ -20,12 +21,28 @@ | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * 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 <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <unistd.h> | ||||
| #include <getopt.h> | ||||
| #include <errno.h> | ||||
| @@ -33,7 +50,6 @@ | ||||
| #include <sys/wait.h> | ||||
| #include "busybox.h" | ||||
|  | ||||
|  | ||||
| /* | ||||
|    This function have special algorithm. | ||||
|    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_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) | ||||
| { | ||||
| 	char *file_to_act_on; | ||||
| 	char **args; | ||||
| 	int  i, a; | ||||
| 	char *s_max_args = NULL; | ||||
| 	char *s_line_size = NULL; | ||||
| 	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"; | ||||
| 	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; | ||||
| 	argv += optind; | ||||
| @@ -88,20 +129,81 @@ int xargs_main(int argc, char **argv) | ||||
| 	args = xcalloc(a + 2, sizeof(char *)); | ||||
|  | ||||
| 	/* 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++; | ||||
| 	} | ||||
| 	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  | ||||
| 	 * line to be used later as an argument to the command */ | ||||
| 	while ((file_to_act_on = bb_get_chomped_line_from_file(stdin)) != NULL) { | ||||
| 		if(file_to_act_on[0] != 0 || (flg & OPT_NO_EMPTY) == 0) { | ||||
| 			args[a] = file_to_act_on[0] ? file_to_act_on : NULL; | ||||
| 	do { | ||||
| 		char *line_buffer_ptr = 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)) { | ||||
| 				for(i=0; args[i]; i++) { | ||||
| 					if(i) | ||||
| 						fputc(' ', stderr); | ||||
| 					fputs(args[i], stderr); | ||||
| 				} | ||||
|  | ||||
| 				fputs(((flg & OPT_INTERACTIVE) ? " ?..." : "\n"), stderr); | ||||
| 			} | ||||
|  | ||||
| @@ -109,9 +211,8 @@ int xargs_main(int argc, char **argv) | ||||
| 				xargs_exec(args); | ||||
| 			} | ||||
| 		} | ||||
| 		/* clean up */ | ||||
| 		free(file_to_act_on); | ||||
| 	} | ||||
| 	} while (line_buffer); | ||||
|  | ||||
| #ifdef CONFIG_FEATURE_CLEAN_UP | ||||
| 	free(args); | ||||
| #endif | ||||
|   | ||||
		Reference in New Issue
	
	Block a user