[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/pythoncapi/cpython/pythoncapi/Mac/Tools/pythonw.c [Back]  [Original]

/*
 * This wrapper program executes a python executable hidden inside an
 * application bundle inside the Python framework. This is needed to run
 * GUI code: some GUI API's don't work unless the program is inside an
 * application bundle.
 *
 * This program uses posix_spawn rather than plain execv because we need
 * slightly more control over how the "real" interpreter is executed.
 *
 * On OSX 10.4 (and earlier) this falls back to using exec because the
 * posix_spawnv functions aren't available there.
 */

#pragma weak_import posix_spawnattr_init
#pragma weak_import posix_spawnattr_setbinpref_np
#pragma weak_import posix_spawnattr_setflags
#pragma weak_import posix_spawn

#include 
#include 
#ifdef HAVE_SPAWN_H
#include 
#endif
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


extern char** environ;

/*
 * Locate the python framework by looking for the
 * library that contains Py_Initialize.
 *
 * In a regular framework the structure is:
 *
 *    Python.framework/Versions/2.7
 *              /Python
 *              /Resources/Python.app/Contents/MacOS/Python
 *
 * In a virtualenv style structure the expected
 * structure is:
 *
 *    ROOT
 *       /bin/pythonw
 *       /.Python    sizeof(real_path)) {
                errno = EINVAL;
                err(1, "realpath: %s", path);
            }

        } else {
            if (realpath(".", real_path) == NULL) {
                err(1, "realpath: %s", path);
            }
            if (strlcat(real_path, "/", sizeof(real_path)) > sizeof(real_path)) {
                errno = EINVAL;
                err(1, "realpath: %s", path);
            }
            if (strlcat(real_path, path, sizeof(real_path)) > sizeof(real_path)) {
                errno = EINVAL;
                err(1, "realpath: %s", path);
            }
        }

        setenv("__PYVENV_LAUNCHER__", real_path, 1);
    }

    /*
     * Let argv[0] refer to the new interpreter. This is needed to
     * get the effect we want on OSX 10.5 or earlier. That is, without
     * changing argv[0] the real interpreter won't have access to
     * the Window Server.
     */
    argv[0] = exec_path;

#ifdef HAVE_SPAWN_H
    /* We're weak-linking to posix-spawnv to ensure that
     * an executable build on 10.5 can work on 10.4.
     */
    if (posix_spawn != NULL) {
        posix_spawnattr_t spawnattr = NULL;

        setup_spawnattr(&spawnattr);
        posix_spawn(NULL, exec_path, NULL,
            &spawnattr, argv, environ);
        err(1, "posix_spawn: %s", exec_path);
    }
#endif
    execve(exec_path, argv, environ);
    err(1, "execve: %s", argv[0]);
    /* NOTREACHED */
}

Web Proxy Viewer  |  New URL  |  Original Page