diff options
Diffstat (limited to 'Modules/getpath.c')
-rw-r--r-- | Modules/getpath.c | 735 |
1 files changed, 363 insertions, 372 deletions
diff --git a/Modules/getpath.c b/Modules/getpath.c index 010fbaa..876bac0 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -139,13 +139,12 @@ static char *module_search_path = NULL; static char lib_python[20]; /* Dynamically set to "lib/python" VERSION */ static void -reduce(dir) - char *dir; +reduce(char *dir) { - size_t i = strlen(dir); - while (i > 0 && dir[i] != SEP) - --i; - dir[i] = '\0'; + size_t i = strlen(dir); + while (i > 0 && dir[i] != SEP) + --i; + dir[i] = '\0'; } @@ -158,239 +157,231 @@ reduce(dir) #endif static int -isfile(filename) /* Is file, not directory */ - char *filename; +isfile(char *filename) /* Is file, not directory */ { - struct stat buf; - if (stat(filename, &buf) != 0) - return 0; - if (!S_ISREG(buf.st_mode)) - return 0; - return 1; + struct stat buf; + if (stat(filename, &buf) != 0) + return 0; + if (!S_ISREG(buf.st_mode)) + return 0; + return 1; } static int -ismodule(filename) /* Is module -- check for .pyc/.pyo too */ - char *filename; +ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */ { - if (isfile(filename)) - return 1; - - /* Check for the compiled version of prefix. */ - if (strlen(filename) < MAXPATHLEN) { - strcat(filename, Py_OptimizeFlag ? "o" : "c"); - if (isfile(filename)) - return 1; - } - return 0; + if (isfile(filename)) + return 1; + + /* Check for the compiled version of prefix. */ + if (strlen(filename) < MAXPATHLEN) { + strcat(filename, Py_OptimizeFlag ? "o" : "c"); + if (isfile(filename)) + return 1; + } + return 0; } static int -isxfile(filename) /* Is executable file */ - char *filename; +isxfile(char *filename) /* Is executable file */ { - struct stat buf; - if (stat(filename, &buf) != 0) - return 0; - if (!S_ISREG(buf.st_mode)) - return 0; - if ((buf.st_mode & 0111) == 0) - return 0; - return 1; + struct stat buf; + if (stat(filename, &buf) != 0) + return 0; + if (!S_ISREG(buf.st_mode)) + return 0; + if ((buf.st_mode & 0111) == 0) + return 0; + return 1; } static int -isdir(filename) /* Is directory */ - char *filename; +isdir(char *filename) /* Is directory */ { - struct stat buf; - if (stat(filename, &buf) != 0) - return 0; - if (!S_ISDIR(buf.st_mode)) - return 0; - return 1; + struct stat buf; + if (stat(filename, &buf) != 0) + return 0; + if (!S_ISDIR(buf.st_mode)) + return 0; + return 1; } static void -joinpath(buffer, stuff) - char *buffer; - char *stuff; +joinpath(char *buffer, char *stuff) { - size_t n, k; - if (stuff[0] == SEP) - n = 0; - else { - n = strlen(buffer); - if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) - buffer[n++] = SEP; - } - k = strlen(stuff); - if (n + k > MAXPATHLEN) - k = MAXPATHLEN - n; - strncpy(buffer+n, stuff, k); - buffer[n+k] = '\0'; + size_t n, k; + if (stuff[0] == SEP) + n = 0; + else { + n = strlen(buffer); + if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN) + buffer[n++] = SEP; + } + k = strlen(stuff); + if (n + k > MAXPATHLEN) + k = MAXPATHLEN - n; + strncpy(buffer+n, stuff, k); + buffer[n+k] = '\0'; } static int -search_for_prefix(argv0_path, home) - char *argv0_path; - char *home; +search_for_prefix(char *argv0_path, char *home) { - size_t n; - char *vpath; - - /* If PYTHONHOME is set, we believe it unconditionally */ - if (home) { - char *delim; - strcpy(prefix, home); - delim = strchr(prefix, DELIM); - if (delim) - *delim = '\0'; - joinpath(prefix, lib_python); - joinpath(prefix, LANDMARK); - return 1; - } - - /* Check to see if argv[0] is in the build directory */ - strcpy(prefix, argv0_path); - joinpath(prefix, "Modules/Setup"); - if (isfile(prefix)) { - /* Check VPATH to see if argv0_path is in the build directory. - * Complication: the VPATH passed in is relative to the - * Modules build directory and points to the Modules source - * directory; we need it relative to the build tree and - * pointing to the source tree. Solution: chop off a leading - * ".." (but only if it's there -- it could be an absolute - * path) and chop off the final component (assuming it's - * "Modules"). - */ - vpath = VPATH; - if (vpath[0] == '.' && vpath[1] == '.' && vpath[2] == '/') - vpath += 3; - strcpy(prefix, argv0_path); - joinpath(prefix, vpath); - reduce(prefix); - joinpath(prefix, "Lib"); - joinpath(prefix, LANDMARK); - if (ismodule(prefix)) - return -1; - } - - /* Search from argv0_path, until root is found */ - strcpy(prefix, argv0_path); - do { - n = strlen(prefix); - joinpath(prefix, lib_python); - joinpath(prefix, LANDMARK); - if (ismodule(prefix)) - return 1; - prefix[n] = '\0'; - reduce(prefix); - } while (prefix[0]); - - /* Look at configure's PREFIX */ - strcpy(prefix, PREFIX); - joinpath(prefix, lib_python); - joinpath(prefix, LANDMARK); - if (ismodule(prefix)) - return 1; - - /* Fail */ - return 0; + size_t n; + char *vpath; + + /* If PYTHONHOME is set, we believe it unconditionally */ + if (home) { + char *delim; + strcpy(prefix, home); + delim = strchr(prefix, DELIM); + if (delim) + *delim = '\0'; + joinpath(prefix, lib_python); + joinpath(prefix, LANDMARK); + return 1; + } + + /* Check to see if argv[0] is in the build directory */ + strcpy(prefix, argv0_path); + joinpath(prefix, "Modules/Setup"); + if (isfile(prefix)) { + /* Check VPATH to see if argv0_path is in the build directory. + * Complication: the VPATH passed in is relative to the + * Modules build directory and points to the Modules source + * directory; we need it relative to the build tree and + * pointing to the source tree. Solution: chop off a leading + * ".." (but only if it's there -- it could be an absolute + * path) and chop off the final component (assuming it's + * "Modules"). + */ + vpath = VPATH; + if (vpath[0] == '.' && vpath[1] == '.' && vpath[2] == '/') + vpath += 3; + strcpy(prefix, argv0_path); + joinpath(prefix, vpath); + reduce(prefix); + joinpath(prefix, "Lib"); + joinpath(prefix, LANDMARK); + if (ismodule(prefix)) + return -1; + } + + /* Search from argv0_path, until root is found */ + strcpy(prefix, argv0_path); + do { + n = strlen(prefix); + joinpath(prefix, lib_python); + joinpath(prefix, LANDMARK); + if (ismodule(prefix)) + return 1; + prefix[n] = '\0'; + reduce(prefix); + } while (prefix[0]); + + /* Look at configure's PREFIX */ + strcpy(prefix, PREFIX); + joinpath(prefix, lib_python); + joinpath(prefix, LANDMARK); + if (ismodule(prefix)) + return 1; + + /* Fail */ + return 0; } static int -search_for_exec_prefix(argv0_path, home) - char *argv0_path; - char *home; +search_for_exec_prefix(char *argv0_path, char *home) { - size_t n; - - /* If PYTHONHOME is set, we believe it unconditionally */ - if (home) { - char *delim; - delim = strchr(home, DELIM); - if (delim) - strcpy(exec_prefix, delim+1); - else - strcpy(exec_prefix, home); - joinpath(exec_prefix, lib_python); - joinpath(exec_prefix, "lib-dynload"); - return 1; - } - - /* Check to see if argv[0] is in the build directory */ - strcpy(exec_prefix, argv0_path); - joinpath(exec_prefix, "Modules/Setup"); - if (isfile(exec_prefix)) { - reduce(exec_prefix); - return -1; - } - - /* Search from argv0_path, until root is found */ - strcpy(exec_prefix, argv0_path); - do { - n = strlen(exec_prefix); - joinpath(exec_prefix, lib_python); - joinpath(exec_prefix, "lib-dynload"); - if (isdir(exec_prefix)) - return 1; - exec_prefix[n] = '\0'; - reduce(exec_prefix); - } while (exec_prefix[0]); - - /* Look at configure's EXEC_PREFIX */ - strcpy(exec_prefix, EXEC_PREFIX); - joinpath(exec_prefix, lib_python); - joinpath(exec_prefix, "lib-dynload"); - if (isdir(exec_prefix)) - return 1; - - /* Fail */ - return 0; + size_t n; + + /* If PYTHONHOME is set, we believe it unconditionally */ + if (home) { + char *delim; + delim = strchr(home, DELIM); + if (delim) + strcpy(exec_prefix, delim+1); + else + strcpy(exec_prefix, home); + joinpath(exec_prefix, lib_python); + joinpath(exec_prefix, "lib-dynload"); + return 1; + } + + /* Check to see if argv[0] is in the build directory */ + strcpy(exec_prefix, argv0_path); + joinpath(exec_prefix, "Modules/Setup"); + if (isfile(exec_prefix)) { + reduce(exec_prefix); + return -1; + } + + /* Search from argv0_path, until root is found */ + strcpy(exec_prefix, argv0_path); + do { + n = strlen(exec_prefix); + joinpath(exec_prefix, lib_python); + joinpath(exec_prefix, "lib-dynload"); + if (isdir(exec_prefix)) + return 1; + exec_prefix[n] = '\0'; + reduce(exec_prefix); + } while (exec_prefix[0]); + + /* Look at configure's EXEC_PREFIX */ + strcpy(exec_prefix, EXEC_PREFIX); + joinpath(exec_prefix, lib_python); + joinpath(exec_prefix, "lib-dynload"); + if (isdir(exec_prefix)) + return 1; + + /* Fail */ + return 0; } static void calculate_path() { - extern char *Py_GetProgramName(); - - static char delimiter[2] = {DELIM, '\0'}; - static char separator[2] = {SEP, '\0'}; - char *pythonpath = PYTHONPATH; - char *rtpypath = getenv("PYTHONPATH"); - char *home = Py_GetPythonHome(); - char *path = getenv("PATH"); - char *prog = Py_GetProgramName(); - char argv0_path[MAXPATHLEN+1]; - int pfound, efound; /* 1 if found; -1 if found build directory */ - char *buf; - size_t bufsz; - size_t prefixsz; - char *defpath = pythonpath; + extern char *Py_GetProgramName(); + + static char delimiter[2] = {DELIM, '\0'}; + static char separator[2] = {SEP, '\0'}; + char *pythonpath = PYTHONPATH; + char *rtpypath = getenv("PYTHONPATH"); + char *home = Py_GetPythonHome(); + char *path = getenv("PATH"); + char *prog = Py_GetProgramName(); + char argv0_path[MAXPATHLEN+1]; + int pfound, efound; /* 1 if found; -1 if found build directory */ + char *buf; + size_t bufsz; + size_t prefixsz; + char *defpath = pythonpath; #ifdef WITH_NEXT_FRAMEWORK - NSModule pythonModule; + NSModule pythonModule; #endif #ifdef WITH_NEXT_FRAMEWORK - pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); - /* Use dylib functions to find out where the framework was loaded from */ - buf = NSLibraryNameForModule(pythonModule); - if (buf != NULL) { - /* We're in a framework. */ - strcpy(progpath, buf); - - /* Frameworks have support for versioning */ - strcpy(lib_python, "lib"); - } else { - /* If we're not in a framework, fall back to the old way (even though NSNameOfModule() probably does the same thing.) */ + pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); + /* Use dylib functions to find out where the framework was loaded from */ + buf = NSLibraryNameForModule(pythonModule); + if (buf != NULL) { + /* We're in a framework. */ + strcpy(progpath, buf); + + /* Frameworks have support for versioning */ + strcpy(lib_python, "lib"); + } + else { + /* If we're not in a framework, fall back to the old way + (even though NSNameOfModule() probably does the same thing.) */ #endif /* Initialize this dynamically for K&R C */ @@ -402,179 +393,179 @@ calculate_path() * $PATH isn't exported, you lose. */ if (strchr(prog, SEP)) - strcpy(progpath, prog); + strcpy(progpath, prog); else if (path) { - while (1) { - char *delim = strchr(path, DELIM); - - if (delim) { - size_t len = delim - path; - strncpy(progpath, path, len); - *(progpath + len) = '\0'; - } - else - strcpy(progpath, path); - - joinpath(progpath, prog); - if (isxfile(progpath)) - break; - - if (!delim) { - progpath[0] = '\0'; - break; - } - path = delim + 1; - } + while (1) { + char *delim = strchr(path, DELIM); + + if (delim) { + size_t len = delim - path; + strncpy(progpath, path, len); + *(progpath + len) = '\0'; + } + else + strcpy(progpath, path); + + joinpath(progpath, prog); + if (isxfile(progpath)) + break; + + if (!delim) { + progpath[0] = '\0'; + break; + } + path = delim + 1; + } } else - progpath[0] = '\0'; + progpath[0] = '\0'; #ifdef WITH_NEXT_FRAMEWORK - } + } #endif - strcpy(argv0_path, progpath); + strcpy(argv0_path, progpath); #if HAVE_READLINK - { - char tmpbuffer[MAXPATHLEN+1]; - int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN); - while (linklen != -1) { - /* It's not null terminated! */ - tmpbuffer[linklen] = '\0'; - if (tmpbuffer[0] == SEP) - strcpy(argv0_path, tmpbuffer); - else { - /* Interpret relative to progpath */ - reduce(argv0_path); - joinpath(argv0_path, tmpbuffer); - } - linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN); - } - } + { + char tmpbuffer[MAXPATHLEN+1]; + int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN); + while (linklen != -1) { + /* It's not null terminated! */ + tmpbuffer[linklen] = '\0'; + if (tmpbuffer[0] == SEP) + strcpy(argv0_path, tmpbuffer); + else { + /* Interpret relative to progpath */ + reduce(argv0_path); + joinpath(argv0_path, tmpbuffer); + } + linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN); + } + } #endif /* HAVE_READLINK */ - reduce(argv0_path); - - if (!(pfound = search_for_prefix(argv0_path, home))) { - if (!Py_FrozenFlag) - fprintf(stderr, - "Could not find platform independent libraries <prefix>\n"); - strcpy(prefix, PREFIX); - joinpath(prefix, lib_python); - } - else - reduce(prefix); + reduce(argv0_path); + + if (!(pfound = search_for_prefix(argv0_path, home))) { + if (!Py_FrozenFlag) + fprintf(stderr, + "Could not find platform independent libraries <prefix>\n"); + strcpy(prefix, PREFIX); + joinpath(prefix, lib_python); + } + else + reduce(prefix); - if (!(efound = search_for_exec_prefix(argv0_path, home))) { - if (!Py_FrozenFlag) - fprintf(stderr, - "Could not find platform dependent libraries <exec_prefix>\n"); - strcpy(exec_prefix, EXEC_PREFIX); - joinpath(exec_prefix, "lib/lib-dynload"); - } - /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ - - if ((!pfound || !efound) && !Py_FrozenFlag) - fprintf(stderr, - "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); - - /* Calculate size of return buffer. - */ - bufsz = 0; - - if (rtpypath) - bufsz += strlen(rtpypath) + 1; - - prefixsz = strlen(prefix) + 1; - - while (1) { - char *delim = strchr(defpath, DELIM); - - if (defpath[0] != SEP) - /* Paths are relative to prefix */ - bufsz += prefixsz; - - if (delim) - bufsz += delim - defpath + 1; - else { - bufsz += strlen(defpath) + 1; - break; - } - defpath = delim + 1; - } - - bufsz += strlen(exec_prefix) + 1; - - /* This is the only malloc call in this file */ - buf = PyMem_Malloc(bufsz); - - if (buf == NULL) { - /* We can't exit, so print a warning and limp along */ - fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); - fprintf(stderr, "Using default static PYTHONPATH.\n"); - module_search_path = PYTHONPATH; - } - else { - /* Run-time value of $PYTHONPATH goes first */ - if (rtpypath) { - strcpy(buf, rtpypath); - strcat(buf, delimiter); - } - else - buf[0] = '\0'; - - /* Next goes merge of compile-time $PYTHONPATH with - * dynamically located prefix. - */ - defpath = pythonpath; - while (1) { - char *delim = strchr(defpath, DELIM); - - if (defpath[0] != SEP) { - strcat(buf, prefix); - strcat(buf, separator); - } - - if (delim) { - size_t len = delim - defpath + 1; - size_t end = strlen(buf) + len; - strncat(buf, defpath, len); - *(buf + end) = '\0'; - } - else { - strcat(buf, defpath); - break; - } - defpath = delim + 1; - } - strcat(buf, delimiter); - - /* Finally, on goes the directory for dynamic-load modules */ - strcat(buf, exec_prefix); - - /* And publish the results */ - module_search_path = buf; - } - - /* Reduce prefix and exec_prefix to their essence, - * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. - * If we're loading relative to the build directory, - * return the compiled-in defaults instead. - */ - if (pfound > 0) { - reduce(prefix); - reduce(prefix); - } - else - strcpy(prefix, PREFIX); - - if (efound > 0) { - reduce(exec_prefix); - reduce(exec_prefix); - reduce(exec_prefix); - } - else - strcpy(exec_prefix, EXEC_PREFIX); + if (!(efound = search_for_exec_prefix(argv0_path, home))) { + if (!Py_FrozenFlag) + fprintf(stderr, + "Could not find platform dependent libraries <exec_prefix>\n"); + strcpy(exec_prefix, EXEC_PREFIX); + joinpath(exec_prefix, "lib/lib-dynload"); + } + /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ + + if ((!pfound || !efound) && !Py_FrozenFlag) + fprintf(stderr, + "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n"); + + /* Calculate size of return buffer. + */ + bufsz = 0; + + if (rtpypath) + bufsz += strlen(rtpypath) + 1; + + prefixsz = strlen(prefix) + 1; + + while (1) { + char *delim = strchr(defpath, DELIM); + + if (defpath[0] != SEP) + /* Paths are relative to prefix */ + bufsz += prefixsz; + + if (delim) + bufsz += delim - defpath + 1; + else { + bufsz += strlen(defpath) + 1; + break; + } + defpath = delim + 1; + } + + bufsz += strlen(exec_prefix) + 1; + + /* This is the only malloc call in this file */ + buf = PyMem_Malloc(bufsz); + + if (buf == NULL) { + /* We can't exit, so print a warning and limp along */ + fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n"); + fprintf(stderr, "Using default static PYTHONPATH.\n"); + module_search_path = PYTHONPATH; + } + else { + /* Run-time value of $PYTHONPATH goes first */ + if (rtpypath) { + strcpy(buf, rtpypath); + strcat(buf, delimiter); + } + else + buf[0] = '\0'; + + /* Next goes merge of compile-time $PYTHONPATH with + * dynamically located prefix. + */ + defpath = pythonpath; + while (1) { + char *delim = strchr(defpath, DELIM); + + if (defpath[0] != SEP) { + strcat(buf, prefix); + strcat(buf, separator); + } + + if (delim) { + size_t len = delim - defpath + 1; + size_t end = strlen(buf) + len; + strncat(buf, defpath, len); + *(buf + end) = '\0'; + } + else { + strcat(buf, defpath); + break; + } + defpath = delim + 1; + } + strcat(buf, delimiter); + + /* Finally, on goes the directory for dynamic-load modules */ + strcat(buf, exec_prefix); + + /* And publish the results */ + module_search_path = buf; + } + + /* Reduce prefix and exec_prefix to their essence, + * e.g. /usr/local/lib/python1.5 is reduced to /usr/local. + * If we're loading relative to the build directory, + * return the compiled-in defaults instead. + */ + if (pfound > 0) { + reduce(prefix); + reduce(prefix); + } + else + strcpy(prefix, PREFIX); + + if (efound > 0) { + reduce(exec_prefix); + reduce(exec_prefix); + reduce(exec_prefix); + } + else + strcpy(exec_prefix, EXEC_PREFIX); } @@ -583,31 +574,31 @@ calculate_path() char * Py_GetPath() { - if (!module_search_path) - calculate_path(); - return module_search_path; + if (!module_search_path) + calculate_path(); + return module_search_path; } char * Py_GetPrefix() { - if (!module_search_path) - calculate_path(); - return prefix; + if (!module_search_path) + calculate_path(); + return prefix; } char * Py_GetExecPrefix() { - if (!module_search_path) - calculate_path(); - return exec_prefix; + if (!module_search_path) + calculate_path(); + return exec_prefix; } char * Py_GetProgramFullPath() { - if (!module_search_path) - calculate_path(); - return progpath; + if (!module_search_path) + calculate_path(); + return progpath; } |