diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 4e50111526..55a1134e3d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,9 @@ +2002-11-12 Andrew Cagney + + * utils.c (gdb_realpath): Rewrite. Try, in order: realpath() with + a constant buffer; cannonicalize_file_name(); realpath() with a + pathconf() defined buffer, xstrdup(). + 2002-11-12 Andrew Cagney * config/djgpp/fnchange.lst: Fix typo, hang1.c to hang1.C; hang2.c diff --git a/gdb/utils.c b/gdb/utils.c index 24a2819f49..b2a1d1810b 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -2704,31 +2704,64 @@ string_to_core_addr (const char *my_string) char * gdb_realpath (const char *filename) { + /* Method 1: The system has a compile time upper bound on a filename + path. Use that and realpath() to canonicalize the name. This is + the most common case. Note that, if there isn't a compile time + upper bound, you want to avoid realpath() at all costs. */ #if defined(HAVE_REALPATH) + { # if defined (PATH_MAX) - char buf[PATH_MAX]; + char buf[PATH_MAX]; # define USE_REALPATH # elif defined (MAXPATHLEN) - char buf[MAXPATHLEN]; -# define USE_REALPATH -# elif defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA) - char *buf = alloca ((size_t)pathconf ("/", _PC_PATH_MAX)); + char buf[MAXPATHLEN]; # define USE_REALPATH # endif +# if defined (USE_REALPATH) + char *rp = realpath (filename, buf); + if (rp == NULL) + rp = filename; + return xstrdup (rp); + } +# endif #endif /* HAVE_REALPATH */ -#if defined(USE_REALPATH) - char *rp = realpath (filename, buf); - return xstrdup (rp ? rp : filename); -#elif defined(HAVE_CANONICALIZE_FILE_NAME) - char *rp = canonicalize_file_name (filename); - if (rp == NULL) - return xstrdup (filename); - else - return rp; -#else - return xstrdup (filename); + /* Method 2: The host system (i.e., GNU) has the function + canonicalize_file_name() which malloc's a chunk of memory and + returns that, use that. */ +#if defined(HAVE_CANONICALIZE_FILE_NAME) + { + char *rp = canonicalize_file_name (filename); + if (rp == NULL) + return xstrdup (filename); + else + return rp; + } #endif + + /* Method 3: Now we're getting desperate! The system doesn't have a + compile time buffer size and no alternative function. Query the + OS, using pathconf(), for the buffer limit. Care is needed + though, some systems do not limit PATH_MAX (return -1 for + pathconf()) making it impossible to pass a correctly sized buffer + to realpath() (it could always overflow). On those systems, we + skip this. */ +#if defined (HAVE_REALPATH) && defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA) + { + /* Find out the max path size. */ + long path_max = pathconf ("/", _PC_PATH_MAX); + if (path_max > 0) + { + /* PATH_MAX is bounded. */ + char *buf = alloca (path_max); + char *rp = realpath (filename, buf); + return xstrdup (rp ? rp : filename); + } + } +#endif + + /* This system is a lost cause, just dup the buffer. */ + return xstrdup (filename); } /* Return a copy of FILENAME, with its directory prefix canonicalized