]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
Change "readlink -f" to be more compatible with prior implementations.
authorJim Meyering <jim@meyering.net>
Tue, 6 Jul 2004 16:11:03 +0000 (16:11 +0000)
committerJim Meyering <jim@meyering.net>
Tue, 6 Jul 2004 16:11:03 +0000 (16:11 +0000)
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

index dd9e5afe2041ed53876e089450dd0f8f04cdfb09..7df0a2d3168fccdb6fe267e37ea9ca77f133b3ad 100644 (file)
@@ -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)
     {