blob: 5bc2827a89b88ab500e2cf151b5d9b62a0eb82f5 [file] [log] [blame]
Guido van Rossum50d4cc21997-11-22 21:59:45 +00001
2/* Return the initial module search path. */
3/* Used by DOS, OS/2, Windows 3.1. Works on NT too. */
4
5#include "Python.h"
6#include "osdefs.h"
7
8#ifdef MS_WIN32
9#include <windows.h>
Thomas Woutersa5345942000-07-22 23:59:33 +000010extern BOOL PyWin_IsWin32s(void);
Guido van Rossum50d4cc21997-11-22 21:59:45 +000011#endif
12
13#include <sys/types.h>
14#include <sys/stat.h>
15#include <string.h>
16
17#if HAVE_UNISTD_H
18#include <unistd.h>
19#endif /* HAVE_UNISTD_H */
20
21/* Search in some common locations for the associated Python libraries.
22 *
Guido van Rossuma34c3131997-12-05 22:07:14 +000023 * Two directories must be found, the platform independent directory
24 * (prefix), containing the common .py and .pyc files, and the platform
25 * dependent directory (exec_prefix), containing the shared library
26 * modules. Note that prefix and exec_prefix can be the same directory,
27 * but for some installations, they are different.
Guido van Rossum50d4cc21997-11-22 21:59:45 +000028 *
29 * Py_GetPath() tries to return a sensible Python module search path.
30 *
31 * First, we look to see if the executable is in a subdirectory of
32 * the Python build directory. We calculate the full path of the
33 * directory containing the executable as progpath. We work backwards
34 * along progpath and look for $dir/Modules/Setup.in, a distinctive
35 * landmark. If found, we use $dir/Lib as $root. The returned
36 * Python path is the compiled #define PYTHONPATH with all the initial
37 * "./lib" replaced by $root.
38 *
39 * Otherwise, if there is a PYTHONPATH environment variable, we return that.
40 *
Jeremy Hylton847a9962000-05-26 21:49:07 +000041 * Otherwise we try to find $progpath/lib/os.py, and if found, then
Guido van Rossum50d4cc21997-11-22 21:59:45 +000042 * root is $progpath/lib, and we return Python path as compiled PYTHONPATH
43 * with all "./lib" replaced by $root (as above).
44 *
45 */
46
47#ifndef LANDMARK
Jeremy Hylton847a9962000-05-26 21:49:07 +000048#define LANDMARK "lib\\os.py"
Guido van Rossum50d4cc21997-11-22 21:59:45 +000049#endif
50
51static char prefix[MAXPATHLEN+1];
Guido van Rossuma34c3131997-12-05 22:07:14 +000052static char exec_prefix[MAXPATHLEN+1];
Guido van Rossum50d4cc21997-11-22 21:59:45 +000053static char progpath[MAXPATHLEN+1];
54static char *module_search_path = NULL;
55
56
57static int
Antoine Pitrouc83ea132010-05-09 14:46:46 +000058is_sep(char ch) /* determine if "ch" is a separator character */
Guido van Rossum50d4cc21997-11-22 21:59:45 +000059{
60#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +000061 return ch == SEP || ch == ALTSEP;
Guido van Rossum50d4cc21997-11-22 21:59:45 +000062#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +000063 return ch == SEP;
Guido van Rossum50d4cc21997-11-22 21:59:45 +000064#endif
65}
66
67
68static void
Thomas Wouters78890102000-07-22 19:25:51 +000069reduce(char *dir)
Guido van Rossum50d4cc21997-11-22 21:59:45 +000070{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000071 int i = strlen(dir);
72 while (i > 0 && !is_sep(dir[i]))
73 --i;
74 dir[i] = '\0';
Guido van Rossum50d4cc21997-11-22 21:59:45 +000075}
Antoine Pitrouc83ea132010-05-09 14:46:46 +000076
Guido van Rossum50d4cc21997-11-22 21:59:45 +000077
78static int
Thomas Wouters78890102000-07-22 19:25:51 +000079exists(char *filename)
Guido van Rossum50d4cc21997-11-22 21:59:45 +000080{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000081 struct stat buf;
82 return stat(filename, &buf) == 0;
Guido van Rossum50d4cc21997-11-22 21:59:45 +000083}
84
85
Andrew MacIntyred0278ec2004-12-12 08:28:11 +000086/* Add a path component, by appending stuff to buffer.
87 buffer must have at least MAXPATHLEN + 1 bytes allocated, and contain a
88 NUL-terminated string with no more than MAXPATHLEN characters (not counting
89 the trailing NUL). It's a fatal error if it contains a string longer than
90 that (callers must be careful!). If these requirements are met, it's
91 guaranteed that buffer will still be a NUL-terminated string with no more
92 than MAXPATHLEN characters at exit. If stuff is too long, only as much of
93 stuff as fits will be appended.
94*/
Guido van Rossum50d4cc21997-11-22 21:59:45 +000095static void
Thomas Wouters78890102000-07-22 19:25:51 +000096join(char *buffer, char *stuff)
Guido van Rossum50d4cc21997-11-22 21:59:45 +000097{
Antoine Pitrouc83ea132010-05-09 14:46:46 +000098 int n, k;
99 if (is_sep(stuff[0]))
100 n = 0;
101 else {
102 n = strlen(buffer);
103 if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
104 buffer[n++] = SEP;
105 }
106 if (n > MAXPATHLEN)
107 Py_FatalError("buffer overflow in getpathp.c's joinpath()");
108 k = strlen(stuff);
109 if (n + k > MAXPATHLEN)
110 k = MAXPATHLEN - n;
111 strncpy(buffer+n, stuff, k);
112 buffer[n+k] = '\0';
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000113}
114
115
116static int
Thomas Wouters78890102000-07-22 19:25:51 +0000117search_for_prefix(char *argv0_path, char *landmark)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000118{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000119 int n;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000120
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000121 /* Search from argv0_path, until root is found */
122 strcpy(prefix, argv0_path);
123 do {
124 n = strlen(prefix);
125 join(prefix, landmark);
126 if (exists(prefix)) {
127 prefix[n] = '\0';
128 return 1;
129 }
130 prefix[n] = '\0';
131 reduce(prefix);
132 } while (prefix[0]);
133 return 0;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000134}
135
136#ifdef MS_WIN32
137#include "malloc.h" // for alloca - see comments below!
138extern const char *PyWin_DLLVersionString; // a string loaded from the DLL at startup.
139
140
141/* Load a PYTHONPATH value from the registry.
142 Load from either HKEY_LOCAL_MACHINE or HKEY_CURRENT_USER.
143
144 Returns NULL, or a pointer that should be freed.
145*/
146
147static char *
148getpythonregpath(HKEY keyBase, BOOL bWin32s)
149{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000150 HKEY newKey = 0;
151 DWORD nameSize = 0;
152 DWORD dataSize = 0;
153 DWORD numEntries = 0;
154 LONG rc;
155 char *retval = NULL;
156 char *dataBuf;
157 const char keyPrefix[] = "Software\\Python\\PythonCore\\";
158 const char keySuffix[] = "\\PythonPath";
159 int versionLen;
160 char *keyBuf;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000161
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000162 // Tried to use sysget("winver") but here is too early :-(
163 versionLen = strlen(PyWin_DLLVersionString);
164 // alloca == no free required, but memory only local to fn.
165 // also no heap fragmentation! Am I being silly?
166 keyBuf = alloca(sizeof(keyPrefix)-1 + versionLen + sizeof(keySuffix)); // chars only, plus 1 NULL.
167 // lots of constants here for the compiler to optimize away :-)
168 memcpy(keyBuf, keyPrefix, sizeof(keyPrefix)-1);
169 memcpy(keyBuf+sizeof(keyPrefix)-1, PyWin_DLLVersionString, versionLen);
170 memcpy(keyBuf+sizeof(keyPrefix)-1+versionLen, keySuffix, sizeof(keySuffix)); // NULL comes with this one!
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000171
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000172 rc=RegOpenKey(keyBase,
173 keyBuf,
174 &newKey);
175 if (rc==ERROR_SUCCESS) {
176 RegQueryInfoKey(newKey, NULL, NULL, NULL, NULL, NULL, NULL,
177 &numEntries, &nameSize, &dataSize, NULL, NULL);
178 }
179 if (bWin32s && numEntries==0 && dataSize==0) {
180 /* must hardcode for Win32s */
181 numEntries = 1;
182 dataSize = 511;
183 }
184 if (numEntries) {
185 /* Loop over all subkeys. */
186 /* Win32s doesnt know how many subkeys, so we do
187 it twice */
188 char keyBuf[MAX_PATH+1];
189 int index = 0;
190 int off = 0;
191 for(index=0;;index++) {
192 long reqdSize = 0;
193 DWORD rc = RegEnumKey(newKey,
194 index, keyBuf, MAX_PATH+1);
195 if (rc) break;
196 rc = RegQueryValue(newKey, keyBuf, NULL, &reqdSize);
197 if (rc) break;
198 if (bWin32s && reqdSize==0) reqdSize = 512;
199 dataSize += reqdSize + 1; /* 1 for the ";" */
200 }
201 dataBuf = malloc(dataSize+1);
202 if (dataBuf==NULL)
203 return NULL; /* pretty serious? Raise error? */
204 /* Now loop over, grabbing the paths.
205 Subkeys before main library */
206 for(index=0;;index++) {
207 int adjust;
208 long reqdSize = dataSize;
209 DWORD rc = RegEnumKey(newKey,
210 index, keyBuf,MAX_PATH+1);
211 if (rc) break;
212 rc = RegQueryValue(newKey,
213 keyBuf, dataBuf+off, &reqdSize);
214 if (rc) break;
215 if (reqdSize>1) {
216 /* If Nothing, or only '\0' copied. */
217 adjust = strlen(dataBuf+off);
218 dataSize -= adjust;
219 off += adjust;
220 dataBuf[off++] = ';';
221 dataBuf[off] = '\0';
222 dataSize--;
223 }
224 }
225 /* Additionally, win32s doesnt work as expected, so
226 the specific strlen() is required for 3.1. */
227 rc = RegQueryValue(newKey, "", dataBuf+off, &dataSize);
228 if (rc==ERROR_SUCCESS) {
229 if (strlen(dataBuf)==0)
230 free(dataBuf);
231 else
232 retval = dataBuf; /* caller will free */
233 }
234 else
235 free(dataBuf);
236 }
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000237
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000238 if (newKey)
239 RegCloseKey(newKey);
240 return retval;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000241}
242#endif /* MS_WIN32 */
243
244static void
Thomas Wouters78890102000-07-22 19:25:51 +0000245get_progpath(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000246{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000247 extern char *Py_GetProgramName(void);
248 char *path = getenv("PATH");
249 char *prog = Py_GetProgramName();
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000250
251#ifdef MS_WIN32
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000252 if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
253 return;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000254#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000255 if (prog == NULL || *prog == '\0')
256 prog = "python";
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000257
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000258 /* If there is no slash in the argv0 path, then we have to
259 * assume python is on the user's $PATH, since there's no
260 * other way to find a directory to start the search from. If
261 * $PATH isn't exported, you lose.
262 */
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000263#ifdef ALTSEP
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000264 if (strchr(prog, SEP) || strchr(prog, ALTSEP))
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000265#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000266 if (strchr(prog, SEP))
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000267#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000268 strcpy(progpath, prog);
269 else if (path) {
270 while (1) {
271 char *delim = strchr(path, DELIM);
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000272
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000273 if (delim) {
274 int len = delim - path;
275 strncpy(progpath, path, len);
276 *(progpath + len) = '\0';
277 }
278 else
279 strcpy(progpath, path);
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000280
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000281 join(progpath, prog);
282 if (exists(progpath))
283 break;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000284
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000285 if (!delim) {
286 progpath[0] = '\0';
287 break;
288 }
289 path = delim + 1;
290 }
291 }
292 else
293 progpath[0] = '\0';
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000294}
295
296static void
Thomas Wouters78890102000-07-22 19:25:51 +0000297calculate_path(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000298{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000299 char argv0_path[MAXPATHLEN+1];
300 char *buf;
301 int bufsz;
302 char *pythonhome = Py_GetPythonHome();
303 char *envpath = Py_GETENV("PYTHONPATH");
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000304#ifdef MS_WIN32
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000305 char *machinepath, *userpath;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000306
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000307 /* Are we running under Windows 3.1(1) Win32s? */
308 if (PyWin_IsWin32s()) {
309 /* Only CLASSES_ROOT is supported */
310 machinepath = getpythonregpath(HKEY_CLASSES_ROOT, TRUE);
311 userpath = NULL;
312 } else {
313 machinepath = getpythonregpath(HKEY_LOCAL_MACHINE, FALSE);
314 userpath = getpythonregpath(HKEY_CURRENT_USER, FALSE);
315 }
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000316#endif
317
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000318 get_progpath();
319 strcpy(argv0_path, progpath);
320 reduce(argv0_path);
321 if (pythonhome == NULL || *pythonhome == '\0') {
322 if (search_for_prefix(argv0_path, LANDMARK))
323 pythonhome = prefix;
324 else
325 pythonhome = NULL;
326 }
327 else {
328 char *delim;
Guido van Rossuma34c3131997-12-05 22:07:14 +0000329
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000330 strcpy(prefix, pythonhome);
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000331
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000332 /* Extract Any Optional Trailing EXEC_PREFIX */
333 /* e.g. PYTHONHOME=<prefix>:<exec_prefix> */
334 delim = strchr(prefix, DELIM);
335 if (delim) {
336 *delim = '\0';
337 strcpy(exec_prefix, delim+1);
338 } else
339 strcpy(exec_prefix, EXEC_PREFIX);
Guido van Rossuma34c3131997-12-05 22:07:14 +0000340 }
341
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000342 if (envpath && *envpath == '\0')
343 envpath = NULL;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000344
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000345 /* We need to construct a path from the following parts:
346 (1) the PYTHONPATH environment variable, if set;
347 (2) for Win32, the machinepath and userpath, if set;
348 (3) the PYTHONPATH config macro, with the leading "."
349 of each component replaced with pythonhome, if set;
350 (4) the directory containing the executable (argv0_path).
351 The length calculation calculates #3 first.
352 */
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000353
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000354 /* Calculate size of return buffer */
355 if (pythonhome != NULL) {
356 char *p;
357 bufsz = 1;
358 for (p = PYTHONPATH; *p; p++) {
359 if (*p == DELIM)
360 bufsz++; /* number of DELIM plus one */
361 }
362 bufsz *= strlen(pythonhome);
363 }
364 else
365 bufsz = 0;
366 bufsz += strlen(PYTHONPATH) + 1;
367 if (envpath != NULL)
368 bufsz += strlen(envpath) + 1;
369 bufsz += strlen(argv0_path) + 1;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000370#ifdef MS_WIN32
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000371 if (machinepath)
372 bufsz += strlen(machinepath) + 1;
373 if (userpath)
374 bufsz += strlen(userpath) + 1;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000375#endif
376
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000377 module_search_path = buf = malloc(bufsz);
378 if (buf == NULL) {
379 /* We can't exit, so print a warning and limp along */
380 fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
381 if (envpath) {
382 fprintf(stderr, "Using default static $PYTHONPATH.\n");
383 module_search_path = envpath;
384 }
385 else {
386 fprintf(stderr, "Using environment $PYTHONPATH.\n");
387 module_search_path = PYTHONPATH;
388 }
389 return;
390 }
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000391
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000392 if (envpath) {
393 strcpy(buf, envpath);
394 buf = strchr(buf, '\0');
395 *buf++ = DELIM;
396 }
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000397#ifdef MS_WIN32
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000398 if (machinepath) {
399 strcpy(buf, machinepath);
400 buf = strchr(buf, '\0');
401 *buf++ = DELIM;
402 }
403 if (userpath) {
404 strcpy(buf, userpath);
405 buf = strchr(buf, '\0');
406 *buf++ = DELIM;
407 }
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000408#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000409 if (pythonhome == NULL) {
410 strcpy(buf, PYTHONPATH);
411 buf = strchr(buf, '\0');
412 }
413 else {
414 char *p = PYTHONPATH;
415 char *q;
416 int n;
417 for (;;) {
418 q = strchr(p, DELIM);
419 if (q == NULL)
420 n = strlen(p);
421 else
422 n = q-p;
423 if (p[0] == '.' && is_sep(p[1])) {
424 strcpy(buf, pythonhome);
425 buf = strchr(buf, '\0');
426 p++;
427 n--;
428 }
429 strncpy(buf, p, n);
430 buf += n;
431 if (q == NULL)
432 break;
433 *buf++ = DELIM;
434 p = q+1;
435 }
436 }
437 if (argv0_path) {
438 *buf++ = DELIM;
439 strcpy(buf, argv0_path);
440 buf = strchr(buf, '\0');
441 }
442 *buf = '\0';
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000443}
444
445
446/* External interface */
447
448char *
Thomas Wouters78890102000-07-22 19:25:51 +0000449Py_GetPath(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000450{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000451 if (!module_search_path)
452 calculate_path();
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000453
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000454 return module_search_path;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000455}
456
457char *
Thomas Wouters78890102000-07-22 19:25:51 +0000458Py_GetPrefix(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000459{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000460 if (!module_search_path)
461 calculate_path();
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000462
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000463 return prefix;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000464}
465
466char *
Thomas Wouters78890102000-07-22 19:25:51 +0000467Py_GetExecPrefix(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000468{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000469 if (!module_search_path)
470 calculate_path();
Guido van Rossuma34c3131997-12-05 22:07:14 +0000471
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000472 return exec_prefix;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000473}
474
475char *
Thomas Wouters78890102000-07-22 19:25:51 +0000476Py_GetProgramFullPath(void)
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000477{
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000478 if (!module_search_path)
479 calculate_path();
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000480
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000481 return progpath;
Guido van Rossum50d4cc21997-11-22 21:59:45 +0000482}