Merge from gettext. 2006-05-17 Bruno Haible <[EMAIL PROTECTED]>
Cygwin portability. * progreloc.c (WIN32_NATIVE): Renamed from WIN32. 2006-04-30 Bruno Haible <[EMAIL PROTECTED]> * progreloc.c: Include <mach-o/dyld.h> if available. (find_executable): Use _NSGetExecutablePath when possible. 2006-05-06 Charles Wilson <[EMAIL PROTECTED]> * progreloc.c (maybe_executable) [CYGWIN]: Use the access() function. 2005-12-29 Bruno Haible <[EMAIL PROTECTED]> * progreloc.c (set_program_name_and_installdir): Fix compilation error. 2005-12-04 Bruno Haible <[EMAIL PROTECTED]> Cygwin portability. * progreloc.c: Include <windows.h> also on Cygwin. (find_executable): Add support for Cygwin. (set_program_name_and_installdir): Handle also platforms with nonempty EXEEXT. *** progreloc.c 19 Sep 2005 17:28:14 -0000 1.8 --- progreloc.c 22 Jul 2006 16:14:06 -0000 *************** *** 1,5 **** /* Provide relocatable programs. ! Copyright (C) 2003-2004 Free Software Foundation, Inc. Written by Bruno Haible <[EMAIL PROTECTED]>, 2003. This program is free software; you can redistribute it and/or modify --- 1,5 ---- /* Provide relocatable programs. ! Copyright (C) 2003-2006 Free Software Foundation, Inc. Written by Bruno Haible <[EMAIL PROTECTED]>, 2003. This program is free software; you can redistribute it and/or modify *************** *** 34,45 **** #endif #include <sys/stat.h> #if defined _WIN32 || defined __WIN32__ ! # undef WIN32 /* avoid warning on mingw32 */ ! # define WIN32 #endif ! #ifdef WIN32 # define WIN32_LEAN_AND_MEAN # include <windows.h> #endif --- 34,49 ---- #endif #include <sys/stat.h> + /* Get declaration of _NSGetExecutablePath on MacOS X 10.2 or newer. */ + #if HAVE_MACH_O_DYLD_H + # include <mach-o/dyld.h> + #endif + #if defined _WIN32 || defined __WIN32__ ! # define WIN32_NATIVE #endif ! #if defined WIN32_NATIVE || defined __CYGWIN__ # define WIN32_LEAN_AND_MEAN # include <windows.h> #endif *************** *** 90,96 **** static bool maybe_executable (const char *filename) { ! #if !defined WIN32 if (access (filename, X_OK) < 0) return false; --- 94,101 ---- static bool maybe_executable (const char *filename) { ! /* Woe32 lacks the access() function, but Cygwin doesn't. */ ! #if !(defined WIN32_NATIVE && !defined __CYGWIN__) if (access (filename, X_OK) < 0) return false; *************** *** 125,140 **** static char * find_executable (const char *argv0) { ! #ifdef WIN32 ! char buf[1024]; ! int length = GetModuleFileName (NULL, buf, sizeof (buf)); if (length < 0) return NULL; ! if (!IS_PATH_WITH_DIR (buf)) /* Shouldn't happen. */ return NULL; ! return xstrdup (buf); ! #else /* Unix */ #ifdef __linux__ /* The executable is accessible as /proc/<pid>/exe. In newer Linux versions, also as /proc/self/exe. Linux >= 2.1 provides a symlink --- 130,168 ---- static char * find_executable (const char *argv0) { ! #if defined WIN32_NATIVE || defined __CYGWIN__ ! char location[MAX_PATH]; ! int length = GetModuleFileName (NULL, location, sizeof (location)); if (length < 0) return NULL; ! if (!IS_PATH_WITH_DIR (location)) /* Shouldn't happen. */ return NULL; ! { ! #if defined __CYGWIN__ ! /* cygwin-1.5.13 (2005-03-01) or newer would also allow a Linux-like ! implementation: readlink of "/proc/self/exe". But using the ! result of the Win32 system call is simpler and is consistent with the ! code in relocatable.c. */ ! /* On Cygwin, we need to convert paths coming from Win32 system calls ! to the Unix-like slashified notation. */ ! static char location_as_posix_path[2 * MAX_PATH]; ! /* There's no error return defined for cygwin_conv_to_posix_path. ! See cygwin-api/func-cygwin-conv-to-posix-path.html. ! Does it overflow the buffer of expected size MAX_PATH or does it ! truncate the path? I don't know. Let's catch both. */ ! cygwin_conv_to_posix_path (location, location_as_posix_path); ! location_as_posix_path[MAX_PATH - 1] = '\0'; ! if (strlen (location_as_posix_path) >= MAX_PATH - 1) ! /* A sign of buffer overflow or path truncation. */ ! return NULL; ! /* Call canonicalize_file_name, because Cygwin supports symbolic links. */ ! return canonicalize_file_name (location_as_posix_path); ! #else ! return xstrdup (location); ! #endif ! } ! #else /* Unix && !Cygwin */ #ifdef __linux__ /* The executable is accessible as /proc/<pid>/exe. In newer Linux versions, also as /proc/self/exe. Linux >= 2.1 provides a symlink *************** *** 160,165 **** --- 188,203 ---- } } #endif + #if HAVE_MACH_O_DYLD_H && HAVE__NSGETEXECUTABLEPATH + /* On MacOS X 10.2 or newer, the function + int _NSGetExecutablePath (char *buf, unsigned long *bufsize); + can be used to retrieve the executable's full path. */ + char location[4096]; + unsigned long length = sizeof (location); + if (_NSGetExecutablePath (location, &length) == 0 + && location[0] == '/') + return canonicalize_file_name (location); + #endif /* Guess the executable's full path. We assume the executable has been called via execlp() or execvp() with properly set up argv[0]. The login(1) convention to add a '-' prefix to argv[0] is not supported. */ *************** *** 259,279 **** { const char *argv0_stripped = argv0; ! /* Relocatable programs are renamed to .bin by install-reloc. Remove ! this suffix here. */ { size_t argv0_len = strlen (argv0); ! if (argv0_len > 4 && memcmp (argv0 + argv0_len - 4, ".bin", 4) == 0) ! { ! char *shorter = (char *) xmalloc (argv0_len - 4 + 1); #ifdef NO_XMALLOC ! if (shorter != NULL) #endif ! { ! memcpy (shorter, argv0, argv0_len - 4); ! shorter[argv0_len - 4] = '\0'; ! argv0_stripped = shorter; } } } --- 297,346 ---- { const char *argv0_stripped = argv0; ! /* Relocatable programs are renamed to .bin by install-reloc. Or, more ! generally, their suffix is changed from $exeext to .bin$exeext. ! Remove the ".bin" here. */ { size_t argv0_len = strlen (argv0); ! const size_t exeext_len = sizeof (EXEEXT) - sizeof (""); ! if (argv0_len > 4 + exeext_len) ! if (memcmp (argv0 + argv0_len - exeext_len - 4, ".bin", 4) == 0) ! { ! if (sizeof (EXEEXT) > sizeof ("")) ! { ! /* Compare using an inlined copy of c_strncasecmp(), because ! the filenames may have undergone a case conversion since ! they were packaged. In other words, EXEEXT may be ".exe" ! on one system and ".EXE" on another. */ ! static const char exeext[] = EXEEXT; ! const char *s1 = argv0 + argv0_len - exeext_len; ! const char *s2 = exeext; ! for (; *s1 != '\0'; s1++, s2++) ! { ! unsigned char c1 = *s1; ! unsigned char c2 = *s2; ! if ((c1 >= 'A' && c1 <= 'Z' ? c1 - 'A' + 'a' : c1) ! != (c2 >= 'A' && c2 <= 'Z' ? c2 - 'A' + 'a' : c2)) ! goto done_stripping; ! } ! } ! /* Remove ".bin" before EXEEXT or its equivalent. */ ! { ! char *shorter = (char *) xmalloc (argv0_len - 4 + 1); #ifdef NO_XMALLOC ! if (shorter != NULL) #endif ! { ! memcpy (shorter, argv0, argv0_len - exeext_len - 4); ! if (sizeof (EXEEXT) > sizeof ("")) ! memcpy (shorter + argv0_len - exeext_len - 4, ! argv0 + argv0_len - exeext_len - 4, ! exeext_len); ! shorter[argv0_len - 4] = '\0'; ! argv0_stripped = shorter; ! } } + done_stripping: ; } }