#include "xalloc.h"
#include "xgetcwd.h"
-#if !(HAVE_CANONICALIZE_FILE_NAME || GNULIB_CANONICALIZE_LGPL)
+#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
+# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
+#endif
+
+#if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS) \
+ || GNULIB_CANONICALIZE_LGPL)
/* Return the canonical absolute name of file NAME. A canonical name
does not contain any `.', `..' components nor any repeated file name
separators ('/') or symlinks. All components must exist.
rname_limit = rname + PATH_MAX;
rname[0] = '/';
dest = rname + 1;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/')
+ *dest++ = '/';
}
for (start = name; *start; start = end)
/* Back up to previous component, ignore if at root already. */
if (dest > rname + 1)
while ((--dest)[-1] != '/');
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
+ && *dest == '/')
+ dest++;
}
else
{
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;
+ }
st.st_mode = 0;
}
name = end = memcpy (extra_buf, buf, n);
if (buf[0] == '/')
- dest = rname + 1; /* It's an absolute symlink */
+ {
+ dest = rname + 1; /* It's an absolute symlink */
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/')
+ *dest++ = '/';
+ }
else
- /* Back up to previous component, ignore if at root already: */
- if (dest > rname + 1)
- while ((--dest)[-1] != '/');
+ {
+ /* Back up to previous component, ignore if at root
+ already: */
+ if (dest > rname + 1)
+ while ((--dest)[-1] != '/');
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
+ && *dest == '/')
+ dest++;
+ }
free (buf);
}
}
if (dest > rname + 1 && dest[-1] == '/')
--dest;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && *dest == '/')
+ dest++;
*dest = '\0';
free (extra_buf);