blob: 5839eab3654a675dd90520d0907d603f6a00d3c0 [file] [log] [blame]
Andrew MacIntyre41d97d62002-02-17 05:23:30 +00001
2/* Return the initial module search path. */
3/* This version used by OS/2+EMX */
4
5/* ----------------------------------------------------------------
6 PATH RULES FOR OS/2+EMX:
7 This describes how sys.path is formed on OS/2+EMX. It describes the
8 functionality, not the implementation (ie, the order in which these
9 are actually fetched is different)
10
11 * Python always adds an empty entry at the start, which corresponds
12 to the current directory.
13
Georg Brandl7eb4b7d2005-07-22 21:49:32 +000014 * If the PYTHONPATH env. var. exists, its entries are added next.
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000015
16 * We attempt to locate the "Python Home" - if the PYTHONHOME env var
17 is set, we believe it. Otherwise, we use the path of our host .EXE's
18 to try and locate our "landmark" (lib\\os.py) and deduce our home.
19 - If we DO have a Python Home: The relevant sub-directories (Lib,
20 plat-win, lib-tk, etc) are based on the Python Home
21 - If we DO NOT have a Python Home, the core Python Path is
22 loaded from the registry. This is the main PythonPath key,
23 and both HKLM and HKCU are combined to form the path)
24
25 * Iff - we can not locate the Python Home, and have not had a PYTHONPATH
26 specified (ie, we have _nothing_ we can assume is a good path), a
27 default path with relative entries is used (eg. .\Lib;.\plat-win, etc)
28
29
30 The end result of all this is:
31 * When running python.exe, or any other .exe in the main Python directory
32 (either an installed version, or directly from the PCbuild directory),
33 the core path is deduced.
34
35 * When Python is hosted in another exe (different directory, embedded via
36 COM, etc), the Python Home will not be deduced, so the core path from
37 the registry is used. Other "application paths "in the registry are
38 always read.
39
40 * If Python can't find its home and there is no registry (eg, frozen
41 exe, some very strange installation setup) you get a path with
42 some default, but relative, paths.
43
44 ---------------------------------------------------------------- */
45
46
47#include "Python.h"
48#include "osdefs.h"
49
50#ifndef PYOS_OS2
51#error This file only compilable on OS/2
52#endif
53
54#define INCL_DOS
55#include <os2.h>
56
57#include <sys/types.h>
58#include <sys/stat.h>
59#include <string.h>
60
61#if HAVE_UNISTD_H
62#include <unistd.h>
63#endif /* HAVE_UNISTD_H */
64
65/* Search in some common locations for the associated Python libraries.
66 *
67 * Py_GetPath() tries to return a sensible Python module search path.
68 *
69 * The approach is an adaptation for Windows of the strategy used in
70 * ../Modules/getpath.c; it uses the Windows Registry as one of its
71 * information sources.
72 */
73
74#ifndef LANDMARK
75#if defined(PYCC_GCC)
76#define LANDMARK "lib/os.py"
77#else
78#define LANDMARK "lib\\os.py"
79#endif
80#endif
81
82static char prefix[MAXPATHLEN+1];
83static char progpath[MAXPATHLEN+1];
84static char *module_search_path = NULL;
85
86
87static int
88is_sep(char ch) /* determine if "ch" is a separator character */
89{
90#ifdef ALTSEP
91 return ch == SEP || ch == ALTSEP;
92#else
93 return ch == SEP;
94#endif
95}
96
Andrew MacIntyre0c833482003-04-22 03:21:42 +000097/* assumes 'dir' null terminated in bounds.
98 * Never writes beyond existing terminator.
99 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000100static void
101reduce(char *dir)
102{
103 size_t i = strlen(dir);
104 while (i > 0 && !is_sep(dir[i]))
105 --i;
106 dir[i] = '\0';
107}
108
109static int
110exists(char *filename)
111{
112 struct stat buf;
113 return stat(filename, &buf) == 0;
114}
115
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000116/* Is module (check for .pyc/.pyo too)
117 * Assumes 'filename' MAXPATHLEN+1 bytes long -
118 * may extend 'filename' by one character.
119 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000120static int
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000121ismodule(char *filename)
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000122{
123 if (exists(filename))
124 return 1;
125
126 /* Check for the compiled version of prefix. */
127 if (strlen(filename) < MAXPATHLEN) {
128 strcat(filename, Py_OptimizeFlag ? "o" : "c");
129 if (exists(filename))
130 return 1;
131 }
132 return 0;
133}
134
Andrew MacIntyred0278ec2004-12-12 08:28:11 +0000135/* Add a path component, by appending stuff to buffer.
136 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
137 NUL-terminated string with no more than MAXPATHLEN characters (not counting
138 the trailing NUL). It's a fatal error if it contains a string longer than
139 that (callers must be careful!). If these requirements are met, it's
140 guaranteed that buffer will still be a NUL-terminated string with no more
141 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
142 stuff as fits will be appended.
143*/
144
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000145static void
146join(char *buffer, char *stuff)
147{
148 size_t n, k;
149 if (is_sep(stuff[0]))
150 n = 0;
151 else {
152 n = strlen(buffer);
153 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
154 buffer[n++] = SEP;
155 }
Andrew MacIntyred0278ec2004-12-12 08:28:11 +0000156 if (n > MAXPATHLEN)
157 Py_FatalError("buffer overflow in getpathp.c's joinpath()");
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000158 k = strlen(stuff);
159 if (n + k > MAXPATHLEN)
160 k = MAXPATHLEN - n;
161 strncpy(buffer+n, stuff, k);
162 buffer[n+k] = '\0';
163}
164
165/* gotlandmark only called by search_for_prefix, which ensures
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000166 * 'prefix' is null terminated in bounds. join() ensures
167 * 'landmark' can not overflow prefix if too long.
168 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000169static int
170gotlandmark(char *landmark)
171{
172 int n, ok;
173
174 n = strlen(prefix);
175 join(prefix, landmark);
176 ok = ismodule(prefix);
177 prefix[n] = '\0';
178 return ok;
179}
180
181/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000182 * assumption provided by only caller, calculate_path()
183 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000184static int
185search_for_prefix(char *argv0_path, char *landmark)
186{
187 /* Search from argv0_path, until landmark is found */
188 strcpy(prefix, argv0_path);
189 do {
190 if (gotlandmark(landmark))
191 return 1;
192 reduce(prefix);
193 } while (prefix[0]);
194 return 0;
195}
196
197
198static void
199get_progpath(void)
200{
201 extern char *Py_GetProgramName(void);
202 char *path = getenv("PATH");
203 char *prog = Py_GetProgramName();
204
205 PPIB pib;
206 if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
207 (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
208 return;
209
210 if (prog == NULL || *prog == '\0')
211 prog = "python";
212
213 /* If there is no slash in the argv0 path, then we have to
214 * assume python is on the user's $PATH, since there's no
215 * other way to find a directory to start the search from. If
216 * $PATH isn't exported, you lose.
217 */
218#ifdef ALTSEP
219 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
220#else
221 if (strchr(prog, SEP))
222#endif
223 strncpy(progpath, prog, MAXPATHLEN);
224 else if (path) {
225 while (1) {
226 char *delim = strchr(path, DELIM);
227
228 if (delim) {
229 size_t len = delim - path;
230 /* ensure we can't overwrite buffer */
231#if !defined(PYCC_GCC)
232 len = min(MAXPATHLEN,len);
233#else
234 len = MAXPATHLEN < len ? MAXPATHLEN : len;
235#endif
236 strncpy(progpath, path, len);
237 *(progpath + len) = '\0';
238 }
239 else
240 strncpy(progpath, path, MAXPATHLEN);
241
242 /* join() is safe for MAXPATHLEN+1 size buffer */
243 join(progpath, prog);
244 if (exists(progpath))
245 break;
246
247 if (!delim) {
248 progpath[0] = '\0';
249 break;
250 }
251 path = delim + 1;
252 }
253 }
254 else
255 progpath[0] = '\0';
256}
257
258static void
259calculate_path(void)
260{
261 char argv0_path[MAXPATHLEN+1];
262 char *buf;
263 size_t bufsz;
264 char *pythonhome = Py_GetPythonHome();
265 char *envpath = getenv("PYTHONPATH");
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000266 char zip_path[MAXPATHLEN+1];
267 size_t len;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000268
269 get_progpath();
270 /* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
271 strcpy(argv0_path, progpath);
272 reduce(argv0_path);
273 if (pythonhome == NULL || *pythonhome == '\0') {
274 if (search_for_prefix(argv0_path, LANDMARK))
275 pythonhome = prefix;
276 else
277 pythonhome = NULL;
278 }
279 else
280 strncpy(prefix, pythonhome, MAXPATHLEN);
281
282 if (envpath && *envpath == '\0')
283 envpath = NULL;
284
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000285 /* Calculate zip archive path */
286 strncpy(zip_path, progpath, MAXPATHLEN);
287 zip_path[MAXPATHLEN] = '\0';
288 len = strlen(zip_path);
289 if (len > 4) {
290 zip_path[len-3] = 'z'; /* change ending to "zip" */
291 zip_path[len-2] = 'i';
292 zip_path[len-1] = 'p';
293 }
294 else {
295 zip_path[0] = 0;
296 }
297
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000298 /* We need to construct a path from the following parts.
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000299 * (1) the PYTHONPATH environment variable, if set;
300 * (2) the zip archive file path;
301 * (3) the PYTHONPATH config macro, with the leading "."
302 * of each component replaced with pythonhome, if set;
303 * (4) the directory containing the executable (argv0_path).
304 * The length calculation calculates #3 first.
305 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000306
307 /* Calculate size of return buffer */
308 if (pythonhome != NULL) {
309 char *p;
310 bufsz = 1;
311 for (p = PYTHONPATH; *p; p++) {
312 if (*p == DELIM)
313 bufsz++; /* number of DELIM plus one */
314 }
315 bufsz *= strlen(pythonhome);
316 }
317 else
318 bufsz = 0;
319 bufsz += strlen(PYTHONPATH) + 1;
320 bufsz += strlen(argv0_path) + 1;
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000321 bufsz += strlen(zip_path) + 1;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000322 if (envpath != NULL)
323 bufsz += strlen(envpath) + 1;
324
325 module_search_path = buf = malloc(bufsz);
326 if (buf == NULL) {
327 /* We can't exit, so print a warning and limp along */
328 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
329 if (envpath) {
330 fprintf(stderr, "Using environment $PYTHONPATH.\n");
331 module_search_path = envpath;
332 }
333 else {
334 fprintf(stderr, "Using default static path.\n");
335 module_search_path = PYTHONPATH;
336 }
337 return;
338 }
339
340 if (envpath) {
341 strcpy(buf, envpath);
342 buf = strchr(buf, '\0');
343 *buf++ = DELIM;
344 }
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000345 if (zip_path[0]) {
346 strcpy(buf, zip_path);
347 buf = strchr(buf, '\0');
348 *buf++ = DELIM;
349 }
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000350
351 if (pythonhome == NULL) {
352 strcpy(buf, PYTHONPATH);
353 buf = strchr(buf, '\0');
354 }
355 else {
356 char *p = PYTHONPATH;
357 char *q;
358 size_t n;
359 for (;;) {
360 q = strchr(p, DELIM);
361 if (q == NULL)
362 n = strlen(p);
363 else
364 n = q-p;
365 if (p[0] == '.' && is_sep(p[1])) {
366 strcpy(buf, pythonhome);
367 buf = strchr(buf, '\0');
368 p++;
369 n--;
370 }
371 strncpy(buf, p, n);
372 buf += n;
373 if (q == NULL)
374 break;
375 *buf++ = DELIM;
376 p = q+1;
377 }
378 }
379 if (argv0_path) {
380 *buf++ = DELIM;
381 strcpy(buf, argv0_path);
382 buf = strchr(buf, '\0');
383 }
384 *buf = '\0';
385}
386
387
388/* External interface */
389
390char *
391Py_GetPath(void)
392{
393 if (!module_search_path)
394 calculate_path();
395 return module_search_path;
396}
397
398char *
399Py_GetPrefix(void)
400{
401 if (!module_search_path)
402 calculate_path();
403 return prefix;
404}
405
406char *
407Py_GetExecPrefix(void)
408{
409 return Py_GetPrefix();
410}
411
412char *
413Py_GetProgramFullPath(void)
414{
415 if (!module_search_path)
416 calculate_path();
417 return progpath;
418}