예제 #1
0
파일: getpath.c 프로젝트: DinoV/cpython
static _PyInitError
calculate_path_impl(const _PyCoreConfig *core_config,
                    PyCalculatePath *calculate, _PyPathConfig *config)
{
    _PyInitError err;

    err = calculate_program_full_path(core_config, calculate, config);
    if (_Py_INIT_FAILED(err)) {
        return err;
    }

    err = calculate_argv0_path(calculate, config->program_full_path);
    if (_Py_INIT_FAILED(err)) {
        return err;
    }

    calculate_read_pyenv(calculate);

    wchar_t prefix[MAXPATHLEN+1];
    memset(prefix, 0, sizeof(prefix));
    calculate_prefix(core_config, calculate, prefix);

    calculate_zip_path(calculate, prefix);

    wchar_t exec_prefix[MAXPATHLEN+1];
    memset(exec_prefix, 0, sizeof(exec_prefix));
    calculate_exec_prefix(core_config, calculate, exec_prefix);

    if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
        !core_config->_frozen)
    {
        fprintf(stderr,
                "Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");
    }

    err = calculate_module_search_path(core_config, calculate,
                                       prefix, exec_prefix, config);
    if (_Py_INIT_FAILED(err)) {
        return err;
    }

    calculate_reduce_prefix(calculate, prefix);

    config->prefix = _PyMem_RawWcsdup(prefix);
    if (config->prefix == NULL) {
        return _Py_INIT_NO_MEMORY();
    }

    calculate_reduce_exec_prefix(calculate, exec_prefix);

    config->exec_prefix = _PyMem_RawWcsdup(exec_prefix);
    if (config->exec_prefix == NULL) {
        return _Py_INIT_NO_MEMORY();
    }

    return _Py_INIT_OK();
}
예제 #2
0
static _PyInitError canonicalize(wchar_t *buffer, const wchar_t *path)
{
    if (buffer == NULL) {
        return _Py_INIT_NO_MEMORY();
    }

    if (_PathCchCanonicalizeEx_Initialized == 0) {
        HMODULE pathapi = LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll");
        if (pathapi) {
            _PathCchCanonicalizeEx = (PPathCchCanonicalizeEx)GetProcAddress(pathapi, "PathCchCanonicalizeEx");
        }
        else {
            _PathCchCanonicalizeEx = NULL;
        }
        _PathCchCanonicalizeEx_Initialized = 1;
    }

    if (_PathCchCanonicalizeEx) {
        if (FAILED(_PathCchCanonicalizeEx(buffer, MAXPATHLEN + 1, path, 0))) {
            return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()");
        }
    }
    else {
        if (!PathCanonicalizeW(buffer, path)) {
            return _Py_INIT_ERR("buffer overflow in getpathp.c's canonicalize()");
        }
    }
    return _Py_INIT_OK();
}
예제 #3
0
/* Set the global path configuration from core_config. */
_PyInitError
_PyCoreConfig_SetPathConfig(const _PyCoreConfig *core_config)
{
    PyMemAllocatorEx old_alloc;
    _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

    _PyInitError err;
    _PyPathConfig path_config = _PyPathConfig_INIT;

    path_config.module_search_path = wstrlist_join(DELIM,
                                                   core_config->nmodule_search_path,
                                                   core_config->module_search_paths);
    if (path_config.module_search_path == NULL) {
        goto no_memory;
    }

    if (copy_wstr(&path_config.program_full_path, core_config->executable) < 0) {
        goto no_memory;
    }
    if (copy_wstr(&path_config.prefix, core_config->prefix) < 0) {
        goto no_memory;
    }
#ifdef MS_WINDOWS
    if (copy_wstr(&path_config.dll_path, core_config->dll_path) < 0) {
        goto no_memory;
    }
#else
    if (copy_wstr(&path_config.exec_prefix, core_config->exec_prefix) < 0) {
        goto no_memory;
    }
#endif
    if (copy_wstr(&path_config.program_name, core_config->program_name) < 0) {
        goto no_memory;
    }
    if (copy_wstr(&path_config.home, core_config->home) < 0) {
        goto no_memory;
    }

    err = _PyPathConfig_SetGlobal(&path_config);
    if (_Py_INIT_FAILED(err)) {
        goto done;
    }

    err = _Py_INIT_OK();
    goto done;

no_memory:
    err = _Py_INIT_NO_MEMORY();

done:
    _PyPathConfig_Clear(&path_config);
    PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    return err;
}
예제 #4
0
/* Calculate the path configuration: initialize path_config from core_config */
static _PyInitError
_PyPathConfig_Calculate(_PyPathConfig *path_config,
                        const _PyCoreConfig *core_config)
{
    _PyInitError err;
    _PyPathConfig new_config = _PyPathConfig_INIT;

    PyMemAllocatorEx old_alloc;
    _PyMem_SetDefaultAllocator(PYMEM_DOMAIN_RAW, &old_alloc);

    /* Calculate program_full_path, prefix, exec_prefix (Unix)
       or dll_path (Windows), and module_search_path */
    err = _PyPathConfig_Calculate_impl(&new_config, core_config);
    if (_Py_INIT_FAILED(err)) {
        goto err;
    }

    /* Copy home and program_name from core_config */
    if (copy_wstr(&new_config.home, core_config->home) < 0) {
        err = _Py_INIT_NO_MEMORY();
        goto err;
    }
    if (copy_wstr(&new_config.program_name, core_config->program_name) < 0) {
        err = _Py_INIT_NO_MEMORY();
        goto err;
    }

    _PyPathConfig_Clear(path_config);
    *path_config = new_config;

    err = _Py_INIT_OK();
    goto done;

err:
    _PyPathConfig_Clear(&new_config);

done:
    PyMem_SetAllocator(PYMEM_DOMAIN_RAW, &old_alloc);
    return err;
}
예제 #5
0
static _PyInitError
calculate_path_impl(const _PyCoreConfig *core_config,
                    PyCalculatePath *calculate, _PyPathConfig *config)
{
    _PyInitError err;

    err = get_dll_path(calculate, config);
    if (_Py_INIT_FAILED(err)) {
        return err;
    }

    err = get_program_full_path(core_config, calculate, config);
    if (_Py_INIT_FAILED(err)) {
        return err;
    }

    /* program_full_path guaranteed \0 terminated in MAXPATH+1 bytes. */
    wcscpy_s(calculate->argv0_path, MAXPATHLEN+1, config->program_full_path);
    reduce(calculate->argv0_path);

    wchar_t prefix[MAXPATHLEN+1];
    memset(prefix, 0, sizeof(prefix));

    /* Search for a sys.path file */
    if (calculate_pth_file(config, prefix)) {
        goto done;
    }

    calculate_pyvenv_file(calculate);

    /* Calculate zip archive path from DLL or exe path */
    change_ext(calculate->zip_path,
               config->dll_path[0] ? config->dll_path : config->program_full_path,
               L".zip");

    calculate_home_prefix(calculate, prefix);

    err = calculate_module_search_path(core_config, calculate, config, prefix);
    if (_Py_INIT_FAILED(err)) {
        return err;
    }

done:
    config->prefix = _PyMem_RawWcsdup(prefix);
    if (config->prefix == NULL) {
        return _Py_INIT_NO_MEMORY();
    }

    return _Py_INIT_OK();
}
예제 #6
0
static _PyInitError
core_config_init_module_search_paths(_PyCoreConfig *config,
                                     _PyPathConfig *path_config)
{
    assert(config->module_search_paths == NULL);
    assert(config->nmodule_search_path < 0);

    config->nmodule_search_path = 0;

    const wchar_t *sys_path = path_config->module_search_path;
    const wchar_t delim = DELIM;
    const wchar_t *p = sys_path;
    while (1) {
        p = wcschr(sys_path, delim);
        if (p == NULL) {
            p = sys_path + wcslen(sys_path); /* End of string */
        }

        size_t path_len = (p - sys_path);
        wchar_t *path = PyMem_RawMalloc((path_len + 1) * sizeof(wchar_t));
        if (path == NULL) {
            return _Py_INIT_NO_MEMORY();
        }
        memcpy(path, sys_path, path_len * sizeof(wchar_t));
        path[path_len] = L'\0';

        _PyInitError err = _Py_wstrlist_append(&config->nmodule_search_path,
                                               &config->module_search_paths,
                                               path);
        PyMem_RawFree(path);
        if (_Py_INIT_FAILED(err)) {
            return err;
        }

        if (*p == '\0') {
            break;
        }
        sys_path = p + 1;
    }
    return _Py_INIT_OK();
}
예제 #7
0
static _PyInitError
get_dll_path(PyCalculatePath *calculate, _PyPathConfig *config)
{
    wchar_t dll_path[MAXPATHLEN+1];
    memset(dll_path, 0, sizeof(dll_path));

#ifdef Py_ENABLE_SHARED
    extern HANDLE PyWin_DLLhModule;
    if (PyWin_DLLhModule) {
        if (!GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
            dll_path[0] = 0;
        }
    }
#else
    dll_path[0] = 0;
#endif

    config->dll_path = _PyMem_RawWcsdup(dll_path);
    if (config->dll_path == NULL) {
        return _Py_INIT_NO_MEMORY();
    }
    return _Py_INIT_OK();
}
예제 #8
0
파일: getpath.c 프로젝트: DinoV/cpython
static _PyInitError
calculate_module_search_path(const _PyCoreConfig *core_config,
                             PyCalculatePath *calculate,
                             const wchar_t *prefix, const wchar_t *exec_prefix,
                             _PyPathConfig *config)
{
    /* Calculate size of return buffer */
    size_t bufsz = 0;
    if (core_config->module_search_path_env != NULL) {
        bufsz += wcslen(core_config->module_search_path_env) + 1;
    }

    wchar_t *defpath = calculate->pythonpath;
    size_t prefixsz = wcslen(prefix) + 1;
    while (1) {
        wchar_t *delim = wcschr(defpath, DELIM);

        if (defpath[0] != SEP) {
            /* Paths are relative to prefix */
            bufsz += prefixsz;
        }

        if (delim) {
            bufsz += delim - defpath + 1;
        }
        else {
            bufsz += wcslen(defpath) + 1;
            break;
        }
        defpath = delim + 1;
    }

    bufsz += wcslen(calculate->zip_path) + 1;
    bufsz += wcslen(exec_prefix) + 1;

    /* Allocate the buffer */
    wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
    if (buf == NULL) {
        return _Py_INIT_NO_MEMORY();
    }
    buf[0] = '\0';

    /* Run-time value of $PYTHONPATH goes first */
    if (core_config->module_search_path_env) {
        wcscpy(buf, core_config->module_search_path_env);
        wcscat(buf, delimiter);
    }

    /* Next is the default zip path */
    wcscat(buf, calculate->zip_path);
    wcscat(buf, delimiter);

    /* Next goes merge of compile-time $PYTHONPATH with
     * dynamically located prefix.
     */
    defpath = calculate->pythonpath;
    while (1) {
        wchar_t *delim = wcschr(defpath, DELIM);

        if (defpath[0] != SEP) {
            wcscat(buf, prefix);
            if (prefixsz >= 2 && prefix[prefixsz - 2] != SEP &&
                defpath[0] != (delim ? DELIM : L'\0'))
            {
                /* not empty */
                wcscat(buf, separator);
            }
        }

        if (delim) {
            size_t len = delim - defpath + 1;
            size_t end = wcslen(buf) + len;
            wcsncat(buf, defpath, len);
            buf[end] = '\0';
        }
        else {
            wcscat(buf, defpath);
            break;
        }
        defpath = delim + 1;
    }
    wcscat(buf, delimiter);

    /* Finally, on goes the directory for dynamic-load modules */
    wcscat(buf, exec_prefix);

    config->module_search_path = buf;
    return _Py_INIT_OK();
}
예제 #9
0
파일: getpath.c 프로젝트: DinoV/cpython
static _PyInitError
calculate_program_full_path(const _PyCoreConfig *core_config,
                            PyCalculatePath *calculate, _PyPathConfig *config)
{
    wchar_t program_full_path[MAXPATHLEN+1];
    memset(program_full_path, 0, sizeof(program_full_path));

#ifdef __APPLE__
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
    uint32_t nsexeclength = MAXPATHLEN;
#else
    unsigned long nsexeclength = MAXPATHLEN;
#endif
    char execpath[MAXPATHLEN+1];
#endif

    /* If there is no slash in the argv0 path, then we have to
     * assume python is on the user's $PATH, since there's no
     * other way to find a directory to start the search from.  If
     * $PATH isn't exported, you lose.
     */
    if (wcschr(core_config->program_name, SEP)) {
        wcsncpy(program_full_path, core_config->program_name, MAXPATHLEN);
    }
#ifdef __APPLE__
     /* On Mac OS X, if a script uses an interpreter of the form
      * "#!/opt/python2.3/bin/python", the kernel only passes "python"
      * as argv[0], which falls through to the $PATH search below.
      * If /opt/python2.3/bin isn't in your path, or is near the end,
      * this algorithm may incorrectly find /usr/bin/python. To work
      * around this, we can use _NSGetExecutablePath to get a better
      * hint of what the intended interpreter was, although this
      * will fail if a relative path was used. but in that case,
      * absolutize() should help us out below
      */
    else if(0 == _NSGetExecutablePath(execpath, &nsexeclength) &&
            execpath[0] == SEP)
    {
        size_t len;
        wchar_t *path = Py_DecodeLocale(execpath, &len);
        if (path == NULL) {
            return DECODE_LOCALE_ERR("executable path", len);
        }
        wcsncpy(program_full_path, path, MAXPATHLEN);
        PyMem_RawFree(path);
    }
#endif /* __APPLE__ */
    else if (calculate->path_env) {
        wchar_t *path = calculate->path_env;
        while (1) {
            wchar_t *delim = wcschr(path, DELIM);

            if (delim) {
                size_t len = delim - path;
                if (len > MAXPATHLEN) {
                    len = MAXPATHLEN;
                }
                wcsncpy(program_full_path, path, len);
                program_full_path[len] = '\0';
            }
            else {
                wcsncpy(program_full_path, path, MAXPATHLEN);
            }

            joinpath(program_full_path, core_config->program_name);
            if (isxfile(program_full_path)) {
                break;
            }

            if (!delim) {
                program_full_path[0] = L'\0';
                break;
            }
            path = delim + 1;
        }
    }
    else {
        program_full_path[0] = '\0';
    }
    if (program_full_path[0] != SEP && program_full_path[0] != '\0') {
        absolutize(program_full_path);
    }

    config->program_full_path = _PyMem_RawWcsdup(program_full_path);
    if (config->program_full_path == NULL) {
        return _Py_INIT_NO_MEMORY();
    }
    return _Py_INIT_OK();
}
예제 #10
0
_PyInitError
_PyCoreConfig_InitPathConfig(_PyCoreConfig *config)
{
    _PyPathConfig path_config = _PyPathConfig_INIT;
    _PyInitError err;

    err = _PyPathConfig_Calculate(&path_config, config);
    if (_Py_INIT_FAILED(err)) {
        goto error;
    }

    if (config->nmodule_search_path < 0) {
        err = core_config_init_module_search_paths(config, &path_config);
        if (_Py_INIT_FAILED(err)) {
            goto error;
        }
    }

    if (config->executable == NULL) {
        if (copy_wstr(&config->executable,
                      path_config.program_full_path) < 0) {
            goto no_memory;
        }
    }

    if (config->prefix == NULL) {
        if (copy_wstr(&config->prefix, path_config.prefix) < 0) {
            goto no_memory;
        }
    }

    if (config->exec_prefix == NULL) {
#ifdef MS_WINDOWS
        wchar_t *exec_prefix = path_config.prefix;
#else
        wchar_t *exec_prefix = path_config.exec_prefix;
#endif
        if (copy_wstr(&config->exec_prefix, exec_prefix) < 0) {
            goto no_memory;
        }
    }

#ifdef MS_WINDOWS
    if (config->dll_path == NULL) {
        if (copy_wstr(&config->dll_path, path_config.dll_path) < 0) {
            goto no_memory;
        }
    }
#endif

    if (config->base_prefix == NULL) {
        if (copy_wstr(&config->base_prefix, config->prefix) < 0) {
            goto no_memory;
        }
    }

    if (config->base_exec_prefix == NULL) {
        if (copy_wstr(&config->base_exec_prefix, config->exec_prefix) < 0) {
            goto no_memory;
        }
    }

    if (path_config.isolated != -1) {
        config->isolated = path_config.isolated;
    }
    if (path_config.site_import != -1) {
        config->site_import = path_config.site_import;
    }

    _PyPathConfig_Clear(&path_config);
    return _Py_INIT_OK();

no_memory:
    err = _Py_INIT_NO_MEMORY();

error:
    _PyPathConfig_Clear(&path_config);
    return err;
}