diff options
-rw-r--r-- | debianutils/readlink.c | 37 | ||||
-rw-r--r-- | libbb/getopt32.c | 9 |
2 files changed, 33 insertions, 13 deletions
diff --git a/debianutils/readlink.c b/debianutils/readlink.c index 0d5ad94f4..9536d3200 100644 --- a/debianutils/readlink.c +++ b/debianutils/readlink.c @@ -13,21 +13,32 @@ #include <stdlib.h> #include <getopt.h> -#define READLINK_FLAG_f (1 << 0) - int readlink_main(int argc, char **argv) { char *buf; - unsigned opt = ENABLE_FEATURE_READLINK_FOLLOW ? - getopt32(argc, argv, "f") : 0; - - if (argc != (ENABLE_FEATURE_READLINK_FOLLOW ? optind + 1 : 2)) - bb_show_usage(); - - if (opt & READLINK_FLAG_f) - buf = realpath(argv[optind], bb_common_bufsiz1); - else - buf = xreadlink(argv[ENABLE_FEATURE_READLINK_FOLLOW ? optind : 1]); + char *fname; + + USE_FEATURE_READLINK_FOLLOW( + unsigned opt; + /* We need exactly one non-option argument. */ + opt_complementary = "=1"; + opt = getopt32(argc, argv, "f"); + fname = argv[optind]; + ) + SKIP_FEATURE_READLINK_FOLLOW( + const unsigned opt = 0; + if (argc != 2) bb_show_usage(); + fname = argv[1]; + ) + + /* compat: coreutils readlink reports errors silently via exit code */ + logmode = LOGMODE_NONE; + + if (opt) { + buf = realpath(fname, bb_common_bufsiz1); + } else { + buf = xreadlink(fname); + } if (!buf) return EXIT_FAILURE; @@ -36,5 +47,5 @@ int readlink_main(int argc, char **argv) if (ENABLE_FEATURE_CLEAN_UP && buf != bb_common_bufsiz1) free(buf); - return EXIT_SUCCESS; + bb_fflush_stdout_and_exit(EXIT_SUCCESS); } diff --git a/libbb/getopt32.c b/libbb/getopt32.c index 2f2f0b9e9..73e6b8684 100644 --- a/libbb/getopt32.c +++ b/libbb/getopt32.c @@ -188,6 +188,10 @@ Special characters: by a single digit (0-9) means that at least N non-option arguments must be present on the command line + "=N" An equal sign as the first char in a opt_complementary group followed + by a single digit (0-9) means that exactly N non-option + arguments must be present on the command line + "V-" An option with dash before colon or end-of-line results in bb_show_usage being called if this option is encountered. This is typically used to implement "print verbose usage message @@ -400,6 +404,11 @@ getopt32(int argc, char **argv, const char *applet_opts, ...) } continue; } + if (*s == '=') { + min_arg = max_arg = c - '0'; + s++; + continue; + } for (on_off = complementary; on_off->opt; on_off++) if (on_off->opt == *s) break; |