2002-07-17 Alan Modra * prefix.c (update_path): Strip ".." components when prior dir doesn't exist. Pass correct var to UPDATE_PATH_HOST_CANONICALIZE. --- gcc-3.2/gcc/prefix.c.strip-dotdot 2001-10-11 05:15:55.000000000 +0200 +++ gcc-3.2/gcc/prefix.c 2002-08-17 09:37:01.000000000 +0200 @@ -251,7 +252,7 @@ update_path (path, key) const char *path; const char *key; { - char *result; + char *result, *p; if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0) { @@ -271,9 +272,66 @@ update_path (path, key) else result = xstrdup (path); +#ifndef ALWAYS_STRIP_DOTDOT +#define ALWAYS_STRIP_DOTDOT 0 +#endif + + p = result; + while (1) + { + char *src, *dest; + + p = strchr (p, '.'); + if (p == NULL) + break; + /* Look for `/../' */ + if (p[1] == '.' + && IS_DIR_SEPARATOR (p[2]) + && (p != result && IS_DIR_SEPARATOR (p[-1]))) + { + *p = 0; + if (!ALWAYS_STRIP_DOTDOT && access (result, X_OK) == 0) + { + *p = '.'; + break; + } + else + { + /* We can't access the dir, so we won't be able to + access dir/.. either. Strip out `dir/../'. If `dir' + turns out to be `.', strip one more path component. */ + dest = p; + do + { + --dest; + while (dest != result && IS_DIR_SEPARATOR (*dest)) + --dest; + while (dest != result && !IS_DIR_SEPARATOR (dest[-1])) + --dest; + } + while (dest != result && *dest == '.'); + /* If we have something like `./..' or `/..', don't + strip anything more. */ + if (*dest == '.' || IS_DIR_SEPARATOR (*dest)) + { + *p = '.'; + break; + } + src = p + 3; + while (IS_DIR_SEPARATOR (*src)) + ++src; + p = dest; + while ((*dest++ = *src++) != 0) + ; + } + } + else + ++p; + } + #ifdef UPDATE_PATH_HOST_CANONICALIZE /* Perform host dependent canonicalization when needed. */ - UPDATE_PATH_HOST_CANONICALIZE (path); + UPDATE_PATH_HOST_CANONICALIZE (result); #endif #ifdef DIR_SEPARATOR_2