summaryrefslogtreecommitdiff
path: root/src/readlink.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2004-07-06 16:11:03 +0000
committerJim Meyering <jim@meyering.net>2004-07-06 16:11:03 +0000
commite0b8973bd4b146b5fb39641a4ee7984e922c3ff5 (patch)
tree1650c40c6ea48f150a05e8447d22db65d002cfc8 /src/readlink.c
parent554dc97975b1edcd894b163194fc529aa2a74722 (diff)
downloadcoreutils-e0b8973bd4b146b5fb39641a4ee7984e922c3ff5.tar.xz
Change "readlink -f" to be more compatible with prior implementations.
Add more canonicalize options, -e and -m. Add comprehensive tests for all readlink modes. (longopts): Add new options. (usage): Document them. (canonicalize_fname): New proxy function. (main): Handle new options.
Diffstat (limited to 'src/readlink.c')
-rw-r--r--src/readlink.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/src/readlink.c b/src/readlink.c
index dd9e5afe2..7df0a2d31 100644
--- a/src/readlink.c
+++ b/src/readlink.c
@@ -43,10 +43,14 @@ static int canonicalize;
static int no_newline;
/* If nonzero, report error messages. */
static int verbose;
+ /* In canonicalize mode, use this method. */
+canonicalize_mode_t can_mode = CAN_ALL_BUT_LAST;
static struct option const longopts[] =
{
{"canonicalize", no_argument, 0, 'f'},
+ {"canonicalize-existing", no_argument, 0, 'e'},
+ {"canonicalize-missing", no_argument, 0, 'm'},
{"no-newline", no_argument, 0, 'n'},
{"quiet", no_argument, 0, 'q'},
{"silent", no_argument, 0, 's'},
@@ -68,12 +72,19 @@ usage (int status)
fputs (_("Display value of a symbolic link on standard output.\n\n"),
stdout);
fputs (_("\
- -f, --canonicalize canonicalize by following every symlink in every\n\
- component of the given path recursively\n\
- -n, --no-newline do not output the trailing newline\n\
+ -f, --canonicalize canonicalize by following every symlink in\n\
+ every component of the given path recursively;\n\
+ all but the last path component must exist\n\
+ -e, --canonicalize-existing canonicalize by following every symlink in\n\
+ every component of the given path recursively,\n\
+ all path components must exist\n\
+ -m, --canonicalize-missing canonicalize by following every symlink in\n\
+ every component of the given path recursively,\n\
+ without requirements on components existence\n\
+ -n, --no-newline do not output the trailing newline\n\
-q, --quiet,\n\
- -s, --silent suppress most error messages\n\
- -v, --verbose report error messages\n\
+ -s, --silent suppress most error messages\n\
+ -v, --verbose report error messages\n\
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
@@ -82,6 +93,12 @@ usage (int status)
exit (status);
}
+static char *
+canonicalize_fname (const char *fname)
+{
+ return canonicalize_filename_mode (fname, can_mode);
+}
+
int
main (int argc, char *const argv[])
{
@@ -97,14 +114,23 @@ main (int argc, char *const argv[])
atexit (close_stdout);
- while ((optc = getopt_long (argc, argv, "fnqsv", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "efmnqsv", longopts, NULL)) != -1)
{
switch (optc)
{
case 0:
break;
+ case 'e':
+ canonicalize = 1;
+ can_mode = CAN_EXISTING;
+ break;
case 'f':
canonicalize = 1;
+ can_mode = CAN_ALL_BUT_LAST;
+ break;
+ case 'm':
+ canonicalize = 1;
+ can_mode = CAN_MISSING;
break;
case 'n':
no_newline = 1;
@@ -138,7 +164,7 @@ main (int argc, char *const argv[])
}
value = (canonicalize
- ? canonicalize_file_name (fname)
+ ? canonicalize_fname (fname)
: xreadlink (fname, 1024));
if (value)
{