lbry-android-sdk/recipes/python3crystax/interpreter.c.3.10
2021-08-21 13:24:58 +01:00

199 lines
5.5 KiB
Text

#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <string.h>
#include <dlfcn.h>
#include <wchar.h>
#include <locale.h>
#include <stdlib.h>
#define PYTHON3_STDLIB_REL_PATH "stdlib.zip"
#define PYTHON3_MODULES_REL_PATH "modules"
#define PYTHON3_DLL_REL_PATH "libpython3.10.so"
#define SYS_PATH_BUFFER_SIZE (2*(PATH_MAX + 1))
static char NULL_PTR_STR[] = "NULL";
static void GetExecutablePath(char* path)
{
int size = readlink("/proc/self/exe", path, PATH_MAX);
if (size < 0)
size = 0;
path[size] = 0;
}
static void GetRelativePathFormat(char* base, char* fmt)
{
unsigned idx;
char *p, *end;
end = strrchr(base, '/');
for (idx = 0, p = base; *p; ++p, ++idx)
{
fmt[idx] = *p;
if (p == end)
break;
}
fmt[++idx] = '%';
fmt[++idx] = 's';
fmt[++idx] = 0;
}
typedef void (*Py_SetProgramNamePtr)(wchar_t*);
typedef void (*Py_SetPathPtr)(const wchar_t*);
typedef int (*Py_MainPtr)(int, wchar_t**);
typedef void* (*PyMem_RawMallocPtr)(size_t);
typedef void (*PyMem_RawFreePtr)(void*);
typedef wchar_t* (*Py_DecodeLocalePtr)(const char*, size_t*);
int main(int argc, char** argv)
{
char executable[PATH_MAX + 1] = {0};
char pthfmt[PATH_MAX + 1] = {0};
char corepath[PATH_MAX + 1] = {0};
char stdlibpath[PATH_MAX + 1] = {0};
char modpath[PATH_MAX + 1] = {0};
char syspath[SYS_PATH_BUFFER_SIZE] = {0};
void* core = 0;
int retcode = 126;
int i;
Py_SetProgramNamePtr Py_SetProgramName = 0;
Py_SetPathPtr Py_SetPath = 0;
Py_MainPtr Py_Main = 0;
PyMem_RawMallocPtr PyMem_RawMalloc = 0;
PyMem_RawFreePtr PyMem_RawFree = 0;
Py_DecodeLocalePtr Py_DecodeLocale = 0;
GetExecutablePath(executable);
GetRelativePathFormat(executable, pthfmt);
snprintf(corepath, PATH_MAX, pthfmt, PYTHON3_DLL_REL_PATH);
snprintf(stdlibpath, PATH_MAX, pthfmt, PYTHON3_STDLIB_REL_PATH);
snprintf(modpath, PATH_MAX, pthfmt, PYTHON3_MODULES_REL_PATH);
snprintf(syspath, SYS_PATH_BUFFER_SIZE-1, "%s:%s", stdlibpath, modpath);
core = dlopen(corepath, RTLD_LAZY);
if (core == 0)
{
const char* lasterr = dlerror();
if (lasterr == 0)
lasterr = NULL_PTR_STR;
fprintf(stderr, "Fatal Python error: cannot load library: '%s', dlerror: %s\n", corepath, lasterr);
goto exit;
}
Py_SetProgramName = (Py_SetProgramNamePtr)dlsym(core, "Py_SetProgramName");
if (Py_SetProgramName == 0)
{
const char* lasterr = dlerror();
if (lasterr == 0)
lasterr = NULL_PTR_STR;
fprintf(stderr, "Fatal Python error: cannot load symbol: '%s' from library '%s', dlerror: %s\n", "Py_SetProgramName", corepath, lasterr);
goto exit;
}
Py_SetPath = (Py_SetPathPtr)dlsym(core, "Py_SetPath");
if (Py_SetPath == 0)
{
const char* lasterr = dlerror();
if (lasterr == 0)
lasterr = NULL_PTR_STR;
fprintf(stderr, "Fatal Python error: cannot load symbol: '%s' from library '%s', dlerror: %s\n", "Py_SetPath", corepath, lasterr);
goto exit;
}
Py_Main = (Py_MainPtr)dlsym(core, "Py_Main");
if (Py_Main == 0)
{
const char* lasterr = dlerror();
if (lasterr == 0)
lasterr = NULL_PTR_STR;
fprintf(stderr, "Fatal Python error: cannot load symbol: '%s' from library '%s', dlerror: %s\n", "Py_Main", corepath, lasterr);
goto exit;
}
PyMem_RawMalloc = (PyMem_RawMallocPtr)dlsym(core, "PyMem_RawMalloc");
if (PyMem_RawMalloc == 0)
{
const char* lasterr = dlerror();
if (lasterr == 0)
lasterr = NULL_PTR_STR;
fprintf(stderr, "Fatal Python error: cannot load symbol: '%s' from library '%s', dlerror: %s\n", "PyMem_RawMalloc", corepath, lasterr);
goto exit;
}
PyMem_RawFree = (PyMem_RawFreePtr)dlsym(core, "PyMem_RawFree");
if (PyMem_RawFree == 0)
{
const char* lasterr = dlerror();
if (lasterr == 0)
lasterr = NULL_PTR_STR;
fprintf(stderr, "Fatal Python error: cannot load symbol: '%s' from library '%s', dlerror: %s\n", "PyMem_RawFree", corepath, lasterr);
goto exit;
}
Py_DecodeLocale = (Py_DecodeLocalePtr)dlsym(core, "Py_DecodeLocale");
if (Py_DecodeLocale == 0)
{
const char* lasterr = dlerror();
if (lasterr == 0)
lasterr = NULL_PTR_STR;
fprintf(stderr, "Fatal Python error: cannot load symbol: '%s' from library '%s', dlerror: %s\n", "Py_DecodeLocale", corepath, lasterr);
goto exit;
}
wchar_t* executable_w = Py_DecodeLocale(executable, 0);
if (executable_w == 0)
{
fprintf(stderr, "Fatal Python error: unable to decode executable path: '%s'\n", executable);
goto exit;
}
wchar_t* syspath_w = Py_DecodeLocale(syspath, 0);
if (syspath_w == 0)
{
fprintf(stderr, "Fatal Python error: unable to decode syspath: '%s'\n", syspath);
goto exit;
}
wchar_t** argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*)*(argc+1));
wchar_t** argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*)*(argc+1));
char* oldloc = strdup(setlocale(LC_ALL, 0));
setlocale(LC_ALL, "");
for (i = 0; i < argc; ++i)
{
argv_copy[i] = Py_DecodeLocale(argv[i], 0);
if (argv_copy[i] == 0)
{
free(oldloc);
fprintf(stderr, "Fatal Python error: unable to decode the command line argument #%i\n", i + 1);
goto exit;
}
argv_copy2[i] = argv_copy[i];
}
argv_copy2[argc] = argv_copy[argc] = 0;
setlocale(LC_ALL, oldloc);
free(oldloc);
Py_SetProgramName(executable_w);
Py_SetPath(syspath_w);
retcode = Py_Main(argc, argv_copy);
PyMem_RawFree(executable_w);
PyMem_RawFree(syspath_w);
for (i = 0; i < argc; i++)
{
PyMem_RawFree(argv_copy2[i]);
}
PyMem_RawFree(argv_copy);
PyMem_RawFree(argv_copy2);
exit:
if (core != 0)
dlclose(core);
return retcode;
}