> 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.
Signed-off-by: Li Zefan <[EMAIL PROTECTED]>
---
setarch.8 | 22 +++++----
setarch.c | 137 ++++++++++++++++++++++++++++++++++++++++----------------------
2 files changed, 102 insertions(+), 57 deletions(-)
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 <[EMAIL PROTECTED]>
.br
diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c
index 6eba24a..24040af 100644
--- a/sys-utils/setarch.c
+++ b/sys-utils/setarch.c
@@ -36,26 +36,53 @@
#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))
+/* Option --4gb has no equivalent short option, use a non-character as a
+ pseudo short option. */
+#define OPT_4GB (CHAR_MAX+1)
+
+/* 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 }
+};
+
struct {
- char c;
+ char short_opt;
+ const char *long_opt;
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}
+ {'R', "addr-no-randomize", "ADDR_NO_RANDOMIZE", 0x0040000},
+ {'F', "fdpic-funcptrs", "FDPIC_FUNCPTRS", 0x0080000},
+ {'Z', "mmap-page-zero", "MMAP_PAGE_ZERO", 0x0100000},
+ {'L', "addr-compat-layout", "ADDR_COMPAT_LAYOUT", 0x0200000},
+ {'X', "read-implies-exec", "READ_IMPLIES_EXEC", 0x0400000},
+ {'B', "32bit", "ADDR_LIMIT_32BIT", 0x0800000},
+ {'I', "short-inode", "SHORT_INODE", 0x1000000},
+ {'S', "whole-seconds", "WHOLE_SECONDS", 0x2000000},
+ {'T', "sticky-timeouts", "STICKY_TIMEOUTS", 0x4000000},
+ {'3', "3gb", "ADDR_LIMIT_3GB", 0x8000000}
};
static void __attribute__((__noreturn__))
@@ -71,7 +98,8 @@ show_help(void)
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(_("\t-%c, --%-24sEnable %s\n"), flags[f].short_opt,
+ flags[f].long_opt, flags[f].name);
printf(_("\nFor more information see setarch(8).\n"));
exit(EXIT_SUCCESS);
@@ -89,6 +117,23 @@ show_usage(const char *s)
exit(EXIT_FAILURE);
}
+static unsigned int turn_on_option(char c, int verbose)
+{
+ unsigned int option = 0;
+ int f;
+
+ for (f = 0; f < sizeof(flags) / sizeof(flags[0]); f++) {
+ if (c == flags[f].short_opt) {
+ if (verbose)
+ fprintf(stderr, _("Switching on %s.\n"), flags[f].name);
+ option = flags[f].option;
+ break;
+ }
+ }
+
+ return option;
+}
+
int set_arch(const char *pers, unsigned long options)
{
struct utsname un;
@@ -179,6 +224,8 @@ int main(int argc, char *argv[])
const char *p;
unsigned long options = 0;
int verbose = 0;
+ int unknown = 0;
+ int c;
setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
@@ -194,6 +241,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,45 +253,40 @@ 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 '3':
+ case 'B':
+ case 'F':
+ case 'I':
+ case 'L':
+ case 'R':
+ case 'S':
+ case 'T':
+ case 'X':
+ case 'Z':
+ options |= turn_on_option( (char)c, verbose );
+ break;
+ case OPT_4GB: /* just ignore this one */
+ break;
+ case '?':
+ default:
+ unknown = 1;
+ break;
}
}
+ if (unknown)
+ error(0, 0, _("Unknown options are ignored"));
+
+ argc -= optind;
+ argv += optind;
if (set_arch(p, options))
error(EXIT_FAILURE, errno, _("Failed to set personality to %s"), p);
---
-
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html