From 5edb0ea6bbd57dd916417737f98c9109dc1ecb5b Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 12 Jan 2015 12:19:54 +0100 Subject: setarch: cleanup options usage * call --help, --verbose and --list from one place only * add 'archwrapper' variable to detect when called by symplink * make --list available only got setchar(8) (but no for symlinks) Reported-by: Benno Schulenberg Signed-off-by: Karel Zak --- sys-utils/setarch.c | 66 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 28 deletions(-) (limited to 'sys-utils/setarch.c') diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c index a09625c86..68183e915 100644 --- a/sys-utils/setarch.c +++ b/sys-utils/setarch.c @@ -41,12 +41,6 @@ # define personality(pers) ((long)syscall(SYS_personality, pers)) #endif -/* Options without equivalent short options */ -enum { - OPT_4GB = CHAR_MAX + 1, - OPT_UNAME26 -}; - #define turn_on(_flag, _opts) \ do { \ (_opts) |= _flag; \ @@ -88,10 +82,12 @@ enum { # define ADDR_LIMIT_3GB 0x8000000 #endif +static int archwrapper; + static void __attribute__((__noreturn__)) show_help(void) { fputs(USAGE_HEADER, stdout); - if (!strcmp(program_invocation_short_name, "setarch")) + if (!archwrapper) printf(_(" %s [options] [ [...]]\n"), program_invocation_short_name); else printf(_(" %s [options] [ [...]]\n"), program_invocation_short_name); @@ -113,7 +109,9 @@ static void __attribute__((__noreturn__)) show_help(void) fputs(_(" --4gb ignored (for backward compatibility only)\n"), stdout); fputs(_(" --uname-2.6 turns on UNAME26\n"), stdout); fputs(_(" -v, --verbose say what options are being switched on\n"), stdout); - fputs(_(" --list list settable architectures, and exit\n"), stdout); + + if (!archwrapper) + fputs(_(" --list list settable architectures, and exit\n"), stdout); fputs(USAGE_SEPARATOR, stdout); fputs(USAGE_HELP, stdout); @@ -254,11 +252,18 @@ static int set_arch(const char *pers, unsigned long options, int list) int main(int argc, char *argv[]) { - const char *p; + const char *arch = NULL; unsigned long options = 0; int verbose = 0; int c; + /* Options without equivalent short options */ + enum { + OPT_4GB = CHAR_MAX + 1, + OPT_UNAME26, + OPT_LIST + }; + /* Options --3gb and --4gb are for compatibitity with an old * Debian setarch implementation. */ static const struct option longopts[] = { @@ -277,6 +282,7 @@ int main(int argc, char *argv[]) {"3gb", no_argument, NULL, '3'}, {"4gb", no_argument, NULL, OPT_4GB}, {"uname-2.6", no_argument, NULL, OPT_UNAME26}, + {"list", no_argument, NULL, OPT_LIST}, {NULL, 0, NULL, 0} }; @@ -288,26 +294,21 @@ int main(int argc, char *argv[]) if (argc < 1) show_usage(_("Not enough arguments")); - p = program_invocation_short_name; - if (!strcmp(p, "setarch")) { - argc--; - if (argc < 1) - show_usage(_("Not enough arguments")); - p = argv[1]; - argv[1] = argv[0]; /* for getopt_long() to get the program name */ - argv++; - if (!strcmp(p, "-h") || !strcmp(p, "--help")) - show_help(); - else if (!strcmp(p, "-V") || !strcmp(p, "--version")) - show_version(); - else if (!strcmp(p, "--list")) { - set_arch(argv[0], 0L, 1); - return EXIT_SUCCESS; + archwrapper = strcmp(program_invocation_short_name, "setarch") != 0; + if (archwrapper) + arch = program_invocation_short_name; /* symlinks to setarch */ + else { + if (*argv[1] != '-') { + arch = argv[1]; + argv[1] = argv[0]; /* for getopt_long() to get the program name */ + argv++; + argc--; } } + #if defined(__sparc64__) || defined(__sparc__) - if (!strcmp(p, "sparc32bash")) { - if (set_arch(p, 0L, 0)) + if (archwrapper && strcmp(arch, "sparc32bash") == 0) { + if (set_arch(arch, 0L, 0)) err(EXIT_FAILURE, _("Failed to set personality to %s"), p); execl("/bin/bash", NULL); err(EXIT_FAILURE, _("failed to execute %s"), "/bin/bash"); @@ -360,16 +361,25 @@ int main(int argc, char *argv[]) case OPT_UNAME26: turn_on(UNAME26, options); break; + case OPT_LIST: + if (!archwrapper) { + set_arch(NULL, 0, 1); + break; + } else + warnx(_("unrecognized option '--list'")); default: show_usage(NULL); } } + if (!arch) + errx(EXIT_FAILURE, _("no architecture argument specified")); + argc -= optind; argv += optind; - if (set_arch(p, options, 0)) - err(EXIT_FAILURE, _("Failed to set personality to %s"), p); + if (set_arch(arch, options, 0)) + err(EXIT_FAILURE, _("failed to set personality to %s"), arch); /* flush all output streams before exec */ fflush(NULL); -- cgit v1.2.3-55-g7522