Commit f9200da2 by Neil Booth Committed by Neil Booth

configure.in: Add check for lstat.

	* configure.in: Add check for lstat.
	* configure, config.in: Regenerate.
	* cppinit.c (append_include_chain): Make empty path ".".
        * cpplib.c (do_line): Don't simplify #line paths.
        * cppfiles.c (remove_component_p): New function.
	(find_or_create_entry): Acknowledge stat () errors during
	path simplification.
	(handle_missing_header): Don't simplify paths.
        (_cpp_simplify_pathname): Don't simplify VMS paths.  Return
        the empty path untouched.  Don't leave a trailing '/'.

From-SVN: r41148
parent 0bda3da7
2001-04-06 Neil Booth <neil@daikokuya.demon.co.uk>
* configure.in: Add check for lstat.
* configure, config.in: Regenerate.
* cppinit.c (append_include_chain): Make empty path ".".
* cpplib.c (do_line): Don't simplify #line paths.
* cppfiles.c (remove_component_p): New function.
(find_or_create_entry): Acknowledge stat () errors during
path simplification.
(handle_missing_header): Don't simplify paths.
(_cpp_simplify_pathname): Don't simplify VMS paths. Return
the empty path untouched. Don't leave a trailing '/'.
2001-04-06 Benjamin Kosnik <bkoz@redhat.com> 2001-04-06 Benjamin Kosnik <bkoz@redhat.com>
* cppdefault.c (GPLUSPLUS_BACKWARD_INCLUDE_DIR): Add. * cppdefault.c (GPLUSPLUS_BACKWARD_INCLUDE_DIR): Add.
......
...@@ -134,6 +134,9 @@ ...@@ -134,6 +134,9 @@
/* Define if you have the kill function. */ /* Define if you have the kill function. */
#undef HAVE_KILL #undef HAVE_KILL
/* Define if you have the lstat function. */
#undef HAVE_LSTAT
/* Define if you have the munmap function. */ /* Define if you have the munmap function. */
#undef HAVE_MUNMAP #undef HAVE_MUNMAP
......
...@@ -3102,7 +3102,7 @@ fi ...@@ -3102,7 +3102,7 @@ fi
for ac_func in strtoul bsearch popen \ for ac_func in strtoul bsearch popen \
strchr strrchr kill getrlimit setrlimit atoll atoq \ strchr strrchr kill getrlimit setrlimit atoll atoq \
sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \ sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
fputs_unlocked getrusage iconv nl_langinfo fputs_unlocked getrusage iconv nl_langinfo lstat
do do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
echo "configure:3109: checking for $ac_func" >&5 echo "configure:3109: checking for $ac_func" >&5
......
...@@ -547,7 +547,7 @@ dnl gcc_AC_C_ENUM_BF_UNSIGNED ...@@ -547,7 +547,7 @@ dnl gcc_AC_C_ENUM_BF_UNSIGNED
AC_CHECK_FUNCS(strtoul bsearch popen \ AC_CHECK_FUNCS(strtoul bsearch popen \
strchr strrchr kill getrlimit setrlimit atoll atoq \ strchr strrchr kill getrlimit setrlimit atoll atoq \
sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \ sysconf isascii gettimeofday strsignal putc_unlocked fputc_unlocked \
fputs_unlocked getrusage iconv nl_langinfo) fputs_unlocked getrusage iconv nl_langinfo lstat)
AC_CHECK_TYPE(ssize_t, int) AC_CHECK_TYPE(ssize_t, int)
......
...@@ -101,6 +101,7 @@ static int report_missing_guard PARAMS ((splay_tree_node, void *)); ...@@ -101,6 +101,7 @@ static int report_missing_guard PARAMS ((splay_tree_node, void *));
static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *, static splay_tree_node find_or_create_entry PARAMS ((cpp_reader *,
const char *)); const char *));
static void handle_missing_header PARAMS ((cpp_reader *, const char *, int)); static void handle_missing_header PARAMS ((cpp_reader *, const char *, int));
static int remove_component_p PARAMS ((const char *));
/* Set up the splay tree we use to store information about all the /* Set up the splay tree we use to store information about all the
file names seen in this compilation. We also have entries for each file names seen in this compilation. We also have entries for each
...@@ -155,7 +156,8 @@ _cpp_never_reread (file) ...@@ -155,7 +156,8 @@ _cpp_never_reread (file)
} }
/* Lookup a filename, which is simplified after making a copy, and /* Lookup a filename, which is simplified after making a copy, and
create an entry if none exists. */ create an entry if none exists. errno is nonzero iff a (reported)
stat() error occurred during simplification. */
static splay_tree_node static splay_tree_node
find_or_create_entry (pfile, fname) find_or_create_entry (pfile, fname)
cpp_reader *pfile; cpp_reader *pfile;
...@@ -208,6 +210,9 @@ open_file (pfile, filename) ...@@ -208,6 +210,9 @@ open_file (pfile, filename)
splay_tree_node nd = find_or_create_entry (pfile, filename); splay_tree_node nd = find_or_create_entry (pfile, filename);
struct include_file *file = (struct include_file *) nd->value; struct include_file *file = (struct include_file *) nd->value;
if (errno)
file->fd = -2;
/* Don't retry opening if we failed previously. */ /* Don't retry opening if we failed previously. */
if (file->fd == -2) if (file->fd == -2)
return 0; return 0;
...@@ -643,7 +648,6 @@ handle_missing_header (pfile, fname, angle_brackets) ...@@ -643,7 +648,6 @@ handle_missing_header (pfile, fname, angle_brackets)
p[len++] = '/'; p[len++] = '/';
} }
memcpy (p + len, fname, fname_len + 1); memcpy (p + len, fname, fname_len + 1);
_cpp_simplify_pathname (p);
deps_add_dep (pfile->deps, p); deps_add_dep (pfile->deps, p);
} }
} }
...@@ -1006,6 +1010,26 @@ remap_filename (pfile, name, loc) ...@@ -1006,6 +1010,26 @@ remap_filename (pfile, name, loc)
return name; return name;
} }
/* Returns true if it is safe to remove the final component of path,
when it is followed by a ".." component. We use lstat to avoid
symlinks if we have it. If not, we can still catch errors with
stat (). */
static int
remove_component_p (path)
const char *path;
{
struct stat s;
int result;
#ifdef HAVE_LSTAT
result = lstat (path, &s);
#else
result = stat (path, &s);
#endif
return result == 0 && S_ISDIR (s.st_mode);
}
/* Simplify a path name in place, deleting redundant components. This /* Simplify a path name in place, deleting redundant components. This
reduces OS overhead and guarantees that equivalent paths compare reduces OS overhead and guarantees that equivalent paths compare
the same (modulo symlinks). the same (modulo symlinks).
...@@ -1018,16 +1042,23 @@ remap_filename (pfile, name, loc) ...@@ -1018,16 +1042,23 @@ remap_filename (pfile, name, loc)
//quux //quux (POSIX allows leading // as a namespace escape) //quux //quux (POSIX allows leading // as a namespace escape)
Guarantees no trailing slashes. All transforms reduce the length Guarantees no trailing slashes. All transforms reduce the length
of the string. Returns PATH; of the string. Returns PATH. errno is 0 if no error occurred;
*/ nonzero if an error occurred when using stat () or lstat (). */
char * char *
_cpp_simplify_pathname (path) _cpp_simplify_pathname (path)
char *path; char *path;
{ {
#ifndef VMS
char *from, *to; char *from, *to;
char *base; char *base, *orig_base;
int absolute = 0; int absolute = 0;
errno = 0;
/* Don't overflow the empty path by putting a '.' in it below. */
if (*path == '\0')
return path;
#if defined (HAVE_DOS_BASED_FILE_SYSTEM) #if defined (HAVE_DOS_BASED_FILE_SYSTEM)
/* Convert all backslashes to slashes. */ /* Convert all backslashes to slashes. */
for (from = path; *from; from++) for (from = path; *from; from++)
...@@ -1042,7 +1073,7 @@ _cpp_simplify_pathname (path) ...@@ -1042,7 +1073,7 @@ _cpp_simplify_pathname (path)
from = to = path; from = to = path;
#endif #endif
/* Remove redundant initial /s. */ /* Remove redundant leading /s. */
if (*from == '/') if (*from == '/')
{ {
absolute = 1; absolute = 1;
...@@ -1058,83 +1089,74 @@ _cpp_simplify_pathname (path) ...@@ -1058,83 +1089,74 @@ _cpp_simplify_pathname (path)
to++; to++;
} }
} }
base = to;
base = orig_base = to;
for (;;) for (;;)
{ {
int move_base = 0;
while (*from == '/') while (*from == '/')
from++; from++;
if (from[0] == '.' && from[1] == '/') if (*from == '\0')
from += 2; break;
else if (from[0] == '.' && from[1] == '\0')
goto done; if (*from == '.')
else if (from[0] == '.' && from[1] == '.' && from[2] == '/')
{
if (base == to)
{
if (absolute)
from += 3;
else
{ {
*to++ = *from++; if (from[1] == '\0')
*to++ = *from++; break;
*to++ = *from++; if (from[1] == '/')
base = to;
}
}
else
{ {
to -= 2; from += 2;
while (to > base && *to != '/') to--; continue;
if (*to == '/')
to++;
from += 3;
}
} }
else if (from[0] == '.' && from[1] == '.' && from[2] == '\0') else if (from[1] == '.' && (from[2] == '/' || from[2] == '\0'))
{ {
if (base == to) /* Don't simplify if there was no previous component. */
if (absolute && orig_base == to)
{ {
if (!absolute) from += 2;
{ continue;
*to++ = *from++;
*to++ = *from++;
}
} }
else /* Don't simplify if the previous component was "../",
or if an error has already occurred with (l)stat. */
if (base != to && errno == 0)
{ {
to -= 2; /* We don't back up if it's a symlink. */
while (to > base && *to != '/') to--; *to = '\0';
if (*to == '/') if (remove_component_p (path))
to++;
}
goto done;
}
else
/* Copy this component and trailing /, if any. */
while ((*to++ = *from++) != '/')
{
if (!to[-1])
{ {
while (to > base && *to != '/')
to--; to--;
goto done; from += 2;
continue;
} }
} }
move_base = 1;
}
} }
done: /* Add the component separator. */
/* Trim trailing slash */ if (to > orig_base)
if (to[0] == '/' && (!absolute || to > path+1)) *to++ = '/';
to--;
/* Change the empty string to "." so that stat() on the result /* Copy this component until the trailing null or '/'. */
will always work. */ while (*from != '\0' && *from != '/')
*to++ = *from++;
if (move_base)
base = to;
}
/* Change the empty string to "." so that it is not treated as stdin.
Null terminate. */
if (to == path) if (to == path)
*to++ = '.'; *to++ = '.';
*to = '\0'; *to = '\0';
return path; return path;
#else /* VMS */
errno = 0;
return path;
#endif /* !VMS */
} }
...@@ -211,6 +211,8 @@ append_include_chain (pfile, dir, path, cxx_aware) ...@@ -211,6 +211,8 @@ append_include_chain (pfile, dir, path, cxx_aware)
struct stat st; struct stat st;
unsigned int len; unsigned int len;
if (*dir == '\0')
dir = xstrdup (".");
_cpp_simplify_pathname (dir); _cpp_simplify_pathname (dir);
if (stat (dir, &st)) if (stat (dir, &st))
{ {
......
...@@ -729,12 +729,7 @@ do_line (pfile) ...@@ -729,12 +729,7 @@ do_line (pfile)
cpp_get_token (pfile, &token); cpp_get_token (pfile, &token);
if (token.type == CPP_STRING) if (token.type == CPP_STRING)
{ {
char *fname; const char *fname = (const char *) token.val.str.text;
unsigned int len = token.val.str.len + 1;
fname = (char *) _cpp_pool_alloc (&pfile->ident_pool, len);
memcpy (fname, token.val.str.text, len);
_cpp_simplify_pathname (fname);
/* Only accept flags for the # 55 form. */ /* Only accept flags for the # 55 form. */
if (! pfile->state.line_extension) if (! pfile->state.line_extension)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment