Re: Re: [PATCH] setarch: add long options to setarch and update manpage

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Sep 04, 2007 at 03:45:10PM +0800, Li Zefan wrote:
> > Cool! Cannot we use getopt_long()?
> 
> It needs more work, and more codes should be modified, and the error message
> about invalid options can't remain unchanged. Anyway, here is the patch in 
> which getopt_long() is used.

 I did some changes to avoid duplicate code and make it more readable.
 It would be nice to add to the show_usage() and man page description
 for all flags -- things like "Turns on WHOLE_SECONDS" suck.

    Karel


commit 8df90dec2bfd8c876ddd4cea010f40550d4e24aa
Author: Karel Zak <kzak@xxxxxxxxxx>
Date:   Tue Sep 4 15:45:10 2007 +0800

    setarch: add long options to setarch and update manpage
    
    Co-Author: Li Zefan <lizf@xxxxxxxxxxxxxx>
    Signed-off-by: Li Zefan <lizf@xxxxxxxxxxxxxx>
    Signed-off-by: Karel Zak <kzak@xxxxxxxxxx>

diff --git a/sys-utils/setarch.8 b/sys-utils/setarch.8
index 16946cf..0229be8 100644
--- a/sys-utils/setarch.8
+++ b/sys-utils/setarch.8
@@ -17,7 +17,7 @@ as machine type. It also allows to set various personality options. The default
 is /bin/sh.
 .SH OPTIONS
 .TP
-.I "\-v"
+.I "\-v," "\-\-verbose"
 Be verbose.
 .TP
 .I "\-h," "\-\-help"
@@ -26,36 +26,38 @@ Display help (it is also displayed when setarch takes no arguments).
 .I "\-3," "\-\-3gb"
 Specifies that processes should use a maximum of 3GB of address space on systems where it is supported (ADDR_LIMIT_3GB).
 .TP
-.I "\-B"
+.I "\-B," "\-\-32bit"
 Turns on ADDR_LIMIT_32BIT.
 .TP
-.I "\-F"
+.I "\-F," "\-\-fdpic-funcptrs"
 Userspace function pointers point to descriptors (turns on FDPIC_FUNCPTRS).
 .TP
-.I "\-I"
+.I "\-I," "\-\-short-inode"
 Turns on SHORT_INODE.
 .TP
-.I "\-L"
+.I "\-L," "\-\-addr-compat-layout"
 Changes the way virtual memory is allocated (turns on the ADDR_COMPAT_LAYOUT).
 .TP
-.I "\-R"
+.I "\-R," "\-\-addr-no-randomize"
 Disables randomization of the virtual address space (turns on ADDR_NO_RANDOMIZE).
 .TP
-.I "\-S"
+.I "\-S," "\-\-whole-seconds"
 Turns on WHOLE_SECONDS.
 .TP
-.I "\-T"
+.I "\-T," "\-\-sticky-timeouts"
 Turns on STICKY_TIMEOUTS.
 .TP
-.I "\-X"
+.I "\-X" "\-\-read-implies-exec"
 Turns on READ_IMPLIES_EXEC.
 .TP
-.I "\-Z"
+.I "\-Z," "mmap-page-zero"
 Turns on MMAP_PAGE_ZERO.
 .SH EXAMPLES
 setarch ppc32 rpmbuild --target=ppc --rebuild foo.src.rpm
 .br
 setarch ppc32 -v -vL3 rpmbuild --target=ppc --rebuild bar.src.rpm
+.br
+setarch ppc32 --32bit rpmbuild --target=ppc --rebuild foo.src.rpm
 .SH AUTHOR
 Elliot Lee <sopwith@xxxxxxxxxx>
 .br
diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c
index 6eba24a..301b79e 100644
--- a/sys-utils/setarch.c
+++ b/sys-utils/setarch.c
@@ -36,32 +36,47 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <error.h>
+#include <getopt.h>
+#include <limits.h>
 #include <sys/utsname.h>
 #include "nls.h"
 
 #define set_pers(pers) ((long)syscall(SYS_personality, pers))
 
