Coreutils' `readlink -f foo/' should not fail if lstat("foo")
gives ENOENT.
* 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 <ebb9@byu.net>
2009-09-17 Eric Blake <ebb9@byu.net>
2009-09-17 Eric Blake <ebb9@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.
canonicalize, canonicalize-lgpl: honor // if distinct from /
* modules/canonicalize (Files): Add double-slash-root.m4.
* modules/canonicalize-lgpl (Files): Likewise.
saved_errno = errno;
if (can_mode == CAN_EXISTING)
goto error;
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, "/")] || saved_errno != ENOENT)
+ goto error;
+ continue;
+ }
{
char *result1 = canonicalize_filename_mode (BASE "/zzz", CAN_ALL_BUT_LAST);
char *result2 = canonicalize_filename_mode (BASE "/zzz", CAN_MISSING);
{
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 (result1 != NULL);
ASSERT (result2 != NULL);
+ ASSERT (result3 != NULL);
+ ASSERT (result4 != NULL);
ASSERT (strcmp (result1, result2) == 0);
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);
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);
}
/* 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 (result1 != NULL);
ASSERT (result2 != NULL);
+ ASSERT (result3 != NULL);
+ ASSERT (result4 != NULL);
ASSERT (strcmp (result1, result2) == 0);
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);
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. */
}
/* Check that alternate modes can handle missing dirnames. */