readlink: do not emit errors if file doesnt not exist / not a link getopt32: add =N support
No binary (build failed)
—
(log yok)
| @@ -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); |
| } | |
| @@ -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; | |