From: Bruno Haible Date: Mon, 7 Apr 2003 10:53:18 +0000 (+0000) Subject: Move the ENABLE_RELOCATABLE dependent parts to an extra file progreloc.c. X-Git-Tag: v0.12~89 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f11e4c380e255dbec5bb920db1bf6138a342d902;p=thirdparty%2Fgettext.git Move the ENABLE_RELOCATABLE dependent parts to an extra file progreloc.c. --- diff --git a/ChangeLog b/ChangeLog index 49094648b..8173dd72e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2003-04-06 Bruno Haible + + * config/install-reloc: Also compile progreloc.c. + 2003-04-05 Bruno Haible * config/install-reloc: Don't define NO_LIBRARIES. diff --git a/config/install-reloc b/config/install-reloc index 030bee677..8dea6c3de 100755 --- a/config/install-reloc +++ b/config/install-reloc @@ -110,7 +110,7 @@ test -n "$libdirs" || exit 0 # 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"/xreadlink.c "$srcdir"/canonicalize.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"/canonicalize.c "$srcdir"/relocatable.c "$srcdir"/setenv.c "$srcdir"/strerror.c -o $destprog.wrapper || exit $? # Rename $destprog.wrapper -> $destprog -> $destprog.bin. ln -f $destprog $destprog.bin || exit 1 diff --git a/gettext-tools/lib/ChangeLog b/gettext-tools/lib/ChangeLog index fba2b1ed7..0f98a8c85 100644 --- a/gettext-tools/lib/ChangeLog +++ b/gettext-tools/lib/ChangeLog @@ -1,3 +1,13 @@ +2003-04-06 Bruno Haible + + * progname.c: Move out all methods depending on ENABLE_RELOCATABLE... + * progreloc.c: ... to here. New file. + * Makefile.am (libgettextlib_la_SOURCES): Add progreloc.c. + * Makefile.msvc (OBJECTS): Add progreloc.obj. + (progreloc.obj): New rule. + * Makefile.vms (OBJECTS): Add progreloc.obj. + (progreloc.obj): New rule. + 2003-04-05 Bruno Haible * relocatable.c: Rely on DEPENDS_ON_LIBCHARSET, DEPENDS_ON_LIBICONV, diff --git a/gettext-tools/lib/Makefile.am b/gettext-tools/lib/Makefile.am index 9732d1145..2ebb146e4 100644 --- a/gettext-tools/lib/Makefile.am +++ b/gettext-tools/lib/Makefile.am @@ -56,7 +56,7 @@ libgettextlib_la_SOURCES = \ pathmax.h \ pathname.h concatpath.c \ pipe.h pipe-bidi.c pipe-in.c pipe-out.c w32spawn.h \ - progname.h progname.c \ + progname.h progname.c progreloc.c \ safe-read.h safe-read.c \ safe-write.h safe-write.c \ sh-quote.h sh-quote.c \ diff --git a/gettext-tools/lib/Makefile.msvc b/gettext-tools/lib/Makefile.msvc index 4e25206cb..7f3cdf0cb 100644 --- a/gettext-tools/lib/Makefile.msvc +++ b/gettext-tools/lib/Makefile.msvc @@ -99,7 +99,7 @@ OBJECTS = \ obstack.obj \ concatpath.obj \ pipe-bidi.obj pipe-in.obj pipe-out.obj \ - progname.obj \ + progname.obj progreloc.obj \ safe-read.obj \ safe-write.obj \ sh-quote.obj \ @@ -203,6 +203,9 @@ pipe-out.obj : pipe-out.c progname.obj : progname.c $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c progname.c +progreloc.obj : progreloc.c + $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c progreloc.c + safe-read.obj : safe-read.c $(CC) $(INCLUDES) $(CFLAGS) $(PICFLAGS) -c safe-read.c diff --git a/gettext-tools/lib/Makefile.vms b/gettext-tools/lib/Makefile.vms index 0503ac0ea..fdd6f96b0 100644 --- a/gettext-tools/lib/Makefile.vms +++ b/gettext-tools/lib/Makefile.vms @@ -54,7 +54,7 @@ OBJECTS = \ obstack.obj, \ concatpath.obj, \ pipe-bidi.obj, pipe-in.obj, pipe-out.obj, \ - progname.obj, \ + progname.obj, progreloc.obj, \ relocatable.obj, \ safe-read.obj, \ safe-write.obj, \ @@ -154,6 +154,9 @@ pipe-out.obj : pipe-out.c progname.obj : progname.c $(CC) $(INCLUDES) $(CFLAGS) progname.c +progreloc.obj : progreloc.c + $(CC) $(INCLUDES) $(CFLAGS) progreloc.c + relocatable.obj : relocatable.c $(CC) $(INCLUDES) $(CFLAGS) relocatable.c diff --git a/gettext-tools/lib/progname.c b/gettext-tools/lib/progname.c index 7b9913262..452f3949b 100644 --- a/gettext-tools/lib/progname.c +++ b/gettext-tools/lib/progname.c @@ -24,55 +24,8 @@ /* Specification. */ #include "progname.h" -#include #include -#include #include -#include -#if HAVE_UNISTD_H -# include -#endif -#include - -#if defined _WIN32 || defined __WIN32__ -# undef WIN32 /* avoid warning on mingw32 */ -# define WIN32 -#endif - -#ifdef WIN32 -# define WIN32_LEAN_AND_MEAN -# include -#endif - -#include "xreadlink.h" -#include "canonicalize.h" -#include "relocatable.h" - -#ifdef NO_XMALLOC -# define xmalloc malloc -#else -# include "xmalloc.h" -#endif - -/* Pathname support. - 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 __EMX__ || defined __DJGPP__ - /* Win32, OS/2, DOS */ -# define ISSLASH(C) ((C) == '/' || (C) == '\\') -# define HAS_DEVICE(P) \ - ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ - && (P)[1] == ':') -# define IS_PATH_WITH_DIR(P) \ - (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) -# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) -#else - /* Unix */ -# define ISSLASH(C) ((C) == '/') -# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) -# define FILESYSTEM_PREFIX_LEN(P) 0 -#endif #undef set_program_name @@ -104,221 +57,6 @@ set_program_name (const char *argv0) } -#if ENABLE_RELOCATABLE - -#ifdef __linux__ -/* File descriptor of the executable. - (Only used to verify that we find the correct executable.) */ -static int executable_fd = -1; -#endif - -/* Tests whether a given pathname may belong to the executable. */ -static bool -maybe_executable (const char *filename) -{ -#if !defined WIN32 - if (access (filename, X_OK) < 0) - return false; - -#ifdef __linux__ - if (executable_fd >= 0) - { - /* If we already have an executable_fd, check that filename points to - the same inode. */ - struct stat statexe; - struct stat statfile; - - if (fstat (executable_fd, &statexe) >= 0) - { - if (stat (filename, &statfile) < 0) - return false; - if (!(statfile.st_dev - && statfile.st_dev == statexe.st_dev - && statfile.st_ino == statexe.st_ino)) - return false; - } - } -#endif -#endif - - return true; -} - -/* 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. */ -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//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, - enclosed in brackets, which we cannot use here. */ - { - char *link; - - link = xreadlink ("/proc/self/exe"); - if (link != NULL && link[0] != '[') - return link; - if (executable_fd < 0) - executable_fd = open ("/proc/self/exe", O_RDONLY, 0); - - { - char buf[6+10+5]; - sprintf (buf, "/proc/%d/exe", getpid ()); - link = xreadlink (buf); - if (link != NULL && link[0] != '[') - return link; - if (executable_fd < 0) - executable_fd = open (buf, O_RDONLY, 0); - } - } -#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. */ - { - bool has_slash = false; - { - const char *p; - for (p = argv0; *p; p++) - if (*p == '/') - { - has_slash = true; - break; - } - } - if (!has_slash) - { - /* exec searches paths without slashes in the directory list given - by $PATH. */ - const char *path = getenv ("PATH"); - - if (path != NULL) - { - const char *p; - const char *p_next; - - for (p = path; *p; p = p_next) - { - const char *q; - size_t p_len; - char *concat_name; - - for (q = p; *q; q++) - if (*q == ':') - break; - p_len = q - p; - p_next = (*q == '\0' ? q : q + 1); - - /* 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 - if (concat_name == NULL) - return NULL; -#endif - if (p_len == 0) - /* An empty PATH element designates the current directory. */ - strcpy (concat_name, argv0); - else - { - memcpy (concat_name, p, p_len); - concat_name[p_len] = '/'; - strcpy (concat_name + p_len + 1, argv0); - } - if (maybe_executable (concat_name)) - return canonicalize_file_name (concat_name); - free (concat_name); - } - } - /* Not found in the PATH, assume the current directory. */ - } - /* exec treats paths containing slashes as relative to the current - directory. */ - if (maybe_executable (argv0)) - return canonicalize_file_name (argv0); - } - /* No way to find the executable. */ - return NULL; -#endif -} - -/* Full pathname of executable, or NULL. */ -static char *executable_fullname; - -static void -prepare_relocate (const char *orig_installprefix, const char *orig_installdir, - const char *argv0) -{ - const char *curr_prefix; - - /* Determine the full pathname of the current executable. */ - executable_fullname = find_executable (argv0); - - /* Determine the current installation prefix from it. */ - curr_prefix = compute_curr_prefix (orig_installprefix, orig_installdir, - executable_fullname); - if (curr_prefix != NULL) - /* Now pass this prefix to all copies of the relocate.c source file. */ - set_relocation_prefix (orig_installprefix, curr_prefix); -} - -/* Set program_name, based on argv[0], and original installation prefix and - directory, for relocatability. */ -void -set_program_name_and_installdir (const char *argv0, - const char *orig_installprefix, - const char *orig_installdir) -{ - 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; - } - } - } - - set_program_name (argv0_stripped); - - prepare_relocate (orig_installprefix, orig_installdir, argv0); -} - -/* Return the full pathname of the current executable, based on the earlier - call to set_program_name_and_installdir. Return NULL if unknown. */ -char * -get_full_program_name () -{ - return executable_fullname; -} - -#endif - - /* Indicates whether errors and warnings get prefixed with program_name. Default is true. */ bool error_with_progname = true; diff --git a/gettext-tools/lib/progreloc.c b/gettext-tools/lib/progreloc.c new file mode 100644 index 000000000..cda55a76e --- /dev/null +++ b/gettext-tools/lib/progreloc.c @@ -0,0 +1,293 @@ +/* Provide relocatable programs. + Copyright (C) 2003 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +/* Specification. */ +#include "progname.h" + +#include +#include +#include +#include +#include +#if HAVE_UNISTD_H +# include +#endif +#include + +#if defined _WIN32 || defined __WIN32__ +# undef WIN32 /* avoid warning on mingw32 */ +# define WIN32 +#endif + +#ifdef WIN32 +# define WIN32_LEAN_AND_MEAN +# include +#endif + +#include "xreadlink.h" +#include "canonicalize.h" +#include "relocatable.h" + +#ifdef NO_XMALLOC +# define xmalloc malloc +#else +# include "xmalloc.h" +#endif + +/* Pathname support. + 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 __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_PATH_WITH_DIR(P) \ + (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) +# define FILESYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) +# define FILESYSTEM_PREFIX_LEN(P) 0 +#endif + +#undef set_program_name + + +#if ENABLE_RELOCATABLE + +#ifdef __linux__ +/* File descriptor of the executable. + (Only used to verify that we find the correct executable.) */ +static int executable_fd = -1; +#endif + +/* Tests whether a given pathname may belong to the executable. */ +static bool +maybe_executable (const char *filename) +{ +#if !defined WIN32 + if (access (filename, X_OK) < 0) + return false; + +#ifdef __linux__ + if (executable_fd >= 0) + { + /* If we already have an executable_fd, check that filename points to + the same inode. */ + struct stat statexe; + struct stat statfile; + + if (fstat (executable_fd, &statexe) >= 0) + { + if (stat (filename, &statfile) < 0) + return false; + if (!(statfile.st_dev + && statfile.st_dev == statexe.st_dev + && statfile.st_ino == statexe.st_ino)) + return false; + } + } +#endif +#endif + + return true; +} + +/* 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. */ +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//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, + enclosed in brackets, which we cannot use here. */ + { + char *link; + + link = xreadlink ("/proc/self/exe"); + if (link != NULL && link[0] != '[') + return link; + if (executable_fd < 0) + executable_fd = open ("/proc/self/exe", O_RDONLY, 0); + + { + char buf[6+10+5]; + sprintf (buf, "/proc/%d/exe", getpid ()); + link = xreadlink (buf); + if (link != NULL && link[0] != '[') + return link; + if (executable_fd < 0) + executable_fd = open (buf, O_RDONLY, 0); + } + } +#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. */ + { + bool has_slash = false; + { + const char *p; + for (p = argv0; *p; p++) + if (*p == '/') + { + has_slash = true; + break; + } + } + if (!has_slash) + { + /* exec searches paths without slashes in the directory list given + by $PATH. */ + const char *path = getenv ("PATH"); + + if (path != NULL) + { + const char *p; + const char *p_next; + + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + char *concat_name; + + for (q = p; *q; q++) + if (*q == ':') + break; + p_len = q - p; + p_next = (*q == '\0' ? q : q + 1); + + /* 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 + if (concat_name == NULL) + return NULL; +#endif + if (p_len == 0) + /* An empty PATH element designates the current directory. */ + strcpy (concat_name, argv0); + else + { + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, argv0); + } + if (maybe_executable (concat_name)) + return canonicalize_file_name (concat_name); + free (concat_name); + } + } + /* Not found in the PATH, assume the current directory. */ + } + /* exec treats paths containing slashes as relative to the current + directory. */ + if (maybe_executable (argv0)) + return canonicalize_file_name (argv0); + } + /* No way to find the executable. */ + return NULL; +#endif +} + +/* Full pathname of executable, or NULL. */ +static char *executable_fullname; + +static void +prepare_relocate (const char *orig_installprefix, const char *orig_installdir, + const char *argv0) +{ + const char *curr_prefix; + + /* Determine the full pathname of the current executable. */ + executable_fullname = find_executable (argv0); + + /* Determine the current installation prefix from it. */ + curr_prefix = compute_curr_prefix (orig_installprefix, orig_installdir, + executable_fullname); + if (curr_prefix != NULL) + /* Now pass this prefix to all copies of the relocate.c source file. */ + set_relocation_prefix (orig_installprefix, curr_prefix); +} + +/* Set program_name, based on argv[0], and original installation prefix and + directory, for relocatability. */ +void +set_program_name_and_installdir (const char *argv0, + const char *orig_installprefix, + const char *orig_installdir) +{ + 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; + } + } + } + + set_program_name (argv0_stripped); + + prepare_relocate (orig_installprefix, orig_installdir, argv0); +} + +/* Return the full pathname of the current executable, based on the earlier + call to set_program_name_and_installdir. Return NULL if unknown. */ +char * +get_full_program_name () +{ + return executable_fullname; +} + +#endif diff --git a/gettext-tools/lib/relocwrapper.c b/gettext-tools/lib/relocwrapper.c index 2be63c1ec..6a847850f 100644 --- a/gettext-tools/lib/relocwrapper.c +++ b/gettext-tools/lib/relocwrapper.c @@ -19,6 +19,7 @@ /* Dependencies: relocwrapper -> progname + -> progreloc -> xreadlink -> canonicalize -> relocatable