Index: utils.c =================================================================== RCS file: /cvs/src/src/gdb/utils.c,v retrieving revision 1.70 diff -c -3 -p -r1.70 utils.c *** utils.c 2002/03/19 02:51:07 1.70 --- utils.c 2002/03/19 17:53:01 *************** string_to_core_addr (const char *my_stri *** 2531,2558 **** return addr; } - 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) ! return canonicalize_file_name (filename); #else return xstrdup (filename); #endif } --- 2531,2641 ---- return addr; } #if defined(HAVE_REALPATH) # if defined (PATH_MAX) ! static const int max_rp_buffer_size = PATH_MAX; # define USE_REALPATH # elif defined (MAXPATHLEN) ! static const int max_rp_buffer_size = MAXPATHLEN; # define USE_REALPATH # elif defined (HAVE_UNISTD_H) && defined(HAVE_ALLOCA) ! static const int max_rp_buffer_size = pathconf ("/", _PC_PATH_MAX); # define USE_REALPATH # endif #endif /* HAVE_REALPATH */ + + /* + * gdb_canonicalize_path + * + * Sets RESOLVED_PATH to the canonicalized form of FILENAME, as realpath () + * does. If there is no error, it returns a pointer to the resolved path. + * Otherwise, returns null. + * + * Returns null on platforms where no canonicalization routine (such as + * realpath for instance) are available. + */ + static char * + gdb_canonicalize_path (const char *path, char *resolved_path) + { + #if defined (USE_REALPATH) + return realpath (path, resolved_path); + + #elif defined (HAVE_CANONICALIZE_FILE_NAME) + const char *canonicalized = canonicalize_file_name (path); + + if (!canonicalized) + return null; ! strcpy (resolved_path, canonicalized); ! return resolved_path; ! #else + return null; + + #endif + } + + /* + * gdb_realpath_fallback + * + * This is the fallback version of gdb_realpath when there is no + * canonicalization routine (such as realpath for instance) available. + * In this case, we simply return a copy of FILENAME. + */ + static char * + gdb_realpath_fallback (const char *filename) + { return xstrdup (filename); + } + + /* + * gdb_realpath + * + * Return a copy of FILENAME, with its directory prefix canonicalized, + * as for realpath() (see "man realpath" for more details on what + * this function does), or simply a copy of FILENAME on platforms + * where no canonicalization routine is available. + * + * We don't want to canonicalize the entire FILENAME, because + * the canonicalization routines used to perform the operation also + * expand symbolic links. If FILENAME is itself a link to another file, + * it can lead GDB to translate FILENAME into another filename that GDB + * does not know about. This can confuse graphical front-ends for GDB + * which, like GVD, rely on the filename displayed by GDB to get the + * current file:line location, for example. + */ + char * + gdb_realpath (const char *filename) + { + const char *base_name = lbasename (filename); + char *dir_name; + char *buf; + char *rp = NULL; + + #if !defined (USE_REALPATH) || !defined (HAVE_CANONICALIZE_FILE_NAME) + return gdb_realpath_fallback (filename); #endif + + /* If basename and filename are equal, then there is no path to + canonicalize. Just return a copy of filename */ + if (base_name == filename) + return xstrdup (filename); + + dir_name = alloca ((size_t) (base_name - filename + 1)); + strncpy (dir_name, filename, base_name - filename); + dir_name[base_name - filename] = '\000'; + + /* Allocate enough space to contain the largest path possible returned + by realpath, plus the SLASH_STRING and the base_name */ + buf = alloca ((size_t) max_rp_buffer_size + + strlen (SLASH_STRING) + strlen (base_name)); + rp = gdb_canonicalize_path (dir_name, buf); + + if (rp == NULL) + return xstrdup (filename); + + strcat (buf, SLASH_STRING); + strcat (buf, base_name); + return xstrdup (buf); } +