From 6248a734e2d59ebe95aeb39189326d90f018804e Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Fri, 29 Sep 2006 08:20:30 +0000 Subject: xargs: simplify option parsing --- findutils/xargs.c | 207 ++++++++++++++++++++++++------------------------------ 1 file changed, 91 insertions(+), 116 deletions(-) (limited to 'findutils/xargs.c') diff --git a/findutils/xargs.c b/findutils/xargs.c index d067a3f48..b6a154f15 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c @@ -45,54 +45,52 @@ #endif /* - This function have special algorithm. - Don`t use fork and include to main! + This function has special algorithm. + Don't use fork and include to main! */ static int xargs_exec(char *const *args) { pid_t p; volatile int exec_errno = 0; /* shared vfork stack */ + int status; - if ((p = vfork()) >= 0) { - if (p == 0) { - /* vfork -- child */ - execvp(args[0], args); - exec_errno = errno; /* set error to shared stack */ - _exit(1); - } else { - /* vfork -- parent */ - int status; - - while (wait(&status) == (pid_t) - 1) - if (errno != EINTR) - break; - if (exec_errno) { - errno = exec_errno; - bb_perror_msg("%s", args[0]); - return exec_errno == ENOENT ? 127 : 126; - } else { - if (WEXITSTATUS(status) == 255) { - bb_error_msg("%s: exited with status 255; aborting", args[0]); - return 124; - } - if (WIFSTOPPED(status)) { - bb_error_msg("%s: stopped by signal %d", - args[0], WSTOPSIG(status)); - return 125; - } - if (WIFSIGNALED(status)) { - bb_error_msg("%s: terminated by signal %d", - args[0], WTERMSIG(status)); - return 125; - } - if (WEXITSTATUS(status) != 0) - return 123; - return 0; - } - } - } else { + p = vfork(); + if (p < 0) bb_perror_msg_and_die("vfork"); + + if (p == 0) { + /* vfork -- child */ + execvp(args[0], args); + exec_errno = errno; /* set error to shared stack */ + _exit(1); + } + + /* vfork -- parent */ + while (wait(&status) == (pid_t) -1) + if (errno != EINTR) + break; + if (exec_errno) { + errno = exec_errno; + bb_perror_msg("%s", args[0]); + return exec_errno == ENOENT ? 127 : 126; } + if (WEXITSTATUS(status) == 255) { + bb_error_msg("%s: exited with status 255; aborting", args[0]); + return 124; + } + if (WIFSTOPPED(status)) { + bb_error_msg("%s: stopped by signal %d", + args[0], WSTOPSIG(status)); + return 125; + } + if (WIFSIGNALED(status)) { + bb_error_msg("%s: terminated by signal %d", + args[0], WTERMSIG(status)); + return 125; + } + if (WEXITSTATUS(status)) + return 123; + return 0; } @@ -105,7 +103,7 @@ typedef struct xlist_s { static int eof_stdin_detected; #define ISBLANK(c) ((c) == ' ' || (c) == '\t') -#define ISSPACE(c) (ISBLANK (c) || (c) == '\n' || (c) == '\r' \ +#define ISSPACE(c) (ISBLANK(c) || (c) == '\n' || (c) == '\r' \ || (c) == '\f' || (c) == '\v') #ifdef CONFIG_FEATURE_XARGS_SUPPORT_QUOTES @@ -304,19 +302,10 @@ static int xargs_ask_confirmation(void) return 1; return 0; } - -# define OPT_INC_P 1 #else -# define OPT_INC_P 0 # define xargs_ask_confirmation() 1 #endif /* CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION */ -#ifdef CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT -# define OPT_INC_X 1 -#else -# define OPT_INC_X 0 -#endif - #ifdef CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM static xlist_t *process0_stdin(xlist_t * list_arg, const char *eof_str ATTRIBUTE_UNUSED, size_t mc, char *buf) @@ -371,35 +360,37 @@ static xlist_t *process0_stdin(xlist_t * list_arg, const char *eof_str ATTRIBUTE } return list_arg; } - -# define READ_ARGS(l, e, nmc, mc) (*read_args)(l, e, nmc, mc) -# define OPT_INC_0 1 /* future use */ -#else -# define OPT_INC_0 0 /* future use */ -# define READ_ARGS(l, e, nmc, mc) process_stdin(l, e, nmc, mc) #endif /* CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM */ - -#define OPT_VERBOSE (1<<0) -#define OPT_NO_EMPTY (1<<1) -#define OPT_UPTO_NUMBER (1<<2) -#define OPT_UPTO_SIZE (1<<3) -#define OPT_EOF_STRING (1<<4) -#ifdef CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION -#define OPT_INTERACTIVE (1<<5) -#else -#define OPT_INTERACTIVE (0) /* require for algorithm &| */ -#endif -#define OPT_TERMINATE (1<<(5+OPT_INC_P)) -#define OPT_ZEROTERM (1<<(5+OPT_INC_P+OPT_INC_X)) -/* next future -#define OPT_NEXT_OTHER (1<<(5+OPT_INC_P+OPT_INC_X+OPT_INC_0)) -*/ +/* Correct regardless of combination of CONFIG_xxx */ +enum { + OPTBIT_VERBOSE = 0, + OPTBIT_NO_EMPTY, + OPTBIT_UPTO_NUMBER, + OPTBIT_UPTO_SIZE, + OPTBIT_EOF_STRING, + USE_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) + USE_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) + USE_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) + + OPT_VERBOSE = 1<link) { @@ -515,21 +492,21 @@ int xargs_main(int argc, char **argv) n--; } - if ((opt & (OPT_INTERACTIVE | OPT_VERBOSE))) { + if (opt & (OPT_INTERACTIVE | OPT_VERBOSE)) { for (i = 0; args[i]; i++) { if (i) fputc(' ', stderr); fputs(args[i], stderr); } - if ((opt & OPT_INTERACTIVE) == 0) + if (!(opt & OPT_INTERACTIVE)) fputc('\n', stderr); } - if ((opt & OPT_INTERACTIVE) == 0 || xargs_ask_confirmation() != 0) { + if (!(opt & OPT_INTERACTIVE) || xargs_ask_confirmation()) { child_error = xargs_exec(args); } /* clean up */ - for (i = a; args[i]; i++) { + for (i = argc; args[i]; i++) { cur = list; list = list->link; free(cur); @@ -539,9 +516,7 @@ int xargs_main(int argc, char **argv) break; } } -#ifdef CONFIG_FEATURE_CLEAN_UP - free(max_chars); -#endif + if (ENABLE_FEATURE_CLEAN_UP) free(max_chars); return child_error; } -- cgit v1.2.3