/*
* 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 */
}