From e0b8973bd4b146b5fb39641a4ee7984e922c3ff5 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Tue, 6 Jul 2004 16:11:03 +0000 Subject: 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. --- src/readlink.c | 40 +++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) (limited to 'src/readlink.c') 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) { -- cgit v1.2.3-54-g00ecf