diff options
| author | Eric Blake <eblake@redhat.com> | 2023-03-24 09:58:14 -0500 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-04-16 18:01:44 +0200 |
| commit | d2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a (patch) | |
| tree | 4e80a2e7eaf488830ef8a6d22544885a9a038299 /coreutils | |
| parent | 2ffd8986e21f1782c78e1a9d34f6042af53d876c (diff) | |
| download | busybox-w32-d2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a.tar.gz busybox-w32-d2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a.tar.bz2 busybox-w32-d2b81b3dc2b31d32e1060d3ea8bd998d30a37d8a.zip | |
readlink: support --, -n always
POSIX will be standardizing readlink (just the -n option) and realpath
(just -E and -e options):
https://www.austingroupbugs.net/view.php?id=1457
Change things for readlink so that the POSIX-mandated -n and -- work
even when disabling the non-standard (and partially non-working) -f
when FEATURE_READLINK_FOLLOW is clear.
POSIX also wants readlink to be verbose by default (if the argument is
not a symlink, readlink must output a diagnostic); I did NOT address
that one, because I'm waiting to see what the GNU Coreutils folks do:
https://lists.gnu.org/archive/html/bug-coreutils/2023-03/msg00035.html
Partial fix for https://bugs.busybox.net/show_bug.cgi?id=15466
function old new delta
packed_usage 34538 34557 +19
Signed-off-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/readlink.c | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/coreutils/readlink.c b/coreutils/readlink.c index b2e867883..0a9aa957e 100644 --- a/coreutils/readlink.c +++ b/coreutils/readlink.c | |||
| @@ -25,12 +25,14 @@ | |||
| 25 | //kbuild:lib-$(CONFIG_READLINK) += readlink.o | 25 | //kbuild:lib-$(CONFIG_READLINK) += readlink.o |
| 26 | 26 | ||
| 27 | //usage:#define readlink_trivial_usage | 27 | //usage:#define readlink_trivial_usage |
| 28 | //usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") "FILE" | 28 | //usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") |
| 29 | //usage: IF_NOT_FEATURE_READLINK_FOLLOW("[-n] ") | ||
| 30 | //usage: "FILE" | ||
| 29 | //usage:#define readlink_full_usage "\n\n" | 31 | //usage:#define readlink_full_usage "\n\n" |
| 30 | //usage: "Display the value of a symlink" | 32 | //usage: "Display the value of a symlink" "\n" |
| 31 | //usage: IF_FEATURE_READLINK_FOLLOW( "\n" | ||
| 32 | //usage: "\n -f Canonicalize by following all symlinks" | ||
| 33 | //usage: "\n -n Don't add newline" | 33 | //usage: "\n -n Don't add newline" |
| 34 | //usage: IF_FEATURE_READLINK_FOLLOW( | ||
| 35 | //usage: "\n -f Canonicalize by following all symlinks" | ||
| 34 | //usage: "\n -v Verbose" | 36 | //usage: "\n -v Verbose" |
| 35 | //usage: ) | 37 | //usage: ) |
| 36 | 38 | ||
| @@ -67,25 +69,18 @@ int readlink_main(int argc UNUSED_PARAM, char **argv) | |||
| 67 | { | 69 | { |
| 68 | char *buf; | 70 | char *buf; |
| 69 | char *fname; | 71 | char *fname; |
| 72 | unsigned opt; | ||
| 70 | 73 | ||
| 71 | IF_FEATURE_READLINK_FOLLOW( | 74 | opt = getopt32(argv, "^" "n" IF_FEATURE_READLINK_FOLLOW("fvsq") |
| 72 | unsigned opt; | 75 | "\0" "=1"); |
| 73 | /* We need exactly one non-option argument. */ | 76 | fname = argv[optind]; |
| 74 | opt = getopt32(argv, "^" "fnvsq" "\0" "=1"); | ||
| 75 | fname = argv[optind]; | ||
| 76 | ) | ||
| 77 | IF_NOT_FEATURE_READLINK_FOLLOW( | ||
| 78 | const unsigned opt = 0; | ||
| 79 | if (argc != 2) bb_show_usage(); | ||
| 80 | fname = argv[1]; | ||
| 81 | ) | ||
| 82 | 77 | ||
| 83 | /* compat: coreutils readlink reports errors silently via exit code */ | 78 | /* compat: coreutils readlink reports errors silently via exit code */ |
| 84 | if (!(opt & 4)) /* not -v */ | 79 | if (!(opt & 4)) /* not -v */ |
| 85 | logmode = LOGMODE_NONE; | 80 | logmode = LOGMODE_NONE; |
| 86 | 81 | ||
| 87 | /* NOFORK: only one alloc is allowed; must free */ | 82 | /* NOFORK: only one alloc is allowed; must free */ |
| 88 | if (opt & 1) { /* -f */ | 83 | if (opt & 2) { /* -f */ |
| 89 | buf = xmalloc_realpath_coreutils(fname); | 84 | buf = xmalloc_realpath_coreutils(fname); |
| 90 | } else { | 85 | } else { |
| 91 | buf = xmalloc_readlink_or_warn(fname); | 86 | buf = xmalloc_readlink_or_warn(fname); |
| @@ -93,7 +88,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv) | |||
| 93 | 88 | ||
| 94 | if (!buf) | 89 | if (!buf) |
| 95 | return EXIT_FAILURE; | 90 | return EXIT_FAILURE; |
| 96 | printf((opt & 2) ? "%s" : "%s\n", buf); | 91 | printf((opt & 1) ? "%s" : "%s\n", buf); |
| 97 | free(buf); | 92 | free(buf); |
| 98 | 93 | ||
| 99 | fflush_stdout_and_exit_SUCCESS(); | 94 | fflush_stdout_and_exit_SUCCESS(); |
