-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Jim Meyering on 9/10/2009 11:29 AM: >> readlink -fv missing => lists /path/to/missing >> readlink -fv missing/ => complains that missing is not a dir >> >> I would like to see: 'readlink -fv missing/' list '/path/to/missing', on the >> grounds that one could do 'mkdir missing' to bring the path into existence; >> this matches the documentation that -f ignores a missing final element >> (nowhere >> does it say the final element has to be a non-file). > > Yes, that makes sense.
This patch (on top of my canonicalize cleanups) does that: - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkqrur0ACgkQ84KuGfSFAYCBZgCfZQguPsWRKZJUh7WLF3Nli/tV okIAoJOg78QYodvBq2ybYCGlaqmS/7Zq =Yscq -----END PGP SIGNATURE-----
>From 424bfcda7e9dea15ae03e1332d7ca59b0d1b845d Mon Sep 17 00:00:00 2001 From: Eric Blake <e...@byu.net> Date: Sat, 12 Sep 2009 06:04:46 -0600 Subject: [PATCH] canonicalize: in CAN_ALL_BUT_LAST, allow trailing slash * lib/canonicalize.c (canonicalize_filename_mode): Skip trailing slashes when checking if last component is missing. * tests/test-canonicalize.c (main): Test this. Signed-off-by: Eric Blake <e...@byu.net> --- ChangeLog | 5 +++++ lib/canonicalize.c | 8 ++++++-- tests/test-canonicalize.c | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c03d38..c2290f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2009-09-12 Eric Blake <e...@byu.net> + canonicalize: in CAN_ALL_BUT_LAST, allow trailing slash + * lib/canonicalize.c (canonicalize_filename_mode): Skip trailing + slashes when checking if last component is missing. + * tests/test-canonicalize.c (main): Test this. + canonicalize, canonicalize-lgpl: honor // if distinct from / * modules/canonicalize (Files): Add double-slash-root.m4. * modules/canonicalize-lgpl (Files): Likewise. diff --git a/lib/canonicalize.c b/lib/canonicalize.c index a90f1a8..2374169 100644 --- a/lib/canonicalize.c +++ b/lib/canonicalize.c @@ -183,8 +183,12 @@ canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode) saved_errno = errno; if (can_mode == CAN_EXISTING) goto error; - if (can_mode == CAN_ALL_BUT_LAST && *end) - goto error; + if (can_mode == CAN_ALL_BUT_LAST) + { + if (end[strspn (end, "/")]) + goto error; + continue; + } st.st_mode = 0; } diff --git a/tests/test-canonicalize.c b/tests/test-canonicalize.c index f8dcc54..463297f 100644 --- a/tests/test-canonicalize.c +++ b/tests/test-canonicalize.c @@ -240,26 +240,42 @@ main () { char *result1 = canonicalize_filename_mode (BASE "/zzz", CAN_ALL_BUT_LAST); char *result2 = canonicalize_filename_mode (BASE "/zzz", CAN_MISSING); + char *result3 = canonicalize_filename_mode (BASE "/zzz/", CAN_ALL_BUT_LAST); + char *result4 = canonicalize_filename_mode (BASE "/zzz/", CAN_MISSING); ASSERT (result1 != NULL); ASSERT (result2 != NULL); + ASSERT (result3 != NULL); + ASSERT (result4 != NULL); ASSERT (strcmp (result1, result2) == 0); + ASSERT (strcmp (result2, result3) == 0); + ASSERT (strcmp (result3, result4) == 0); ASSERT (strcmp (result1 + strlen (result1) - strlen ("/" BASE "/zzz"), "/" BASE "/zzz") == 0); free (result1); free (result2); + free (result3); + free (result4); } /* Check that alternate modes can resolve broken symlink basenames. */ { char *result1 = canonicalize_filename_mode (BASE "/ouk", CAN_ALL_BUT_LAST); char *result2 = canonicalize_filename_mode (BASE "/ouk", CAN_MISSING); + char *result3 = canonicalize_filename_mode (BASE "/ouk/", CAN_ALL_BUT_LAST); + char *result4 = canonicalize_filename_mode (BASE "/ouk/", CAN_MISSING); ASSERT (result1 != NULL); ASSERT (result2 != NULL); + ASSERT (result3 != NULL); + ASSERT (result4 != NULL); ASSERT (strcmp (result1, result2) == 0); + ASSERT (strcmp (result2, result3) == 0); + ASSERT (strcmp (result3, result4) == 0); ASSERT (strcmp (result1 + strlen (result1) - strlen ("/" BASE "/wum"), "/" BASE "/wum") == 0); free (result1); free (result2); + free (result3); + free (result4); } /* Check that alternate modes can handle missing dirnames. */ -- 1.6.3.3.334.g916e1