--- embedaddon/libiconv/lib/relocatable.c 2012/05/29 09:29:43 1.1.1.2 +++ embedaddon/libiconv/lib/relocatable.c 2021/03/17 13:38:46 1.1.1.3 @@ -1,5 +1,5 @@ /* Provide relocatable packages. - Copyright (C) 2003-2006, 2008-2011 Free Software Foundation, Inc. + Copyright (C) 2003-2006, 2008-2018 Free Software Foundation, Inc. Written by Bruno Haible , 2003. This program is free software; you can redistribute it and/or modify it @@ -12,10 +12,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. - You should have received a copy of the GNU Library General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ + You should have received a copy of the GNU Library General Public License + along with this program; if not, see . */ /* Tell glibc's to provide a prototype for getline(). @@ -44,11 +42,19 @@ # include "xalloc.h" #endif -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ +#if defined _WIN32 && !defined __CYGWIN__ # define WIN32_LEAN_AND_MEAN # include #endif +#ifdef __EMX__ +# define INCL_DOS +# include + +# define strcmp stricmp +# define strncmp strnicmp +#endif + #if DEPENDS_ON_LIBCHARSET # include #endif @@ -71,8 +77,8 @@ 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')) \ @@ -87,6 +93,19 @@ # define FILE_SYSTEM_PREFIX_LEN(P) 0 #endif +/* Whether to enable the more costly support for relocatable libraries. + It allows libraries to be have been installed with a different original + prefix than the program. But it is quite costly, especially on Cygwin + platforms, see below. Therefore we enable it by default only on native + Windows platforms. */ +#ifndef ENABLE_COSTLY_RELOCATABLE +# if defined _WIN32 && !defined __CYGWIN__ +# define ENABLE_COSTLY_RELOCATABLE 1 +# else +# define ENABLE_COSTLY_RELOCATABLE 0 +# endif +#endif + /* Original installation prefix. */ static char *orig_prefix; static size_t orig_prefix_len; @@ -156,7 +175,7 @@ set_relocation_prefix (const char *orig_prefix_arg, co #endif } -#if !defined IN_LIBRARY || (defined PIC && defined INSTALLDIR) +#if !defined IN_LIBRARY || (defined PIC && defined INSTALLDIR && ENABLE_COSTLY_RELOCATABLE) /* Convenience function: Computes the current installation prefix, based on the original @@ -237,8 +256,8 @@ compute_curr_prefix (const char *orig_installprefix, /* Do case-insensitive comparison if the file system is always or often case-insensitive. It's better to accept the comparison if the difference is only in case, rather than to fail. */ -#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ - /* Win32, Cygwin, OS/2, DOS - case insignificant file system */ +#if defined _WIN32 || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Native Windows, Cygwin, OS/2, DOS - case insignificant file system */ if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi) != (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi)) break; @@ -286,17 +305,17 @@ compute_curr_prefix (const char *orig_installprefix, #endif /* !IN_LIBRARY || PIC */ -#if defined PIC && defined INSTALLDIR +#if defined PIC && defined INSTALLDIR && ENABLE_COSTLY_RELOCATABLE /* Full pathname of shared library, or NULL. */ static char *shared_library_fullname; -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ -/* Native Win32 only. +#if defined _WIN32 && !defined __CYGWIN__ +/* 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 ). */ /* Determine the full pathname of the shared library when it is loaded. */ @@ -324,6 +343,45 @@ DllMain (HINSTANCE module_handle, DWORD event, LPVOID return TRUE; } +#elif defined __EMX__ + +extern int _CRT_init (void); +extern void _CRT_term (void); +extern void __ctordtorInit (void); +extern void __ctordtorTerm (void); + +unsigned long _System +_DLL_InitTerm (unsigned long hModule, unsigned long ulFlag) +{ + static char location[CCHMAXPATH]; + + switch (ulFlag) + { + case 0: + if (_CRT_init () == -1) + return 0; + + __ctordtorInit(); + + /* See http://cyberkinetica.homeunix.net/os2tk45/cp1/1247_L2H_DosQueryModuleNameSy.html + for specification of DosQueryModuleName(). */ + if (DosQueryModuleName (hModule, sizeof (location), location)) + return 0; + + _fnslashify (location); + shared_library_fullname = strdup (location); + break; + + case 1: + __ctordtorTerm(); + + _CRT_term (); + break; + } + + return 1; +} + #else /* Unix */ static void @@ -332,7 +390,9 @@ find_shared_library_fullname () #if (defined __linux__ && (__GLIBC__ >= 2 || defined __UCLIBC__)) || defined __CYGWIN__ /* Linux has /proc/self/maps. glibc 2 and uClibc have the getline() function. - Cygwin >= 1.5 has /proc/self/maps and the getline() function too. */ + Cygwin >= 1.5 has /proc/self/maps and the getline() function too. + But it is costly: ca. 0.3 ms on Linux, 3 ms on Cygwin 1.5, and 5 ms on + Cygwin 1.7. */ FILE *fp; /* Open the current process' maps file. It describes one VMA per line. */ @@ -377,15 +437,15 @@ find_shared_library_fullname () #endif } -#endif /* WIN32 / Unix */ +#endif /* Native Windows / EMX / Unix */ /* Return the full pathname of the current shared library. Return NULL if unknown. - Guaranteed to work only on Linux, Cygwin and Woe32. */ + Guaranteed to work only on Linux, EMX, Cygwin, and native Windows. */ static char * get_shared_library_fullname () { -#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) +#if !(defined _WIN32 && !defined __CYGWIN__) && !defined __EMX__ static bool tried_find_shared_library_fullname; if (!tried_find_shared_library_fullname) { @@ -405,7 +465,7 @@ get_shared_library_fullname () const char * relocate (const char *pathname) { -#if defined PIC && defined INSTALLDIR +#if defined PIC && defined INSTALLDIR && ENABLE_COSTLY_RELOCATABLE static int initialized; /* Initialization code for a shared library. */ @@ -476,8 +536,53 @@ relocate (const char *pathname) } } } + +#ifdef __EMX__ +# ifdef __KLIBC__ +# undef strncmp + + if (strncmp (pathname, "/@unixroot", 10) == 0 + && (pathname[10] == '\0' || ISSLASH (pathname[10]))) + { + /* kLIBC itself processes /@unixroot prefix */ + return pathname; + } + else +# endif + if (ISSLASH (pathname[0])) + { + const char *unixroot = getenv ("UNIXROOT"); + + if (unixroot && HAS_DEVICE (unixroot) && unixroot[2] == '\0') + { + char *result = (char *) xmalloc (2 + strlen (pathname) + 1); +#ifdef NO_XMALLOC + if (result != NULL) +#endif + { + memcpy (result, unixroot, 2); + strcpy (result + 2, pathname); + return result; + } + } + } +#endif + /* Nothing to relocate. */ return pathname; +} + +/* Returns the pathname, relocated according to the current installation + directory. + This function sets *ALLOCATEDP to the allocated memory, or to NULL if + no memory allocation occurs. So that, after you're done with the return + value, to reclaim allocated memory, you can do: free (*ALLOCATEDP). */ +const char * +relocate2 (const char *pathname, char **allocatedp) +{ + const char *result = relocate (pathname); + *allocatedp = (result != pathname ? (char *) result : NULL); + return result; } #endif