From: Emil Velikov Date: Sun, 2 Aug 2026 14:19:30 +0000 (+0100) Subject: Manually handle unrecognised getopt arguments X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=HEAD;p=thirdparty%2Fkmod.git Manually handle unrecognised getopt arguments Was meaning to add a negative test or two to modinfo - where a invalid option is passed into the program - only to notice that the default will print the path, alongside the program name. While fixing that, I've decided to pimp-up the reporting to also show the help screen. Eg. from this: /usr/bin/insmod: unrecognized option '--versoin' ... to this insmod: ERROR: unrecognised option '--versoin' Usage: insmod [options] filename [module options] Options: -f, --force DANGEROUS: forces a module load, may cause data corruption and crash your machine. implies --force-modversion and --force-vermagic --force-modversion Ignore module's version --force-vermagic Ignore module's version magic -s, --syslog print to syslog, not stderr -v, --verbose enables more messages -V, --version show version -h, --help show this help Signed-off-by: Emil Velikov Link: https://github.com/kmod-project/kmod/pull/453 Signed-off-by: Lucas De Marchi --- diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index 8837ecb..e15f897 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -90,6 +90,7 @@ int test_init(const struct test *start, const struct test *stop, int argc, return -EINVAL; } + opterr = 0; while ((c = getopt_long(argc, argv, options_short, options, NULL)) != -1) { switch (c) { case 'l': @@ -102,6 +103,8 @@ int test_init(const struct test *start, const struct test *stop, int argc, oneshot = 1; break; case '?': + TS_ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + help(); return -1; default: TS_ERR("unexpected getopt_long() value %c\n", c); diff --git a/tools/depmod.c b/tools/depmod.c index 1349bef..0fb6fbc 100644 --- a/tools/depmod.c +++ b/tools/depmod.c @@ -2896,6 +2896,7 @@ static int do_depmod(int argc, char *argv[]) memset(&cfg, 0, sizeof(cfg)); memset(&depmod, 0, sizeof(depmod)); + opterr = 0; while ((c = getopt_long(argc, argv, cmdopts_s, cmdopts, NULL)) != -1) { switch (c) { case 'a': @@ -2971,6 +2972,8 @@ static int do_depmod(int argc, char *argv[]) kmod_version(); return EXIT_SUCCESS; case '?': + ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + help(); goto cmdline_failed; default: ERR("unexpected getopt_long() value '%c'.\n", c); diff --git a/tools/insmod.c b/tools/insmod.c index 17d3fc8..e1accdd 100644 --- a/tools/insmod.c +++ b/tools/insmod.c @@ -74,6 +74,7 @@ static int do_insmod(int argc, char *argv[]) const char *null_config = NULL; unsigned int flags = 0; + opterr = 0; while ((c = getopt_long(argc, argv, cmdopts_s, cmdopts, NULL)) != -1) { switch (c) { case 'f': @@ -99,6 +100,8 @@ static int do_insmod(int argc, char *argv[]) kmod_version(); return EXIT_SUCCESS; case '?': + ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + help(); return EXIT_FAILURE; default: ERR("unexpected getopt_long() value '%c'.\n", c); diff --git a/tools/kmod.c b/tools/kmod.c index eda91e6..293a686 100644 --- a/tools/kmod.c +++ b/tools/kmod.c @@ -85,6 +85,7 @@ static int handle_kmod_commands(int argc, char *argv[]) int err = 0, c; size_t i; + opterr = 0; while ((c = getopt_long(argc, argv, options_s, options, NULL)) != -1) { switch (c) { case 'h': @@ -94,6 +95,8 @@ static int handle_kmod_commands(int argc, char *argv[]) kmod_version(); return EXIT_SUCCESS; case '?': + ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + kmod_help(argc, argv); return EXIT_FAILURE; default: fprintf(stderr, "Error: unexpected getopt_long() value '%c'.\n", diff --git a/tools/lsmod.c b/tools/lsmod.c index a55097f..e786f25 100644 --- a/tools/lsmod.c +++ b/tools/lsmod.c @@ -45,6 +45,7 @@ static int do_lsmod(int argc, char *argv[]) bool use_syslog = false; int err, c, r = 0; + opterr = 0; while ((c = getopt_long(argc, argv, cmdopts_s, cmdopts, NULL)) != -1) { switch (c) { case 's': @@ -60,6 +61,8 @@ static int do_lsmod(int argc, char *argv[]) kmod_version(); return EXIT_SUCCESS; case '?': + ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + help(); return EXIT_FAILURE; default: ERR("unexpected getopt_long() value '%c'.\n", c); diff --git a/tools/modinfo.c b/tools/modinfo.c index f5cb307..8ec24a9 100644 --- a/tools/modinfo.c +++ b/tools/modinfo.c @@ -367,6 +367,7 @@ static int do_modinfo(int argc, char *argv[]) bool arg_is_modname = false; int i, err, c; + opterr = 0; while ((c = getopt_long(argc, argv, cmdopts_s, cmdopts, NULL)) != -1) { switch (c) { case 'a': @@ -406,6 +407,8 @@ static int do_modinfo(int argc, char *argv[]) kmod_version(); return EXIT_SUCCESS; case '?': + ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + help(); return EXIT_FAILURE; default: ERR("unexpected getopt_long() value '%c'.\n", c); diff --git a/tools/modprobe.c b/tools/modprobe.c index 6eb06cd..c4b5021 100644 --- a/tools/modprobe.c +++ b/tools/modprobe.c @@ -813,6 +813,7 @@ static int do_modprobe(int argc, char **orig_argv) return EXIT_FAILURE; } + opterr = 0; while ((c = getopt_long(argc, argv, cmdopts_s, cmdopts, NULL)) != -1) { switch (c) { case 'a': @@ -935,6 +936,8 @@ static int do_modprobe(int argc, char **orig_argv) err = 0; goto done; case '?': + ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + help(); err = -1; goto done; default: diff --git a/tools/rmmod.c b/tools/rmmod.c index d8504ea..92f9f9c 100644 --- a/tools/rmmod.c +++ b/tools/rmmod.c @@ -101,6 +101,7 @@ static int do_rmmod(int argc, char *argv[]) int flags = 0; int i, c, r = 0; + opterr = 0; while ((c = getopt_long(argc, argv, cmdopts_s, cmdopts, NULL)) != -1) { switch (c) { case 'f': @@ -119,6 +120,8 @@ static int do_rmmod(int argc, char *argv[]) kmod_version(); return EXIT_SUCCESS; case '?': + ERR("unrecognised option \'%s\'\n\n", argv[optind - 1]); + help(); return EXIT_FAILURE; default: ERR("unexpected getopt_long() value '%c'.\n", c); diff --git a/tools/static-nodes.c b/tools/static-nodes.c index e64cd1b..61e239a 100644 --- a/tools/static-nodes.c +++ b/tools/static-nodes.c @@ -151,6 +151,7 @@ static int do_static_nodes(int argc, char *argv[]) int r, ret = EXIT_SUCCESS; int c, valid; + opterr = 0; while ((c = getopt_long(argc, argv, cmdopts_s, cmdopts, NULL)) != -1) { switch (c) { case 'o': @@ -177,6 +178,9 @@ static int do_static_nodes(int argc, char *argv[]) help(); goto finish; case '?': + fprintf(stderr, "unrecognised option \'%s\'\n\n", + argv[optind - 1]); + help(); ret = EXIT_FAILURE; goto finish; default: