-/* Normalize NAME by resolving any relative references and
- removing trailing slashes. Destructive version: modifies its argument. */
-static int
-normalize_filename_x (char *name)
-{
- char *p, *q;
-
- p = name;
- if (DOUBLE_SLASH_IS_DISTINCT_ROOT && ISSLASH (*p))
- p++;
-
- /* Remove /./, resolve /../ and compress sequences of slashes */
- for (q = p; *q; )
+/* Normalize FILE_NAME by removing redundant slashes and "."
+ components, including redundant trailing slashes. Leave ".."
+ alone, as it may be significant in the presence of symlinks and on
+ platforms where "/.." != "/". Destructive version: modifies its
+ argument. */
+static void
+normalize_filename_x (char *file_name)
+{
+ char *name = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
+ char *p;
+ char const *q;
+ char c;
+
+ /* Don't squeeze leading "//" to "/", on hosts where they're distinct. */
+ name += (DOUBLE_SLASH_IS_DISTINCT_ROOT
+ && ISSLASH (*name) && ISSLASH (name[1]) && ! ISSLASH (name[2]));
+
+ /* Omit redundant leading "." components. */
+ for (q = p = name; (*p = *q) == '.' && ISSLASH (q[1]); p += !*q)
+ for (q += 2; ISSLASH (*q); q++)
+ continue;
+
+ /* Copy components from Q to P, omitting redundant slashes and
+ internal "." components. */
+ while ((*p++ = c = *q++) != '\0')
+ if (ISSLASH (c))
+ while (ISSLASH (q[*q == '.']))
+ q += (*q == '.') + 1;
+
+ /* Omit redundant trailing "." component and slash. */
+ if (2 < p - name)