1 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 14 * If the PYTHONPATH env. var. exists, its entries are added next. 15 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 82 static char prefix[MAXPATHLEN+1]; 83 static char progpath[MAXPATHLEN+1]; 84 static char *module_search_path = NULL; 85 86 87 static int 88 is_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 97 /* assumes 'dir' null terminated in bounds. 98 * Never writes beyond existing terminator. 99 */ 100 static void 101 reduce(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 109 static int 110 exists(char *filename) 111 { 112 struct stat buf; 113 return stat(filename, &buf) == 0; 114 } 115 116 /* Is module (check for .pyc/.pyo too) 117 * Assumes 'filename' MAXPATHLEN+1 bytes long - 118 * may extend 'filename' by one character. 119 */ 120 static int 121 ismodule(char *filename) 122 { 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 135 /* 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 145 static void 146 join(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 } 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'; 163 } 164 165 /* gotlandmark only called by search_for_prefix, which ensures 166 * 'prefix' is null terminated in bounds. join() ensures 167 * 'landmark' can not overflow prefix if too long. 168 */ 169 static int 170 gotlandmark(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. 182 * assumption provided by only caller, calculate_path() 183 */ 184 static int 185 search_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 198 static void 199 get_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 258 static void 259 calculate_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"); 266 char zip_path[MAXPATHLEN+1]; 267 size_t len; 268 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 285 /* 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 298 /* 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 */ 306 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; 321 bufsz += strlen(zip_path) + 1; 322 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 } 345 if (zip_path[0]) { 346 strcpy(buf, zip_path); 347 buf = strchr(buf, '\0'); 348 *buf++ = DELIM; 349 } 350 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 390 char * 391 Py_GetPath(void) 392 { 393 if (!module_search_path) 394 calculate_path(); 395 return module_search_path; 396 } 397 398 char * 399 Py_GetPrefix(void) 400 { 401 if (!module_search_path) 402 calculate_path(); 403 return prefix; 404 } 405 406 char * 407 Py_GetExecPrefix(void) 408 { 409 return Py_GetPrefix(); 410 } 411 412 char * 413 Py_GetProgramFullPath(void) 414 { 415 if (!module_search_path) 416 calculate_path(); 417 return progpath; 418 } 419