This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[patch / rfc / 5.3] Attempt N++ for gdb_realpath()
- From: Andrew Cagney <ac131313 at redhat dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Mon, 11 Nov 2002 11:48:06 -0500
- Subject: [patch / rfc / 5.3] Attempt N++ for gdb_realpath()
Hello,
This is trying to fix
http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=656
It breaks the host system down into:
- realpath() and constant pathmax
- canonicalize file name
- realpath() and pathconf()
- xstrdup()
realpath() is split into two cases - the easy / common one and the nasty
horrible pathconf() one. The latter (which was causing grief on GNU)
has been moved to the end.
comments? For 5.3 and mainline.
Andrew
2002-11-09 Andrew Cagney <ac131313@redhat.com>
* 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