[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
gettext patches for cygwin #3: relocation
From: |
Charles Wilson |
Subject: |
gettext patches for cygwin #3: relocation |
Date: |
Sat, 19 Nov 2005 23:51:06 -0500 |
User-agent: |
Mozilla Thunderbird 1.0.6 (Windows/20050716) |
Mostly having to do with .exe extension.
2005-11-20 Charles Wilson <address@hidden>
* build-aux/install-reloc: handle EXEEXT.
* gettext-runtime/intl/relocatable.c (DllMain): convert path
to unix style on cygwin.
(get_shared_library_fullname): rely on DLLMain to compute
shared_library_fullname.
* gettext-tools/lib/relocatable.c: ditto
* gettext-tools/lib/progreloc.c (maybe_executable): use access()
on cygwin even if WIN32 defined.
(xreadlink_proc_exename): new function to read /proc/pid/exename
(find_executable): don't use GetModuleFileName on cygwin.
Instead, use /proc/self/exe or /proc/<pid>/exename.
(set_program_name_and_installdir): take care for trailing .exe
* gettext-tools/lib/relocwrapper.c (add_dotbin): foo.exe should
become foo.bin.exe, not foo.exe.bin.
--
Chuck
diff -urN gettext-0.14.5-orig/gettext-runtime/intl/relocatable.c
gettext-0.14.5/gettext-runtime/intl/relocatable.c
--- gettext-0.14.5-orig/gettext-runtime/intl/relocatable.c 2005-05-20
16:09:45.000000000 -0400
+++ gettext-0.14.5/gettext-runtime/intl/relocatable.c 2005-11-11
00:05:57.031250000 -0500
@@ -60,6 +60,12 @@
# include <libintl.h>
#endif
+/* cygwin doesn't get these defs by default, unlike other Win32 */
+#if defined __CYGWIN__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
/* Faked cheap 'bool'. */
#undef bool
#undef false
@@ -240,6 +246,11 @@
!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
break;
#else
+ /* technically, cygwin should be treated as above. But, with 'managed'
+ mounts, cygwin can fake case-sensitivity. So, we choose to use
+ case-sensitive comparison on cygwin, even though it may infrequently
+ break things if not using managed mounts
+ */
if (*rpi != *cpi)
break;
#endif
@@ -280,7 +291,7 @@
/* Full pathname of shared library, or NULL. */
static char *shared_library_fullname;
-#if defined _WIN32 || defined __WIN32__
+#if defined _WIN32 || defined __WIN32__ || defined (__CYGWIN__)
/* Determine the full pathname of the shared library when it is loaded. */
@@ -302,7 +313,16 @@
/* Shouldn't happen. */
return FALSE;
+#if defined(__CYGWIN__)
+ {
+ static char cyglocation[MAX_PATH];
+ cygwin_conv_to_posix_path(location, cyglocation);
+ shared_library_fullname = strdup (cyglocation);
+ }
+#else
shared_library_fullname = strdup (location);
+#endif
+
}
return TRUE;
@@ -363,11 +383,11 @@
/* Return the full pathname of the current shared library.
Return NULL if unknown.
- Guaranteed to work only on Linux and Woe32. */
+ Guaranteed to work only on Linux, Cygwin, and Woe32. */
static char *
get_shared_library_fullname ()
{
-#if !(defined _WIN32 || defined __WIN32__)
+#if !(defined _WIN32 || defined __WIN32__ || defined __CYGWIN__)
static bool tried_find_shared_library_fullname;
if (!tried_find_shared_library_fullname)
{
diff -urN gettext-0.14.5-orig/gettext-tools/lib/progreloc.c
gettext-0.14.5/gettext-tools/lib/progreloc.c
--- gettext-0.14.5-orig/gettext-tools/lib/progreloc.c 2005-05-20
16:25:41.000000000 -0400
+++ gettext-0.14.5/gettext-tools/lib/progreloc.c 2005-11-11
00:53:26.546875000 -0500
@@ -91,11 +91,11 @@
static bool
maybe_executable (const char *filename)
{
-#if !defined WIN32
+#if !defined (WIN32) || defined (__CYGWIN__)
if (access (filename, X_OK) < 0)
return false;
-#ifdef __linux__
+# ifdef __linux__
if (executable_fd >= 0)
{
/* If we already have an executable_fd, check that filename points to
@@ -113,12 +113,105 @@
return false;
}
}
-#endif
+# endif
#endif
return true;
}
+/* Using /proc/<pid>/exename
+ Only on cygwin.
+
+ The first entry must be read manually as a text string, and then
+ xreadlink() can be used (in a loop) to find the final target exe.
+ (Or, better, use canonicalize_file_name instead).
+
+ returns NULL if target not found; otherwise returns the fullpath
+ of the executable in malloc'ed storage.
+*/
+static char *
+xreadlink_proc_exename(char * path)
+{
+ char* buf;
+ int fd = -1;
+ ssize_t count;
+ long int path_max;
+
+ if ((path == NULL) || (*path == '\0'))
+ return NULL;
+
+#ifdef PATH_MAX
+ path_max = PATH_MAX
+#else
+ path_max = pathconf (path, _PC_PATH_MAX);
+ if (path_max <= 0)
+ path_max = 1024;
+#endif
+
+ buf = xmalloc(path_max + 5);
+#if NO_XMALLOC
+ if (buf == NULL)
+ return NULL;
+#endif
+
+ if ((fd = open(path, O_RDONLY | O_BINARY)) == -1)
+ {
+ free(buf);
+ return NULL;
+ }
+ count = read(fd, buf, path_max + 4);
+ close(fd);
+
+ /* If count = -1, there was an error reading the file
+ If count = 0, the file was empty (!)
+ If we actually succeed in reading more than PATH_MAX characters,
+ then the contents do not represent a filename
+ In any of these cases, bail out
+ */
+ if ((count <= 0) || (count > path_max + 3))
+ {
+ free(buf);
+ return NULL;
+ }
+ buf[count] = '\0';
+
+ /* Because /proc/<pid>/exename may represent the name of a
+ symlink (to a symlink to a symlink ...) we would need
+ to loop over readlink (xreadlink, if we need to worry
+ about allocated storage). However, canonicalize_file_name()
+ handles all of that for us -- including allocated storage.
+
+ */
+ {
+ char* tbuf;
+ struct stat st;
+
+ tbuf = canonicalize_file_name (buf);
+ free(buf);
+
+ /* canonicalize_file_name doesn't care if the final component
+ of its argument exists, nor if it is a symlink to a non-
+ existant file. We do. Bail if tbuf !exist, or if
+ tbuf is symlink
+ */
+ if (tbuf == NULL)
+ return NULL;
+ if (lstat (tbuf, &st) < 0)
+ {
+ /* tbuf refers to a nonexistant file */
+ free(tbuf);
+ return NULL;
+ }
+ if (S_ISLNK (st.st_mode))
+ {
+ /* tbuf is a symlink to a nonexistant file */
+ free(tbuf);
+ return NULL;
+ }
+ return tbuf;
+ }
+}
+
/* 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
@@ -126,7 +219,7 @@
static char *
find_executable (const char *argv0)
{
-#ifdef WIN32
+#if defined (WIN32) && !defined(__CYGWIN__)
char buf[1024];
int length = GetModuleFileName (NULL, buf, sizeof (buf));
if (length < 0)
@@ -135,8 +228,45 @@
/* Shouldn't happen. */
return NULL;
return xstrdup (buf);
-#else /* Unix */
-#ifdef __linux__
+#else /* !Woe32 */
+# if defined (__CYGWIN__)
+ /* For cygwin, we could use GetModuleFileName and then translate
+ the windows-ish path to unix-ish, using cygwin's mount table.
+ Or, we can rely on cygwin-1.5.0's /proc/<pid>/ structure. We
+ choose the latter...but:
+
+ From cygwin-1.5.0 to 1.5.12, cygwin provides only /proc/<pid>/exename
+ not /proc/<pid>/exe, nor does it provide /proc/self/
+
+ As of cygwin-1.5.13 (01Mar2005), cygwin provides all of
+ /proc/<pid>/exe, /proc/<pic>/exename, and /proc/self/.
+ So, we try them in the most desirable order:
+ 1. /proc/self/exe
+ 2. /proc/self/exename
+ 3. /proc/<pid>/exe
+ 4. /proc/<pid>/exename
+ Except 2 and 3 are unnecessary, given the simultaneous introduction
+ of /proc/self support and /proc/<pid>/exe support.
+ */
+ {
+ char *link;
+
+ link = xreadlink("/proc/self/exe");
+ if (link != NULL)
+ {
+ return link;
+ }
+ else
+ {
+ char buf[6+10+9];
+ snprintf (buf, 24, "/proc/%d/exename", getpid ());
+ link = xreadlink_proc_exename (buf);
+ if (link != NULL)
+ return link;
+ }
+ }
+# else /* !cygwin */
+# if defined (__linux__)
/* The executable is accessible as /proc/<pid>/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,
@@ -160,7 +290,8 @@
executable_fd = open (buf, O_RDONLY, 0);
}
}
-#endif
+# endif /* __linux__ */
+# endif /* __CYGWIN__ */
/* 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. */
@@ -201,10 +332,10 @@
/* We have a path item at p, of length p_len.
Now concatenate the path item and argv0. */
concat_name = (char *) xmalloc (p_len + strlen (argv0) + 2);
-#ifdef NO_XMALLOC
+# ifdef NO_XMALLOC
if (concat_name == NULL)
return NULL;
-#endif
+# endif
if (p_len == 0)
/* An empty PATH element designates the current directory. */
strcpy (concat_name, argv0);
@@ -260,11 +391,12 @@
{
const char *argv0_stripped = argv0;
- /* Relocatable programs are renamed to .bin by install-reloc. Remove
- this suffix here. */
+ /* Relocatable programs are renamed to .bin (or .bin.exe) 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)
+ /* foo.bin --> foo */
{
char *shorter = (char *) xmalloc (argv0_len - 4 + 1);
#ifdef NO_XMALLOC
@@ -276,6 +408,20 @@
argv0_stripped = shorter;
}
}
+ else if (argv0_len > 8 && memcmp (argv0 + argv0_len - 8, ".bin", 4) == 0)
+ /* foo.bin.exe --> foo.exe */
+ {
+ char *shorter = (char *) xmalloc (argv0_len - 4 + 1);
+#ifdef NO_XMALLOC
+ if (shorter != NULL)
+#endif
+ {
+ memcpy (shorter, argv0, argv0_len - 8);
+ memcpy (shorter + argv0_len - 8, ".exe", 4);
+ shorter[argv0_len - 4] = '\0';
+ argv0_stripped = shorter;
+ }
+ }
}
set_program_name (argv0_stripped);
diff -urN gettext-0.14.5-orig/gettext-tools/lib/relocatable.c
gettext-0.14.5/gettext-tools/lib/relocatable.c
--- gettext-0.14.5-orig/gettext-tools/lib/relocatable.c 2005-05-20
16:26:17.000000000 -0400
+++ gettext-0.14.5/gettext-tools/lib/relocatable.c 2005-11-11
00:53:52.250000000 -0500
@@ -60,6 +60,12 @@
# include <libintl.h>
#endif
+/* cygwin doesn't get these defs by default, unlike other Win32 */
+#if defined __CYGWIN__
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+
/* Faked cheap 'bool'. */
#undef bool
#undef false
@@ -240,6 +246,11 @@
!= (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi))
break;
#else
+ /* technically, cygwin should be treated as above. But, with 'managed'
+ mounts, cygwin can fake case-sensitivity. So, we choose to use
+ case-sensitive comparison on cygwin, even though it may infrequently
+ break things if not using managed mounts
+ */
if (*rpi != *cpi)
break;
#endif
@@ -280,7 +291,7 @@
/* Full pathname of shared library, or NULL. */
static char *shared_library_fullname;
-#if defined _WIN32 || defined __WIN32__
+#if defined _WIN32 || defined __WIN32__ || defined (__CYGWIN__)
/* Determine the full pathname of the shared library when it is loaded. */
@@ -302,7 +313,16 @@
/* Shouldn't happen. */
return FALSE;
+#if defined(__CYGWIN__)
+ {
+ static char cyglocation[MAX_PATH];
+ cygwin_conv_to_posix_path(location, cyglocation);
+ shared_library_fullname = strdup (cyglocation);
+ }
+#else
shared_library_fullname = strdup (location);
+#endif
+
}
return TRUE;
@@ -363,11 +383,11 @@
/* Return the full pathname of the current shared library.
Return NULL if unknown.
- Guaranteed to work only on Linux and Woe32. */
+ Guaranteed to work only on Linux, Cygwin, and Woe32. */
static char *
get_shared_library_fullname ()
{
-#if !(defined _WIN32 || defined __WIN32__)
+#if !(defined _WIN32 || defined __WIN32__ || defined __CYGWIN__)
static bool tried_find_shared_library_fullname;
if (!tried_find_shared_library_fullname)
{
diff -urN gettext-0.14.5-orig/gettext-tools/lib/relocwrapper.c
gettext-0.14.5/gettext-tools/lib/relocwrapper.c
--- gettext-0.14.5-orig/gettext-tools/lib/relocwrapper.c 2005-05-20
16:26:25.000000000 -0400
+++ gettext-0.14.5/gettext-tools/lib/relocwrapper.c 2005-11-11
00:55:46.359375000 -0500
@@ -58,17 +58,30 @@
#include "relocatable.h"
#include "setenv.h"
-/* Return a copy of the filename, with an extra ".bin" at the end. */
+/* Return a copy of the filename, with an extra ".bin" at the end.
+ If filename ends with .exe, then ".bin" is inserted between
+ the .exe and the rest of the filename */
static char *
add_dotbin (const char *filename)
{
size_t filename_len = strlen (filename);
char *result = (char *) malloc (filename_len + 4 + 1);
-
+
if (result != NULL)
{
- memcpy (result, filename, filename_len);
- memcpy (result + filename_len, ".bin", 4 + 1);
+ if ((filename_len > 4) &&
+ ((strncmp(filename + filename_len - 4, ".exe", 4) == 0) ||
+ (strncmp(filename + filename_len - 4, ".EXE", 4) == 0)))
+ {
+ memcpy (result, filename, filename_len - 4);
+ memcpy (result + filename_len - 4, ".bin", 4);
+ memcpy (result + filename_len, filename + filename_len - 4, 4 + 1);
+ }
+ else
+ {
+ memcpy (result, filename, filename_len);
+ memcpy (result + filename_len, ".bin", 4 + 1);
+ }
return result;
}
else
diff -urN -x .build -x .inst -x .sinst -x '*~'
gettext-0.14.5-orig/build-aux/install-reloc
gettext-0.14.5/build-aux/install-reloc
--- gettext-0.14.5-orig/build-aux/install-reloc 2005-05-20 16:03:20.000000000
-0400
+++ gettext-0.14.5/build-aux/install-reloc 2005-11-11 18:05:17.906250000
-0500
@@ -108,12 +108,19 @@
# wrapper.
test -n "$libdirs" || exit 0
+# deduce EXEEXT. if $destprog endswith .exe, fine...
+EXEEXT=
+p1=`echo ${destprog}|sed -e 's/\.exe$//'`
+test "${p1}" == "${destprog}" || EXEEXT=.exe
+# otherwise, check for file existence
+test -f "${p1}.exe" && EXEEXT=.exe
+
# Compile wrapper.
installdir=`echo "$destprog" | sed -e 's,/[^/]*$,,'`
-func_verbose $compile_command -I"$builddir" -I"$srcdir" -I"$config_h_dir"
-DHAVE_CONFIG_H -DNO_XMALLOC -D"INSTALLPREFIX=\"$prefix\""
-D"INSTALLDIR=\"$installdir\"" -D"LIBPATHVAR=\"$library_path_var\""
-D"LIBDIRS=$libdirs" "$srcdir"/relocwrapper.c "$srcdir"/progname.c
"$srcdir"/progreloc.c "$srcdir"/xreadlink.c "$srcdir"/readlink.c
"$srcdir"/canonicalize.c "$srcdir"/allocsa.c "$srcdir"/relocatable.c
"$srcdir"/setenv.c "$srcdir"/strerror.c -o $destprog.wrapper || exit $?
+func_verbose $compile_command -I"$builddir" -I"$srcdir" -I"$config_h_dir"
-DHAVE_CONFIG_H -DNO_XMALLOC -D"INSTALLPREFIX=\"$prefix\""
-D"INSTALLDIR=\"$installdir\"" -D"LIBPATHVAR=\"$library_path_var\""
-D"LIBDIRS=$libdirs" "$srcdir"/relocwrapper.c "$srcdir"/progname.c
"$srcdir"/progreloc.c "$srcdir"/xreadlink.c "$srcdir"/readlink.c
"$srcdir"/canonicalize.c "$srcdir"/allocsa.c "$srcdir"/relocatable.c
"$srcdir"/setenv.c "$srcdir"/strerror.c -o ${p1}.wrapper${EXEEXT} || exit $?
# Rename $destprog.wrapper -> $destprog -> $destprog.bin.
-ln -f $destprog $destprog.bin || exit 1
-mv $destprog.wrapper $destprog || exit 1
+ln -f ${p1}${EXEEXT} ${p1}.bin${EXEEXT} || exit 1
+mv ${p1}.wrapper${EXEEXT} ${p1}${EXEEXT} || exit 1
exit 0