2002-11-09 Andrew Cagney * utils.c (gdb_realpath): Rewrite. Try realpath() with a constant buffer, cannonicalize_file_name(), realpath() with a pathconf() defined buffer, xstrdup(). Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.76 diff -p -r1.76 utils.c *** utils.c 1 Aug 2002 17:18:33 -0000 1.76 --- utils.c 11 Nov 2002 16:33:36 -0000 *************** string_to_core_addr (const char *my_stri *** 2534,2564 **** char * gdb_realpath (const char *filename) { #if defined(HAVE_REALPATH) # if defined (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)); # define USE_REALPATH # 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); #endif } /* Return a copy of FILENAME, with its directory prefix canonicalized --- 2534,2597 ---- 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]; # define USE_REALPATH # elif defined (MAXPATHLEN) ! 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 */ ! /* 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