blob: 0d73774ce0e957a573c18ccfd02589d24aa8aae3 [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:
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +00007 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
Andrew MacIntyre41d97d62002-02-17 05:23:30 +00009 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.
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000019 - If we DO have a Python Home: The relevant sub-directories (Lib,
Georg Brandl6e47a332008-05-17 19:15:58 +000020 plat-win, etc) are based on the Python Home
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000021 - If we DO NOT have a Python Home, the core Python Path is
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000022 loaded from the registry. This is the main PythonPath key,
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000023 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
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000035 * When Python is hosted in another exe (different directory, embedded via
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000036 COM, etc), the Python Home will not be deduced, so the core path from
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000037 the registry is used. Other "application paths "in the registry are
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000038 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
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000088is_sep(char ch) /* determine if "ch" is a separator character */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000089{
90#ifdef ALTSEP
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000091 return ch == SEP || ch == ALTSEP;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000092#else
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +000093 return ch == SEP;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +000094#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{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000103 size_t i = strlen(dir);
104 while (i > 0 && !is_sep(dir[i]))
105 --i;
106 dir[i] = '\0';
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000107}
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000108
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000109static int
110exists(char *filename)
111{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000112 struct stat buf;
113 return stat(filename, &buf) == 0;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000114}
115
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000116/* Is module (check for .pyc/.pyo too)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000117 * Assumes 'filename' MAXPATHLEN+1 bytes long -
Andrew MacIntyre0c833482003-04-22 03:21:42 +0000118 * 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{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000123 if (exists(filename))
124 return 1;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000125
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000126 /* 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;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000133}
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{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000148 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 }
156 if (n > MAXPATHLEN)
157 Py_FatalError("buffer overflow in getpathp.c's joinpath()");
158 k = strlen(stuff);
159 if (n + k > MAXPATHLEN)
160 k = MAXPATHLEN - n;
161 strncpy(buffer+n, stuff, k);
162 buffer[n+k] = '\0';
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000163}
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{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000172 int n, ok;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000173
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000174 n = strlen(prefix);
175 join(prefix, landmark);
176 ok = ismodule(prefix);
177 prefix[n] = '\0';
178 return ok;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000179}
180
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000181/* 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{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000187 /* 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;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000195}
196
197
198static void
199get_progpath(void)
200{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000201 extern char *Py_GetProgramName(void);
202 char *path = getenv("PATH");
203 char *prog = Py_GetProgramName();
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000204
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000205 PPIB pib;
206 if ((DosGetInfoBlocks(NULL, &pib) == 0) &&
207 (DosQueryModuleName(pib->pib_hmte, sizeof(progpath), progpath) == 0))
208 return;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000209
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000210 if (prog == NULL || *prog == '\0')
211 prog = "python";
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000212
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000213 /* 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 */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000218#ifdef ALTSEP
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000219 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000220#else
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000221 if (strchr(prog, SEP))
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000222#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000223 strncpy(progpath, prog, MAXPATHLEN);
224 else if (path) {
225 while (1) {
226 char *delim = strchr(path, DELIM);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000227
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000228 if (delim) {
229 size_t len = delim - path;
230 /* ensure we can't overwrite buffer */
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000231#if !defined(PYCC_GCC)
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000232 len = min(MAXPATHLEN,len);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000233#else
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000234 len = MAXPATHLEN < len ? MAXPATHLEN : len;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000235#endif
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000236 strncpy(progpath, path, len);
237 *(progpath + len) = '\0';
238 }
239 else
240 strncpy(progpath, path, MAXPATHLEN);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000241
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000242 /* join() is safe for MAXPATHLEN+1 size buffer */
243 join(progpath, prog);
244 if (exists(progpath))
245 break;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000246
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000247 if (!delim) {
248 progpath[0] = '\0';
249 break;
250 }
251 path = delim + 1;
252 }
253 }
254 else
255 progpath[0] = '\0';
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000256}
257
258static void
259calculate_path(void)
260{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000261 char argv0_path[MAXPATHLEN+1];
262 char *buf;
263 size_t bufsz;
264 char *pythonhome = Py_GetPythonHome();
265 char *envpath = getenv("PYTHONPATH");
266 char zip_path[MAXPATHLEN+1];
267 size_t len;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000268
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000269 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);
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000281
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000282 if (envpath && *envpath == '\0')
283 envpath = NULL;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000284
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +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 }
Andrew MacIntyre214d39a2003-01-02 12:41:58 +0000297
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000298 /* We need to construct a path from the following parts.
299 * (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
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000307 /* 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;
321 bufsz += strlen(zip_path) + 1;
322 if (envpath != NULL)
323 bufsz += strlen(envpath) + 1;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000324
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000325 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 }
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000339
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000340 if (envpath) {
341 strcpy(buf, envpath);
342 buf = strchr(buf, '\0');
343 *buf++ = DELIM;
344 }
345 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
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000351 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';
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000385}
386
387
388/* External interface */
389
390char *
391Py_GetPath(void)
392{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000393 if (!module_search_path)
394 calculate_path();
395 return module_search_path;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000396}
397
398char *
399Py_GetPrefix(void)
400{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000401 if (!module_search_path)
402 calculate_path();
403 return prefix;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000404}
405
406char *
407Py_GetExecPrefix(void)
408{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000409 return Py_GetPrefix();
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000410}
411
412char *
413Py_GetProgramFullPath(void)
414{
Antoine Pitrou7f14f0d2010-05-09 16:14:21 +0000415 if (!module_search_path)
416 calculate_path();
417 return progpath;
Andrew MacIntyre41d97d62002-02-17 05:23:30 +0000418}