-struct {
-    char c;
-    const char *name;
-    unsigned int option;
-} flags[] = {
-    {'R', "ADDR_NO_RANDOMIZE",  0x0040000},
-    {'F', "FDPIC_FUNCPTRS",     0x0080000},
-    {'Z', "MMAP_PAGE_ZERO",     0x0100000},
-    {'L', "ADDR_COMPAT_LAYOUT", 0x0200000},
-    {'X', "READ_IMPLIES_EXEC",  0x0400000},
-    {'B', "ADDR_LIMIT_32BIT",   0x0800000},
-    {'I', "SHORT_INODE",        0x1000000},
-    {'S', "WHOLE_SECONDS",      0x2000000},
-    {'T', "STICKY_TIMEOUTS",    0x4000000},
-    {'3', "ADDR_LIMIT_3GB",     0x8000000}
+/* Option --4gb has no equivalent short option, use a non-character as a
+   pseudo short option. */
+#define OPT_4GB (CHAR_MAX+1)
+
+#define turn_on(_flag, _opts) \
+	do { \
+		(_opts) |= _flag; \
+		if (verbose) \
+			printf(_("Switching on %s.\n"), #_flag); \
+	} while(0)
+
+/* Options --3gb and --4gb are for compatibitity with an old Debian setarch
+   implementation. */
+struct option longopts[] =
+{
+    { "help",               0, 0, 'h' },
+    { "verbose",            0, 0, 'v' },
+    { "addr-no-randomize",  0, 0, 'R' },
+    { "fdpic-funcptrs",     0, 0, 'F' },
+    { "mmap-page-zero",     0, 0, 'Z' },
+    { "addr-compat-layout", 0, 0, 'L' },
+    { "read-implies-exec",  0, 0, 'X' },
+    { "32bit",              0, 0, 'B' },
+    { "short-inode",        0, 0, 'I' },
+    { "whole-seconds",      0, 0, 'S' },
+    { "sticky-timeouts",    0, 0, 'T' },
+    { "3gb",                0, 0, '3' },
+    { "4gb",                0, 0, OPT_4GB },
+    { NULL,                 0, 0, 0 }
 };
 
 static void __attribute__((__noreturn__))
 show_help(void)
 {
-  int f;
   const char *p = program_invocation_short_name;
 
   if (!*p)
@@ -70,8 +85,20 @@ show_help(void)
   printf(_("Usage: %s%s [options] [program [program arguments]]\n\nOptions:\n"),
          p, !strcmp(p, "setarch") ? " <arch>" : "");
 
-  for (f = 0; f < sizeof(flags) / sizeof(flags[0]); f++)
-    printf(_("\t-%c\tEnable %s\n"), flags[f].c, flags[f].name);
+   printf(_(
+   " -h, --help               this help\n"
+   " -v, --verbose            verbose mode\n"
+   " -R, --addr-no-randomize  disables randomization of the virtual address space\n"
+   " -F, --fdpic-funcptrs     turns on function pointers point to descriptors\n"
+   " -Z, --mmap-page-zero     turns on MMAP_PAGE_ZERO\n"
+   " -L, --addr-compat-layout changes the way virtual memory is allocated\n"
+   " -X, --read-implies-exec  turns on READ_IMPLIES_EXEC\n"
+   " -B, --32bit              turns on ADDR_LIMIT_32BIT\n"
+   " -I, --short-inode        turns on SHORT_INODE\n"
+   " -S, --whole-seconds      turns on WHOLE_SECONDS\n"
+   " -T, --sticky-timeouts    turns on STICKY_TIMEOUTS\n"
+   " -3, --3gb                turns on maximum of 3GB of address space\n"
+   "     --4gb                ignored (for backward compatibility only\n"));
 
   printf(_("\nFor more information see setarch(8).\n"));
   exit(EXIT_SUCCESS);
@@ -89,6 +116,7 @@ show_usage(const char *s)
   exit(EXIT_FAILURE);
 }
 
+
 int set_arch(const char *pers, unsigned long options)
 {
   struct utsname un;
@@ -179,6 +207,7 @@ int main(int argc, char *argv[])
   const char *p;
   unsigned long options = 0;
   int verbose = 0;
+  int c;
 
   setlocale(LC_ALL, "");
   bindtextdomain(PACKAGE, LOCALEDIR);
@@ -194,6 +223,7 @@ int main(int argc, char *argv[])
     if (argc < 1)
       show_usage(_("Not enough arguments"));
     p = argv[0];
+    argv[0] = argv[-1];      /* for getopt_long() to get the program name */
     if (!strcmp(p, "-h") || !strcmp(p, "--help"))
       show_help();
   }
@@ -205,46 +235,53 @@ int main(int argc, char *argv[])
        error(EXIT_FAILURE, errno, "/bin/bash");
    }
   #endif
-  for (argv++, argc--; argc && argv[0][0] == '-'; argv++, argc--) {
-    int n, unknown = 1;
-    const char *arg = argv[0];
 
-    if (!strcmp(arg, "--help"))
+  while ((c = getopt_long(argc, argv, "hv3BFILRSTXZ", longopts, NULL)) != -1) {
+    switch (c) {
+    case 'h':
       show_help();
-
-    /* compatibitity with an old Debian setarch implementation
-     * TODO: add long options for all flags
-     */
-    if (!strcmp(arg, "--3gb"))
-      arg="-3";
-    else if (!strcmp(arg, "--4gb"))
-      continue;				/* just ignore this one */
-
-    for (n = 1; arg[n]; n++) {
-      int f;
-
-      if (arg[n] == 'v') {
-	verbose = 1;
-	continue;
-      }
-
-      if (arg[n] == 'h')
-	show_help();
-
-      for (f = 0; f < sizeof(flags) / sizeof(flags[0]); f++) {
-	if (arg[n] == flags[f].c) {
-	  if (verbose)
-	    fprintf(stderr, _("Switching on %s.\n"), flags[f].name);
-	  options |= flags[f].option;
-	  unknown = 0;
-	  break;
-	}
-      }
-      if (unknown)
-	error(0, 0, _("Unknown option `%c' ignored"), arg[n]);
+      break;
+    case 'v':
+      verbose = 1;
+      break;
+    case 'R':
+	turn_on(ADDR_NO_RANDOMIZE, options);
+	break;
+    case 'F':
+	turn_on(FDPIC_FUNCPTRS, options);
+	break;
+    case 'Z':
+	turn_on(MMAP_PAGE_ZERO, options);
+	break;
+    case 'L':
+	turn_on(ADDR_COMPAT_LAYOUT, options);
+	break;
+    case 'X':
+	turn_on(READ_IMPLIES_EXEC, options);
+	break;
+    case 'B':
+	turn_on(ADDR_LIMIT_32BIT, options);
+	break;
+    case 'I':
+	turn_on(SHORT_INODE, options);
+	break;
+    case 'S':
+	turn_on(WHOLE_SECONDS, options);
+	break;
+    case 'T':
+	turn_on(STICKY_TIMEOUTS, options);
+	break;
+    case '3':
+	turn_on(ADDR_LIMIT_3GB, options);
+	break;
+    case OPT_4GB:          /* just ignore this one */
+      break;
     }
   }
 
+  argc -= optind;
+  argv += optind;
+
   if (set_arch(p, options))
     error(EXIT_FAILURE, errno, _("Failed to set personality to %s"), p);
 
-- 
 Karel Zak  <kzak@xxxxxxxxxx>
-
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux