X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=libiberty%2Fmake-relative-prefix.c;h=e3f9f920df4a2b4a8be00e88727d74a42ed46eea;hb=348fe36b1d64f12c60e08f6313520b3191663063;hp=80e7f92fb418297bec8c14ca22f5cdcb09789a61;hpb=cefec4092d6c88bb538f85769b464dea126ec274;p=deliverable%2Fbinutils-gdb.git diff --git a/libiberty/make-relative-prefix.c b/libiberty/make-relative-prefix.c index 80e7f92fb4..e3f9f920df 100644 --- a/libiberty/make-relative-prefix.c +++ b/libiberty/make-relative-prefix.c @@ -1,6 +1,5 @@ /* Relative (relocatable) prefix support. - Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2006 Free Software Foundation, Inc. + Copyright (C) 1987-2020 Free Software Foundation, Inc. This file is part of libiberty. @@ -21,7 +20,8 @@ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA /* -@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, const char *@var{bin_prefix}, const char *@var{prefix}) +@deftypefn Extension {const char*} make_relative_prefix (const char *@var{progname}, @ + const char *@var{bin_prefix}, const char *@var{prefix}) Given three paths @var{progname}, @var{bin_prefix}, @var{prefix}, return the path that is in the same position relative to @@ -57,6 +57,9 @@ relative prefix can be found, return @code{NULL}. #ifdef HAVE_UNISTD_H #include #endif +#ifdef HAVE_SYS_STAT_H +#include +#endif #include @@ -119,6 +122,9 @@ split_directories (const char *name, int *ptr_num_dirs) const char *p, *q; int ch; + if (!*name) + return NULL; + /* Count the number of directories. Special case MSDOS disk names as part of the initial directory. */ p = name; @@ -229,6 +235,7 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, int i, n, common; int needed_len; char *ret = NULL, *ptr, *full_progname; + char *alloc_ptr = NULL; if (progname == NULL || bin_prefix == NULL || prefix == NULL) return NULL; @@ -244,10 +251,18 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, { char *startp, *endp, *nstore; size_t prefixlen = strlen (temp) + 1; + size_t len; if (prefixlen < 2) prefixlen = 2; - nstore = (char *) alloca (prefixlen + strlen (progname) + 1); + len = prefixlen + strlen (progname) + 1; +#ifdef HAVE_HOST_EXECUTABLE_SUFFIX + len += strlen (HOST_EXECUTABLE_SUFFIX); +#endif + if (len < MAX_ALLOCA_SIZE) + nstore = (char *) alloca (len); + else + alloc_ptr = nstore = (char *) malloc (len); startp = endp = temp; while (1) @@ -262,7 +277,7 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, } else { - strncpy (nstore, startp, endp - startp); + memcpy (nstore, startp, endp - startp); if (! IS_DIR_SEPARATOR (endp[-1])) { nstore[endp - startp] = DIR_SEPARATOR; @@ -278,8 +293,14 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, #endif ) { - progname = nstore; - break; +#if defined (HAVE_SYS_STAT_H) && defined (S_ISREG) + struct stat st; + if (stat (nstore, &st) >= 0 && S_ISREG (st.st_mode)) +#endif + { + progname = nstore; + break; + } } if (*endp == 0) @@ -292,19 +313,17 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, } } - if ( resolve_links ) - { - full_progname = lrealpath (progname); - if (full_progname == NULL) - return NULL; - } + if (resolve_links) + full_progname = lrealpath (progname); else - full_progname = strdup(progname); + full_progname = strdup (progname); + if (full_progname == NULL) + goto bailout; prog_dirs = split_directories (full_progname, &prog_num); free (full_progname); if (prog_dirs == NULL) - return NULL; + goto bailout; bin_dirs = split_directories (bin_prefix, &bin_num); if (bin_dirs == NULL) @@ -382,6 +401,7 @@ make_relative_prefix_1 (const char *progname, const char *bin_prefix, free_split_directories (prog_dirs); free_split_directories (bin_dirs); free_split_directories (prefix_dirs); + free (alloc_ptr); return ret; }