Mercurial > hg > octave-kai > gnulib-hg
annotate lib/progreloc.c @ 17463:203c036eb0c6
bootstrap: support checksum utils without a --status option
* build-aux/bootstrap: Only look for sha1sum if updating po files.
Add sha1 to the list of supported checksum utils since it's now
supported through adjustments below.
(update_po_files): Remove the use of --status
in a way that will suppress all error messages, but since this is
only used to minimize updates, it shouldn't cause an issue.
Exit early if there is a problem updating the po file checksums.
(find_tool): Remove the check for --version support as this
is optional as per commit 86186b17. Don't even check for the
presence of the command as if that is needed, it's supported
through configuring prerequisites in bootstrap.conf.
Prompt that when a tool isn't found, one can define an environment
variable to add to the hardcoded search list.
author | Pádraig Brady <P@draigBrady.com> |
---|---|
date | Thu, 08 Aug 2013 11:08:49 +0100 (2013-08-08) |
parents | e542fd46ad6f |
children |
rev | line source |
---|---|
4603 | 1 /* Provide relocatable programs. |
17249
e542fd46ad6f
maint: update all copyright year number ranges
Eric Blake <eblake@redhat.com>
parents:
16935
diff
changeset
|
2 Copyright (C) 2003-2013 Free Software Foundation, Inc. |
4603 | 3 Written by Bruno Haible <bruno@clisp.org>, 2003. |
4 | |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8272
diff
changeset
|
5 This program is free software: you can redistribute it and/or modify |
5270
b084a75dc8bc
Change copyright notice to GPL. The file is still under LGPL 2.0; this
Bruno Haible <bruno@clisp.org>
parents:
5164
diff
changeset
|
6 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8272
diff
changeset
|
7 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8272
diff
changeset
|
8 (at your option) any later version. |
4603 | 9 |
10 This program is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
5270
b084a75dc8bc
Change copyright notice to GPL. The file is still under LGPL 2.0; this
Bruno Haible <bruno@clisp.org>
parents:
5164
diff
changeset
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
b084a75dc8bc
Change copyright notice to GPL. The file is still under LGPL 2.0; this
Bruno Haible <bruno@clisp.org>
parents:
5164
diff
changeset
|
13 GNU General Public License for more details. |
4603 | 14 |
5270
b084a75dc8bc
Change copyright notice to GPL. The file is still under LGPL 2.0; this
Bruno Haible <bruno@clisp.org>
parents:
5164
diff
changeset
|
15 You should have received a copy of the GNU General Public License |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8272
diff
changeset
|
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
4603 | 17 |
18 | |
14541
0f5c066f32ab
* lib/progreloc.c (_GL_USE_STDLIB_ALLOC, malloc): Likewise.
Paul Eggert <eggert@cs.ucla.edu>
parents:
14399
diff
changeset
|
19 #define _GL_USE_STDLIB_ALLOC 1 |
7304
1c4ed7637c24
Include <config.h> unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
7023
diff
changeset
|
20 #include <config.h> |
4603 | 21 |
22 /* Specification. */ | |
23 #include "progname.h" | |
24 | |
25 #include <stdbool.h> | |
26 #include <stdio.h> | |
27 #include <stdlib.h> | |
28 #include <string.h> | |
29 #include <fcntl.h> | |
8272
fd48e35f4e5e
New modules relocatable, relocatable-lib, relocatable-script.
Bruno Haible <bruno@clisp.org>
parents:
7863
diff
changeset
|
30 #include <unistd.h> |
4603 | 31 #include <sys/stat.h> |
32 | |
16935
498a2211d839
Write "Mac OS X" instead of "MacOS X".
Bruno Haible <bruno@clisp.org>
parents:
16242
diff
changeset
|
33 /* Get declaration of _NSGetExecutablePath on Mac OS X 10.2 or newer. */ |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
34 #if HAVE_MACH_O_DYLD_H |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
35 # include <mach-o/dyld.h> |
4603 | 36 #endif |
37 | |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
38 #if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
39 # define WINDOWS_NATIVE |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
40 #endif |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
41 |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
42 #ifdef WINDOWS_NATIVE |
4603 | 43 # define WIN32_LEAN_AND_MEAN |
44 # include <windows.h> | |
45 #endif | |
46 | |
47 #include "relocatable.h" | |
48 | |
49 #ifdef NO_XMALLOC | |
9547
c3d038b0b4d3
Fix link error in relocatability wrappers, due to xalloc_die().
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
50 # include "areadlink.h" |
c3d038b0b4d3
Fix link error in relocatability wrappers, due to xalloc_die().
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
51 # define xreadlink areadlink |
c3d038b0b4d3
Fix link error in relocatability wrappers, due to xalloc_die().
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
52 #else |
c3d038b0b4d3
Fix link error in relocatability wrappers, due to xalloc_die().
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
53 # include "xreadlink.h" |
c3d038b0b4d3
Fix link error in relocatability wrappers, due to xalloc_die().
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
54 #endif |
c3d038b0b4d3
Fix link error in relocatability wrappers, due to xalloc_die().
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
55 |
c3d038b0b4d3
Fix link error in relocatability wrappers, due to xalloc_die().
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
56 #ifdef NO_XMALLOC |
4603 | 57 # define xmalloc malloc |
5583 | 58 # define xstrdup strdup |
4603 | 59 #else |
5583 | 60 # include "xalloc.h" |
4603 | 61 #endif |
62 | |
13667
3211d36b9926
relocatable-prog-wrapper: Fix compilation failure due to O_EXEC.
Bruno Haible <bruno@clisp.org>
parents:
13664
diff
changeset
|
63 #ifndef O_EXEC |
3211d36b9926
relocatable-prog-wrapper: Fix compilation failure due to O_EXEC.
Bruno Haible <bruno@clisp.org>
parents:
13664
diff
changeset
|
64 # define O_EXEC O_RDONLY /* This is often close enough in older systems. */ |
3211d36b9926
relocatable-prog-wrapper: Fix compilation failure due to O_EXEC.
Bruno Haible <bruno@clisp.org>
parents:
13664
diff
changeset
|
65 #endif |
3211d36b9926
relocatable-prog-wrapper: Fix compilation failure due to O_EXEC.
Bruno Haible <bruno@clisp.org>
parents:
13664
diff
changeset
|
66 |
12049
22a617bea642
Declare canonicalize_file_name.
Bruno Haible <bruno@clisp.org>
parents:
12034
diff
changeset
|
67 /* Declare canonicalize_file_name. |
22a617bea642
Declare canonicalize_file_name.
Bruno Haible <bruno@clisp.org>
parents:
12034
diff
changeset
|
68 The <stdlib.h> included above may be the system's one, not the gnulib |
22a617bea642
Declare canonicalize_file_name.
Bruno Haible <bruno@clisp.org>
parents:
12034
diff
changeset
|
69 one. */ |
22a617bea642
Declare canonicalize_file_name.
Bruno Haible <bruno@clisp.org>
parents:
12034
diff
changeset
|
70 extern char * canonicalize_file_name (const char *name); |
22a617bea642
Declare canonicalize_file_name.
Bruno Haible <bruno@clisp.org>
parents:
12034
diff
changeset
|
71 |
4603 | 72 /* Pathname support. |
73 ISSLASH(C) tests whether C is a directory separator character. | |
74 IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. | |
75 */ | |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
76 #if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__ |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
77 /* Native Windows, OS/2, DOS */ |
4603 | 78 # define ISSLASH(C) ((C) == '/' || (C) == '\\') |
79 # define HAS_DEVICE(P) \ | |
80 ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ | |
81 && (P)[1] == ':') | |
82 # define IS_PATH_WITH_DIR(P) \ | |
83 (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) | |
5164
773a21466082
Rename FILESYSTEM_PREFIX_LEN.
Bruno Haible <bruno@clisp.org>
parents:
5053
diff
changeset
|
84 # define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) |
4603 | 85 #else |
86 /* Unix */ | |
87 # define ISSLASH(C) ((C) == '/') | |
88 # define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) | |
5164
773a21466082
Rename FILESYSTEM_PREFIX_LEN.
Bruno Haible <bruno@clisp.org>
parents:
5053
diff
changeset
|
89 # define FILE_SYSTEM_PREFIX_LEN(P) 0 |
4603 | 90 #endif |
91 | |
7863 | 92 /* The results of open() in this file are not used with fchdir, |
93 therefore save some unnecessary work in fchdir.c. */ | |
94 #undef open | |
95 #undef close | |
96 | |
13397
758ef73803db
Avoid relocwrapper link errors due to gnulib replacement functions.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
97 /* Use the system functions, not the gnulib overrides in this file. */ |
758ef73803db
Avoid relocwrapper link errors due to gnulib replacement functions.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
98 #undef sprintf |
758ef73803db
Avoid relocwrapper link errors due to gnulib replacement functions.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
99 |
4603 | 100 #undef set_program_name |
101 | |
102 | |
103 #if ENABLE_RELOCATABLE | |
104 | |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
105 #if defined __linux__ || defined __CYGWIN__ |
4603 | 106 /* File descriptor of the executable. |
107 (Only used to verify that we find the correct executable.) */ | |
108 static int executable_fd = -1; | |
109 #endif | |
110 | |
111 /* Tests whether a given pathname may belong to the executable. */ | |
112 static bool | |
113 maybe_executable (const char *filename) | |
114 { | |
16242
59c686e5b2df
Talk about "native Windows API", not "Woe32".
Bruno Haible <bruno@clisp.org>
parents:
16214
diff
changeset
|
115 /* The native Windows API lacks the access() function. */ |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
116 #if !defined WINDOWS_NATIVE |
4603 | 117 if (access (filename, X_OK) < 0) |
118 return false; | |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
119 #endif |
4603 | 120 |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
121 #if defined __linux__ || defined __CYGWIN__ |
4603 | 122 if (executable_fd >= 0) |
123 { | |
124 /* If we already have an executable_fd, check that filename points to | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
125 the same inode. */ |
4603 | 126 struct stat statexe; |
127 struct stat statfile; | |
128 | |
129 if (fstat (executable_fd, &statexe) >= 0) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
130 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
131 if (stat (filename, &statfile) < 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
132 return false; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
133 if (!(statfile.st_dev |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
134 && statfile.st_dev == statexe.st_dev |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
135 && statfile.st_ino == statexe.st_ino)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
136 return false; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
137 } |
4603 | 138 } |
139 #endif | |
140 | |
141 return true; | |
142 } | |
143 | |
144 /* Determine the full pathname of the current executable, freshly allocated. | |
145 Return NULL if unknown. | |
16242
59c686e5b2df
Talk about "native Windows API", not "Woe32".
Bruno Haible <bruno@clisp.org>
parents:
16214
diff
changeset
|
146 Guaranteed to work on Linux and native Windows. Likely to work on the |
59c686e5b2df
Talk about "native Windows API", not "Woe32".
Bruno Haible <bruno@clisp.org>
parents:
16214
diff
changeset
|
147 other Unixes (maybe except BeOS), under most conditions. */ |
4603 | 148 static char * |
149 find_executable (const char *argv0) | |
150 { | |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
151 #if defined WINDOWS_NATIVE |
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
152 /* Native Windows only. |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
153 On Cygwin, it is better to use the Cygwin provided /proc interface, than |
16214
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
154 to use native Windows API and cygwin_conv_to_posix_path, because it |
ec738d6aeef5
Talk about "native Windows API", not "Win32".
Bruno Haible <bruno@clisp.org>
parents:
16201
diff
changeset
|
155 supports longer file names |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
156 (see <http://cygwin.com/ml/cygwin/2011-01/msg00410.html>). */ |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
157 char location[MAX_PATH]; |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
158 int length = GetModuleFileName (NULL, location, sizeof (location)); |
4603 | 159 if (length < 0) |
160 return NULL; | |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
161 if (!IS_PATH_WITH_DIR (location)) |
4603 | 162 /* Shouldn't happen. */ |
163 return NULL; | |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
164 return xstrdup (location); |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
165 #else /* Unix */ |
14384
588ed4cdea87
Fix misindentation of preprocessor directives.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
166 # ifdef __linux__ |
4603 | 167 /* The executable is accessible as /proc/<pid>/exe. In newer Linux |
168 versions, also as /proc/self/exe. Linux >= 2.1 provides a symlink | |
169 to the true pathname; older Linux versions give only device and ino, | |
170 enclosed in brackets, which we cannot use here. */ | |
171 { | |
172 char *link; | |
173 | |
174 link = xreadlink ("/proc/self/exe"); | |
175 if (link != NULL && link[0] != '[') | |
176 return link; | |
177 if (executable_fd < 0) | |
13664
241057e2e60f
fcntl-h: define O_CLOEXEC and O_EXEC if not defined; use new defines
Paul Eggert <eggert@cs.ucla.edu>
parents:
13397
diff
changeset
|
178 executable_fd = open ("/proc/self/exe", O_EXEC, 0); |
4603 | 179 |
180 { | |
181 char buf[6+10+5]; | |
182 sprintf (buf, "/proc/%d/exe", getpid ()); | |
183 link = xreadlink (buf); | |
184 if (link != NULL && link[0] != '[') | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
185 return link; |
4603 | 186 if (executable_fd < 0) |
13664
241057e2e60f
fcntl-h: define O_CLOEXEC and O_EXEC if not defined; use new defines
Paul Eggert <eggert@cs.ucla.edu>
parents:
13397
diff
changeset
|
187 executable_fd = open (buf, O_EXEC, 0); |
4603 | 188 } |
189 } | |
14384
588ed4cdea87
Fix misindentation of preprocessor directives.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
190 # endif |
14399
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
191 # ifdef __CYGWIN__ |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
192 /* The executable is accessible as /proc/<pid>/exe, at least in |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
193 Cygwin >= 1.5. */ |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
194 { |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
195 char *link; |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
196 |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
197 link = xreadlink ("/proc/self/exe"); |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
198 if (link != NULL) |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
199 return link; |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
200 if (executable_fd < 0) |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
201 executable_fd = open ("/proc/self/exe", O_EXEC, 0); |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
202 } |
5e10178f1466
On Cygwin, use /proc file system instead of win32 API.
Bruno Haible <bruno@clisp.org>
parents:
14384
diff
changeset
|
203 # endif |
14384
588ed4cdea87
Fix misindentation of preprocessor directives.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
204 # if HAVE_MACH_O_DYLD_H && HAVE__NSGETEXECUTABLEPATH |
16935
498a2211d839
Write "Mac OS X" instead of "MacOS X".
Bruno Haible <bruno@clisp.org>
parents:
16242
diff
changeset
|
205 /* On Mac OS X 10.2 or newer, the function |
11025
6d85e95ca18f
Update use of API that has changed in MacOS X 10.4.
Bruno Haible <bruno@clisp.org>
parents:
9576
diff
changeset
|
206 int _NSGetExecutablePath (char *buf, uint32_t *bufsize); |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
207 can be used to retrieve the executable's full path. */ |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
208 char location[4096]; |
11025
6d85e95ca18f
Update use of API that has changed in MacOS X 10.4.
Bruno Haible <bruno@clisp.org>
parents:
9576
diff
changeset
|
209 unsigned int length = sizeof (location); |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
210 if (_NSGetExecutablePath (location, &length) == 0 |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
211 && location[0] == '/') |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
212 return canonicalize_file_name (location); |
14384
588ed4cdea87
Fix misindentation of preprocessor directives.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
213 # endif |
4603 | 214 /* Guess the executable's full path. We assume the executable has been |
215 called via execlp() or execvp() with properly set up argv[0]. The | |
216 login(1) convention to add a '-' prefix to argv[0] is not supported. */ | |
217 { | |
218 bool has_slash = false; | |
219 { | |
220 const char *p; | |
221 for (p = argv0; *p; p++) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
222 if (*p == '/') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
223 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
224 has_slash = true; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
225 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
226 } |
4603 | 227 } |
228 if (!has_slash) | |
229 { | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
230 /* exec searches paths without slashes in the directory list given |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
231 by $PATH. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
232 const char *path = getenv ("PATH"); |
4603 | 233 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
234 if (path != NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
235 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
236 const char *p; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
237 const char *p_next; |
4603 | 238 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
239 for (p = path; *p; p = p_next) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
240 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
241 const char *q; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
242 size_t p_len; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
243 char *concat_name; |
4603 | 244 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
245 for (q = p; *q; q++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
246 if (*q == ':') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
247 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
248 p_len = q - p; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
249 p_next = (*q == '\0' ? q : q + 1); |
4603 | 250 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
251 /* We have a path item at p, of length p_len. |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
252 Now concatenate the path item and argv0. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
253 concat_name = (char *) xmalloc (p_len + strlen (argv0) + 2); |
14384
588ed4cdea87
Fix misindentation of preprocessor directives.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
254 # ifdef NO_XMALLOC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
255 if (concat_name == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
256 return NULL; |
14384
588ed4cdea87
Fix misindentation of preprocessor directives.
Bruno Haible <bruno@clisp.org>
parents:
14079
diff
changeset
|
257 # endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
258 if (p_len == 0) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
259 /* An empty PATH element designates the current directory. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
260 strcpy (concat_name, argv0); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
261 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
262 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
263 memcpy (concat_name, p, p_len); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
264 concat_name[p_len] = '/'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
265 strcpy (concat_name + p_len + 1, argv0); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
266 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
267 if (maybe_executable (concat_name)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
268 return canonicalize_file_name (concat_name); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
269 free (concat_name); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
270 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
271 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
272 /* Not found in the PATH, assume the current directory. */ |
4603 | 273 } |
274 /* exec treats paths containing slashes as relative to the current | |
275 directory. */ | |
276 if (maybe_executable (argv0)) | |
277 return canonicalize_file_name (argv0); | |
278 } | |
279 /* No way to find the executable. */ | |
280 return NULL; | |
281 #endif | |
282 } | |
283 | |
284 /* Full pathname of executable, or NULL. */ | |
285 static char *executable_fullname; | |
286 | |
287 static void | |
288 prepare_relocate (const char *orig_installprefix, const char *orig_installdir, | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
289 const char *argv0) |
4603 | 290 { |
9576
8cae100b8cd1
Improve memory cleanup in 'relocatable' module.
Bruno Haible <bruno@clisp.org>
parents:
9547
diff
changeset
|
291 char *curr_prefix; |
4603 | 292 |
293 /* Determine the full pathname of the current executable. */ | |
294 executable_fullname = find_executable (argv0); | |
295 | |
296 /* Determine the current installation prefix from it. */ | |
297 curr_prefix = compute_curr_prefix (orig_installprefix, orig_installdir, | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
298 executable_fullname); |
4603 | 299 if (curr_prefix != NULL) |
9576
8cae100b8cd1
Improve memory cleanup in 'relocatable' module.
Bruno Haible <bruno@clisp.org>
parents:
9547
diff
changeset
|
300 { |
8cae100b8cd1
Improve memory cleanup in 'relocatable' module.
Bruno Haible <bruno@clisp.org>
parents:
9547
diff
changeset
|
301 /* Now pass this prefix to all copies of the relocate.c source file. */ |
8cae100b8cd1
Improve memory cleanup in 'relocatable' module.
Bruno Haible <bruno@clisp.org>
parents:
9547
diff
changeset
|
302 set_relocation_prefix (orig_installprefix, curr_prefix); |
8cae100b8cd1
Improve memory cleanup in 'relocatable' module.
Bruno Haible <bruno@clisp.org>
parents:
9547
diff
changeset
|
303 |
8cae100b8cd1
Improve memory cleanup in 'relocatable' module.
Bruno Haible <bruno@clisp.org>
parents:
9547
diff
changeset
|
304 free (curr_prefix); |
8cae100b8cd1
Improve memory cleanup in 'relocatable' module.
Bruno Haible <bruno@clisp.org>
parents:
9547
diff
changeset
|
305 } |
4603 | 306 } |
307 | |
308 /* Set program_name, based on argv[0], and original installation prefix and | |
309 directory, for relocatability. */ | |
310 void | |
311 set_program_name_and_installdir (const char *argv0, | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
312 const char *orig_installprefix, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
313 const char *orig_installdir) |
4603 | 314 { |
315 const char *argv0_stripped = argv0; | |
316 | |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
317 /* Relocatable programs are renamed to .bin by install-reloc. Or, more |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
318 generally, their suffix is changed from $exeext to .bin$exeext. |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
319 Remove the ".bin" here. */ |
4603 | 320 { |
321 size_t argv0_len = strlen (argv0); | |
7023
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
322 const size_t exeext_len = sizeof (EXEEXT) - sizeof (""); |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
323 if (argv0_len > 4 + exeext_len) |
d78abd0c0b70
Update from GNU gettext 0.15.
Bruno Haible <bruno@clisp.org>
parents:
6259
diff
changeset
|
324 if (memcmp (argv0 + argv0_len - exeext_len - 4, ".bin", 4) == 0) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
325 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
326 if (sizeof (EXEEXT) > sizeof ("")) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
327 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
328 /* Compare using an inlined copy of c_strncasecmp(), because |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
329 the filenames may have undergone a case conversion since |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
330 they were packaged. In other words, EXEEXT may be ".exe" |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
331 on one system and ".EXE" on another. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
332 static const char exeext[] = EXEEXT; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
333 const char *s1 = argv0 + argv0_len - exeext_len; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
334 const char *s2 = exeext; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
335 for (; *s1 != '\0'; s1++, s2++) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
336 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
337 unsigned char c1 = *s1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
338 unsigned char c2 = *s2; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
339 if ((c1 >= 'A' && c1 <= 'Z' ? c1 - 'A' + 'a' : c1) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
340 != (c2 >= 'A' && c2 <= 'Z' ? c2 - 'A' + 'a' : c2)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
341 goto done_stripping; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
342 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
343 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
344 /* Remove ".bin" before EXEEXT or its equivalent. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
345 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
346 char *shorter = (char *) xmalloc (argv0_len - 4 + 1); |
4603 | 347 #ifdef NO_XMALLOC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
348 if (shorter != NULL) |
4603 | 349 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
350 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
351 memcpy (shorter, argv0, argv0_len - exeext_len - 4); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
352 if (sizeof (EXEEXT) > sizeof ("")) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
353 memcpy (shorter + argv0_len - exeext_len - 4, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
354 argv0 + argv0_len - exeext_len - 4, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
355 exeext_len); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
356 shorter[argv0_len - 4] = '\0'; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
357 argv0_stripped = shorter; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
358 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
359 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12049
diff
changeset
|
360 done_stripping: ; |
4603 | 361 } |
362 } | |
363 | |
364 set_program_name (argv0_stripped); | |
365 | |
366 prepare_relocate (orig_installprefix, orig_installdir, argv0); | |
367 } | |
368 | |
369 /* Return the full pathname of the current executable, based on the earlier | |
370 call to set_program_name_and_installdir. Return NULL if unknown. */ | |
371 char * | |
4691 | 372 get_full_program_name (void) |
4603 | 373 { |
374 return executable_fullname; | |
375 } | |
376 | |
377 #endif |