|
|
6fdc0f |
2005-11-30 Alexandre Oliva <aoliva@redhat.com>
|
|
|
6fdc0f |
|
|
|
6fdc0f |
* gcc.c (find_a_file): Use update_path before access tests.
|
|
|
6fdc0f |
Mostly from Thomas Walker <thomas.walker@morganstanley.com>
|
|
|
6fdc0f |
* prefix.c (update_path): Move dir/../-stripping code to...
|
|
|
6fdc0f |
(maybe_strip_dotdots): New function. Reorganize.
|
|
|
6fdc0f |
|
|
|
6fdc0f |
--- gcc/gcc.c.orig 2005-12-01 18:38:38.000000000 -0200
|
|
|
6fdc0f |
+++ gcc/gcc.c 2005-12-01 18:41:01.000000000 -0200
|
|
|
6fdc0f |
@@ -2371,7 +2371,7 @@
|
|
|
6fdc0f |
find_a_file (struct path_prefix *pprefix, const char *name, int mode,
|
|
|
6fdc0f |
int multilib)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
- char *temp;
|
|
|
6fdc0f |
+ char *temp, *temp2;
|
|
|
6fdc0f |
const char *const file_suffix =
|
|
|
6fdc0f |
((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
|
|
|
6fdc0f |
struct prefix_list *pl;
|
|
|
6fdc0f |
@@ -2407,19 +2407,18 @@
|
|
|
6fdc0f |
NULL));
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
- temp = xmalloc (len);
|
|
|
6fdc0f |
-
|
|
|
6fdc0f |
/* Determine the filename to execute (special case for absolute paths). */
|
|
|
6fdc0f |
|
|
|
6fdc0f |
if (IS_ABSOLUTE_PATH (name))
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
- if (access (name, mode) == 0)
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- strcpy (temp, name);
|
|
|
6fdc0f |
- return temp;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
+ /* IS_ABSOLUTE_PATHNAME lets anything through that starts with '/' */
|
|
|
6fdc0f |
+ temp = update_path (name, NULL);
|
|
|
6fdc0f |
+ if (access (temp, mode) == 0)
|
|
|
6fdc0f |
+ return temp;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
else
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ temp = xmalloc (len);
|
|
|
6fdc0f |
for (pl = pprefix->plist; pl; pl = pl->next)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
const char *this_name
|
|
|
6fdc0f |
@@ -2435,24 +2434,30 @@
|
|
|
6fdc0f |
strcat (temp, machine_suffix);
|
|
|
6fdc0f |
strcat (temp, multilib_name);
|
|
|
6fdc0f |
strcat (temp, file_suffix);
|
|
|
6fdc0f |
- if (access_check (temp, mode) == 0)
|
|
|
6fdc0f |
+ temp2 = update_path (temp, NULL);
|
|
|
6fdc0f |
+ if (access_check (temp2, mode) == 0)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
if (pl->used_flag_ptr != 0)
|
|
|
6fdc0f |
*pl->used_flag_ptr = 1;
|
|
|
6fdc0f |
- return temp;
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
+ return temp2;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ free (temp2);
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
/* Now try just the multilib_name. */
|
|
|
6fdc0f |
strcpy (temp, pl->prefix);
|
|
|
6fdc0f |
strcat (temp, machine_suffix);
|
|
|
6fdc0f |
strcat (temp, multilib_name);
|
|
|
6fdc0f |
- if (access_check (temp, mode) == 0)
|
|
|
6fdc0f |
+ temp2 = update_path (temp, NULL);
|
|
|
6fdc0f |
+ if (access_check (temp2, mode) == 0)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
if (pl->used_flag_ptr != 0)
|
|
|
6fdc0f |
*pl->used_flag_ptr = 1;
|
|
|
6fdc0f |
- return temp;
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
+ return temp2;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ free (temp2);
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
/* Certain prefixes are tried with just the machine type,
|
|
|
6fdc0f |
@@ -2467,23 +2472,29 @@
|
|
|
6fdc0f |
strcat (temp, just_machine_suffix);
|
|
|
6fdc0f |
strcat (temp, multilib_name);
|
|
|
6fdc0f |
strcat (temp, file_suffix);
|
|
|
6fdc0f |
- if (access_check (temp, mode) == 0)
|
|
|
6fdc0f |
+ temp2 = update_path (temp, NULL);
|
|
|
6fdc0f |
+ if (access_check (temp2, mode) == 0)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
if (pl->used_flag_ptr != 0)
|
|
|
6fdc0f |
*pl->used_flag_ptr = 1;
|
|
|
6fdc0f |
- return temp;
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
+ return temp2;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ free (temp2);
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
strcpy (temp, pl->prefix);
|
|
|
6fdc0f |
strcat (temp, just_machine_suffix);
|
|
|
6fdc0f |
strcat (temp, multilib_name);
|
|
|
6fdc0f |
- if (access_check (temp, mode) == 0)
|
|
|
6fdc0f |
+ temp2 = update_path (temp, NULL);
|
|
|
6fdc0f |
+ if (access_check (temp2, mode) == 0)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
if (pl->used_flag_ptr != 0)
|
|
|
6fdc0f |
*pl->used_flag_ptr = 1;
|
|
|
6fdc0f |
- return temp;
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
+ return temp2;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ free (temp2);
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
/* Certain prefixes can't be used without the machine suffix
|
|
|
6fdc0f |
@@ -2497,24 +2508,31 @@
|
|
|
6fdc0f |
strcpy (temp, pl->prefix);
|
|
|
6fdc0f |
strcat (temp, this_name);
|
|
|
6fdc0f |
strcat (temp, file_suffix);
|
|
|
6fdc0f |
- if (access_check (temp, mode) == 0)
|
|
|
6fdc0f |
+ temp2 = update_path (temp, NULL);
|
|
|
6fdc0f |
+ if (access_check (temp2, mode) == 0)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
if (pl->used_flag_ptr != 0)
|
|
|
6fdc0f |
*pl->used_flag_ptr = 1;
|
|
|
6fdc0f |
- return temp;
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
+ return temp2;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ free (temp2);
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
strcpy (temp, pl->prefix);
|
|
|
6fdc0f |
strcat (temp, this_name);
|
|
|
6fdc0f |
- if (access_check (temp, mode) == 0)
|
|
|
6fdc0f |
+ temp2 = update_path (temp, NULL);
|
|
|
6fdc0f |
+ if (access_check (temp2, mode) == 0)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
if (pl->used_flag_ptr != 0)
|
|
|
6fdc0f |
*pl->used_flag_ptr = 1;
|
|
|
6fdc0f |
- return temp;
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
+ return temp2;
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ free (temp2);
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
|
|
|
6fdc0f |
free (temp);
|
|
|
6fdc0f |
return 0;
|
|
|
6fdc0f |
--- gcc/prefix.c.orig 2005-12-01 18:38:38.000000000 -0200
|
|
|
6fdc0f |
+++ gcc/prefix.c 2005-12-01 18:46:37.000000000 -0200
|
|
|
6fdc0f |
@@ -238,6 +238,105 @@
|
|
|
6fdc0f |
while (*string++);
|
|
|
6fdc0f |
}
|
|
|
6fdc0f |
|
|
|
6fdc0f |
+/* Strip dir/.. from a pathname when it makes sense, e.g., when this
|
|
|
6fdc0f |
+ would turn an inaccessible pathname into an accessible one.
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ We short-circuit dir/.. when dir does not exist, and when
|
|
|
6fdc0f |
+ some/dir/../thing does not exist but some/thing does. In case
|
|
|
6fdc0f |
+ there are multiple possible dir/../ stripping possibilities that
|
|
|
6fdc0f |
+ would turn an inaccessible pathname into an accessible one, the one
|
|
|
6fdc0f |
+ closer to the end of the pathname is preferred.
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ RESULT is the pathname that might contain such dotdot sequences to
|
|
|
6fdc0f |
+ be stripped. P points into RESULT, and indicates the location
|
|
|
6fdc0f |
+ where we should start looking for ../ sequences.
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ Even though RESULT is const, P is not, and that's because
|
|
|
6fdc0f |
+ characters in it may be temporarily overwritten, so RESULT must not
|
|
|
6fdc0f |
+ be in read-only storage.
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ The returned value is either a newly-allocated memory area, holding
|
|
|
6fdc0f |
+ a string that is the result of dotdot-stripping from the original
|
|
|
6fdc0f |
+ input strip, or RESULT itself, in which case any modifications made
|
|
|
6fdc0f |
+ to the string will have been undone. */
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+static const char *
|
|
|
6fdc0f |
+maybe_strip_dotdots (const char *result, char *p)
|
|
|
6fdc0f |
+{
|
|
|
6fdc0f |
+ char *temp;
|
|
|
6fdc0f |
+ const char *path, *before, *after;
|
|
|
6fdc0f |
+ size_t len;
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ while (1)
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ p = strchr (p, '.');
|
|
|
6fdc0f |
+ if (p == NULL)
|
|
|
6fdc0f |
+ return result;
|
|
|
6fdc0f |
+ /* Look for `/../' */
|
|
|
6fdc0f |
+ if (p[1] == '.'
|
|
|
6fdc0f |
+ && IS_DIR_SEPARATOR (p[2])
|
|
|
6fdc0f |
+ && (p != result && IS_DIR_SEPARATOR (p[-1])))
|
|
|
6fdc0f |
+ break;
|
|
|
6fdc0f |
+ else
|
|
|
6fdc0f |
+ ++p;
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ *p = 0;
|
|
|
6fdc0f |
+ if (access (result, X_OK) == 0)
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ *p = '.';
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ path = maybe_strip_dotdots (result, p + 3);
|
|
|
6fdc0f |
+ if (access (path, F_OK) == 0)
|
|
|
6fdc0f |
+ return path;
|
|
|
6fdc0f |
+ if (path != result)
|
|
|
6fdc0f |
+ free ((char *) path);
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+ else
|
|
|
6fdc0f |
+ *p = '.';
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ /* If we couldn't access the dir, or if recursion resulted in a
|
|
|
6fdc0f |
+ non-accessible pathname, we try stripping out dir/../. If `dir'
|
|
|
6fdc0f |
+ turns out to be `.', strip one more path component. */
|
|
|
6fdc0f |
+ before = p;
|
|
|
6fdc0f |
+ do
|
|
|
6fdc0f |
+ {
|
|
|
6fdc0f |
+ --before;
|
|
|
6fdc0f |
+ while (before != result && IS_DIR_SEPARATOR (*before))
|
|
|
6fdc0f |
+ --before;
|
|
|
6fdc0f |
+ while (before != result && !IS_DIR_SEPARATOR (before[-1]))
|
|
|
6fdc0f |
+ --before;
|
|
|
6fdc0f |
+ }
|
|
|
6fdc0f |
+ while (before != result && *before == '.'
|
|
|
6fdc0f |
+ && IS_DIR_SEPARATOR (*(before + 1)));
|
|
|
6fdc0f |
+ /* If we have something like `./..' or `/..', don't
|
|
|
6fdc0f |
+ strip anything more. */
|
|
|
6fdc0f |
+ if (*before == '.' || IS_DIR_SEPARATOR (*before))
|
|
|
6fdc0f |
+ return result;
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ after = p + 3;
|
|
|
6fdc0f |
+ while (IS_DIR_SEPARATOR (*after))
|
|
|
6fdc0f |
+ ++after;
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ len = (after - result) + strlen (after);
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ temp = xmalloc (len + 1 - (after - before));
|
|
|
6fdc0f |
+ memcpy (temp, result, before - result);
|
|
|
6fdc0f |
+ memcpy (temp + (before - result), after, len + 1 - (after - result));
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ path = maybe_strip_dotdots (temp, temp + (before - result));
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ if (path != temp)
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ if (access (path, F_OK) == 0)
|
|
|
6fdc0f |
+ result = path;
|
|
|
6fdc0f |
+ else if (path != result)
|
|
|
6fdc0f |
+ free ((char *) path);
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
+ return result;
|
|
|
6fdc0f |
+}
|
|
|
6fdc0f |
+
|
|
|
6fdc0f |
/* Update PATH using KEY if PATH starts with PREFIX. The returned
|
|
|
6fdc0f |
string is always malloc-ed, and the caller is responsible for
|
|
|
6fdc0f |
freeing it. */
|
|
|
6fdc0f |
@@ -245,7 +344,7 @@
|
|
|
6fdc0f |
char *
|
|
|
6fdc0f |
update_path (const char *path, const char *key)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
- char *result, *p;
|
|
|
6fdc0f |
+ char *result, *temp;
|
|
|
6fdc0f |
|
|
|
6fdc0f |
if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0)
|
|
|
6fdc0f |
{
|
|
|
6fdc0f |
@@ -265,62 +364,11 @@
|
|
|
6fdc0f |
else
|
|
|
6fdc0f |
result = xstrdup (path);
|
|
|
6fdc0f |
|
|
|
6fdc0f |
-#ifndef ALWAYS_STRIP_DOTDOT
|
|
|
6fdc0f |
-#define ALWAYS_STRIP_DOTDOT 0
|
|
|
6fdc0f |
-#endif
|
|
|
6fdc0f |
+ temp = result;
|
|
|
6fdc0f |
+ result = (char *) maybe_strip_dotdots (temp, temp);
|
|
|
6fdc0f |
|
|
|
6fdc0f |
- p = result;
|
|
|
6fdc0f |
- while (1)
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- char *src, *dest;
|
|
|
6fdc0f |
-
|
|
|
6fdc0f |
- p = strchr (p, '.');
|
|
|
6fdc0f |
- if (p == NULL)
|
|
|
6fdc0f |
- break;
|
|
|
6fdc0f |
- /* Look for `/../' */
|
|
|
6fdc0f |
- if (p[1] == '.'
|
|
|
6fdc0f |
- && IS_DIR_SEPARATOR (p[2])
|
|
|
6fdc0f |
- && (p != result && IS_DIR_SEPARATOR (p[-1])))
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- *p = 0;
|
|
|
6fdc0f |
- if (!ALWAYS_STRIP_DOTDOT && access (result, X_OK) == 0)
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- *p = '.';
|
|
|
6fdc0f |
- break;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- else
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- /* We can't access the dir, so we won't be able to
|
|
|
6fdc0f |
- access dir/.. either. Strip out `dir/../'. If `dir'
|
|
|
6fdc0f |
- turns out to be `.', strip one more path component. */
|
|
|
6fdc0f |
- dest = p;
|
|
|
6fdc0f |
- do
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- --dest;
|
|
|
6fdc0f |
- while (dest != result && IS_DIR_SEPARATOR (*dest))
|
|
|
6fdc0f |
- --dest;
|
|
|
6fdc0f |
- while (dest != result && !IS_DIR_SEPARATOR (dest[-1]))
|
|
|
6fdc0f |
- --dest;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- while (dest != result && *dest == '.');
|
|
|
6fdc0f |
- /* If we have something like `./..' or `/..', don't
|
|
|
6fdc0f |
- strip anything more. */
|
|
|
6fdc0f |
- if (*dest == '.' || IS_DIR_SEPARATOR (*dest))
|
|
|
6fdc0f |
- {
|
|
|
6fdc0f |
- *p = '.';
|
|
|
6fdc0f |
- break;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- src = p + 3;
|
|
|
6fdc0f |
- while (IS_DIR_SEPARATOR (*src))
|
|
|
6fdc0f |
- ++src;
|
|
|
6fdc0f |
- p = dest;
|
|
|
6fdc0f |
- while ((*dest++ = *src++) != 0)
|
|
|
6fdc0f |
- ;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
- else
|
|
|
6fdc0f |
- ++p;
|
|
|
6fdc0f |
- }
|
|
|
6fdc0f |
+ if (result != temp)
|
|
|
6fdc0f |
+ free (temp);
|
|
|
6fdc0f |
|
|
|
6fdc0f |
#ifdef UPDATE_PATH_HOST_CANONICALIZE
|
|
|
6fdc0f |
/* Perform host dependent canonicalization when needed. */
|