1 /* vi: set sw=4 ts=4: */
3 * Mini readlink implementation for busybox
5 * Copyright (C) 2000,2001 Matt Kraai <kraai@alumni.carnegiemellon.edu>
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
9 //config:config READLINK
10 //config: bool "readlink (4.8 kb)"
13 //config: This program reads a symbolic link and returns the name
14 //config: of the file it points to
16 //config:config FEATURE_READLINK_FOLLOW
17 //config: bool "Enable canonicalization by following all symlinks (-f)"
19 //config: depends on READLINK
21 //config: Enable the readlink option (-f).
23 //applet:IF_READLINK(APPLET_NOFORK(readlink, readlink, BB_DIR_USR_BIN, BB_SUID_DROP, readlink))
25 //kbuild:lib-$(CONFIG_READLINK) += readlink.o
27 //usage:#define readlink_trivial_usage
28 //usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ")
29 //usage: IF_NOT_FEATURE_READLINK_FOLLOW("[-n] ")
31 //usage:#define readlink_full_usage "\n\n"
32 //usage: "Display the value of a symlink" "\n"
33 //usage: "\n -n Don't add newline"
34 //usage: IF_FEATURE_READLINK_FOLLOW(
35 //usage: "\n -f Canonicalize by following all symlinks"
36 //usage: "\n -v Verbose"
42 * # readlink --version
43 * readlink (GNU coreutils) 6.10
46 * canonicalize by following every symlink in
47 * every component of the given name recursively;
48 * all but the last component must exist
49 * -e, --canonicalize-existing
50 * canonicalize by following every symlink in
51 * every component of the given name recursively,
52 * all components must exist
53 * -m, --canonicalize-missing
54 * canonicalize by following every symlink in
55 * every component of the given name recursively,
56 * without requirements on components existence
57 * -n, --no-newline do not output the trailing newline
58 * -q, --quiet, -s, --silent suppress most error messages
59 * -v, --verbose report error messages
61 * bbox supports: -f (partially) -n -v (fully), -q -s (accepts but ignores)
62 * Note: we export the -f flag, but our -f behaves like coreutils' -e.
63 * Unfortunately, there isn't a C lib function we can leverage to get this
64 * behavior which means we'd have to implement the full stack ourselves :(.
67 int readlink_main(int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
68 int readlink_main(int argc UNUSED_PARAM
, char **argv
)
73 /* -n must use bit 0 (see printf below) */
74 opt
= getopt32(argv
, "^" "n" IF_FEATURE_READLINK_FOLLOW("fvsq")
77 /* compat: coreutils readlink reports errors silently via exit code */
78 if (!(opt
& 4)) /* not -v */
79 logmode
= LOGMODE_NONE
;
81 /* NOFORK: only one alloc is allowed; must free */
82 if (opt
& 2) { /* -f */
83 buf
= xmalloc_realpath_coreutils(argv
[optind
]);
85 buf
= xmalloc_readlink_or_warn(argv
[optind
]);
90 printf("%s%s", buf
, &"\n"[opt
& 1]);
93 fflush_stdout_and_exit_SUCCESS();