--- embedaddon/libiconv/srclib/progreloc.c 2012/05/29 09:29:43 1.1.1.2 +++ embedaddon/libiconv/srclib/progreloc.c 2021/03/17 13:38:46 1.1.1.3 @@ -1,5 +1,5 @@ /* Provide relocatable programs. - Copyright (C) 2003-2011 Free Software Foundation, Inc. + Copyright (C) 2003-2019 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software: you can redistribute it and/or modify @@ -13,7 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ #define _GL_USE_STDLIB_ALLOC 1 @@ -22,6 +22,7 @@ /* Specification. */ #include "progname.h" +#include #include #include #include @@ -30,20 +31,25 @@ #include #include -/* Get declaration of _NSGetExecutablePath on MacOS X 10.2 or newer. */ +/* Get declaration of _NSGetExecutablePath on Mac OS X 10.2 or newer. */ #if HAVE_MACH_O_DYLD_H # include #endif -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ -# define WIN32_NATIVE +#if defined _WIN32 && !defined __CYGWIN__ +# define WINDOWS_NATIVE #endif -#ifdef WIN32_NATIVE +#ifdef WINDOWS_NATIVE # define WIN32_LEAN_AND_MEAN # include #endif +#ifdef __EMX__ +# define INCL_DOS +# include +#endif + #include "relocatable.h" #ifdef NO_XMALLOC @@ -73,8 +79,8 @@ extern char * canonicalize_file_name (const char *name ISSLASH(C) tests whether C is a directory separator character. IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. */ -#if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ +#if (defined _WIN32 && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__ + /* Native Windows, OS/2, DOS */ # define ISSLASH(C) ((C) == '/' || (C) == '\\') # define HAS_DEVICE(P) \ ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ @@ -89,11 +95,6 @@ extern char * canonicalize_file_name (const char *name # define FILE_SYSTEM_PREFIX_LEN(P) 0 #endif -/* The results of open() in this file are not used with fchdir, - therefore save some unnecessary work in fchdir.c. */ -#undef open -#undef close - /* Use the system functions, not the gnulib overrides in this file. */ #undef sprintf @@ -102,6 +103,48 @@ extern char * canonicalize_file_name (const char *name #if ENABLE_RELOCATABLE +#ifdef __sun + +/* Helper function, from gnulib module 'safe-read'. */ +static size_t +safe_read (int fd, void *buf, size_t count) +{ + for (;;) + { + ssize_t result = read (fd, buf, count); + + if (0 <= result || errno != EINTR) + return result; + } +} + +/* Helper function, from gnulib module 'full-read'. */ +static size_t +full_read (int fd, void *buf, size_t count) +{ + size_t total = 0; + const char *ptr = (const char *) buf; + + while (count > 0) + { + size_t n = safe_read (fd, ptr, count); + if (n == (size_t) -1) + break; + if (n == 0) + { + errno = 0; + break; + } + total += n; + ptr += n; + count -= n; + } + + return total; +} + +#endif + #if defined __linux__ || defined __CYGWIN__ /* File descriptor of the executable. (Only used to verify that we find the correct executable.) */ @@ -112,8 +155,8 @@ static int executable_fd = -1; static bool maybe_executable (const char *filename) { - /* Woe32 lacks the access() function. */ -#if !defined WIN32_NATIVE + /* The native Windows API lacks the access() function. */ +#if !defined WINDOWS_NATIVE if (access (filename, X_OK) < 0) return false; #endif @@ -143,17 +186,17 @@ maybe_executable (const char *filename) /* Determine the full pathname of the current executable, freshly allocated. Return NULL if unknown. - Guaranteed to work on Linux and Woe32. Likely to work on the other - Unixes (maybe except BeOS), under most conditions. */ + Guaranteed to work on Linux and native Windows. Likely to work on the + other Unixes (maybe except BeOS), under most conditions. */ static char * find_executable (const char *argv0) { -#if defined WIN32_NATIVE - /* Native Win32 only. +#if defined WINDOWS_NATIVE + /* Native Windows only. On Cygwin, it is better to use the Cygwin provided /proc interface, than - to use native Win32 API and cygwin_conv_to_posix_path, because it supports - longer file names - (see ). */ + to use native Windows API and cygwin_conv_to_posix_path, because it + supports longer file names + (see ). */ char location[MAX_PATH]; int length = GetModuleFileName (NULL, location, sizeof (location)); if (length < 0) @@ -162,8 +205,25 @@ find_executable (const char *argv0) /* Shouldn't happen. */ return NULL; return xstrdup (location); +#elif defined __EMX__ + PPIB ppib; + char location[CCHMAXPATH]; + + /* See http://cyberkinetica.homeunix.net/os2tk45/cp1/619_L2H_DosGetInfoBlocksSynt.html + for specification of DosGetInfoBlocks(). */ + if (DosGetInfoBlocks (NULL, &ppib)) + return NULL; + + /* See http://cyberkinetica.homeunix.net/os2tk45/cp1/1247_L2H_DosQueryModuleNameSy.html + for specification of DosQueryModuleName(). */ + if (DosQueryModuleName (ppib->pib_hmte, sizeof (location), location)) + return NULL; + + _fnslashify (location); + + return xstrdup (location); #else /* Unix */ -# ifdef __linux__ +# if defined __linux__ /* The executable is accessible as /proc//exe. In newer Linux versions, also as /proc/self/exe. Linux >= 2.1 provides a symlink to the true pathname; older Linux versions give only device and ino, @@ -188,7 +248,63 @@ find_executable (const char *argv0) } } # endif -# ifdef __CYGWIN__ +# if defined __ANDROID__ || defined __FreeBSD_kernel__ + /* On Android and GNU/kFreeBSD, the executable is accessible as + /proc//exe and /proc/self/exe. */ + { + char *link; + + link = xreadlink ("/proc/self/exe"); + if (link != NULL) + return link; + } +# endif +# if defined __FreeBSD__ || defined __DragonFly__ + /* In FreeBSD >= 5.0, the executable is accessible as /proc//file and + /proc/curproc/file. */ + { + char *link; + + link = xreadlink ("/proc/curproc/file"); + if (link != NULL) + { + if (strcmp (link, "unknown") != 0) + return link; + free (link); + } + } +# endif +# if defined __NetBSD__ + /* In NetBSD >= 4.0, the executable is accessible as /proc//exe and + /proc/curproc/exe. */ + { + char *link; + + link = xreadlink ("/proc/curproc/exe"); + if (link != NULL) + return link; + } +# endif +# if defined __sun + /* On Solaris >= 11.4, /proc//execname and /proc/self/execname contains + the name of the executable, either as an absolute file name or relative to + the current directory. */ + { + char namebuf[4096]; + int fd = open ("/proc/self/execname", O_RDONLY, 0); + if (fd >= 0) + { + size_t len = full_read (fd, namebuf, sizeof (namebuf)); + close (fd); + if (len > 0 && len < sizeof (namebuf)) + { + namebuf[len] = '\0'; + return canonicalize_file_name (namebuf); + } + } + } +# endif +# if defined __CYGWIN__ /* The executable is accessible as /proc//exe, at least in Cygwin >= 1.5. */ { @@ -202,7 +318,7 @@ find_executable (const char *argv0) } # endif # if HAVE_MACH_O_DYLD_H && HAVE__NSGETEXECUTABLEPATH - /* On MacOS X 10.2 or newer, the function + /* On Mac OS X 10.2 or newer, the function int _NSGetExecutablePath (char *buf, uint32_t *bufsize); can be used to retrieve the executable's full path. */ char location[4096];