diff options
author | Malcolm Smith <smith@chaquo.com> | 2024-04-30 14:00:31 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-30 14:00:31 (GMT) |
commit | 3b268f4edc02b22257d745363b5cae199b6e5720 (patch) | |
tree | 6a485b90d723817ae9a16b4bad5995f77698a364 /Python | |
parent | 11f8348d78c22f85694d7a424541b34d6054a8ee (diff) | |
download | cpython-3b268f4edc02b22257d745363b5cae199b6e5720.zip cpython-3b268f4edc02b22257d745363b5cae199b6e5720.tar.gz cpython-3b268f4edc02b22257d745363b5cae199b6e5720.tar.bz2 |
gh-116622: Redirect stdout and stderr to system log when embedded in an Android app (#118063)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/pylifecycle.c | 77 | ||||
-rw-r--r-- | Python/stdlib_module_names.h | 1 |
2 files changed, 78 insertions, 0 deletions
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 0f3ca4a..a672d8c 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -71,6 +71,9 @@ static PyStatus add_main_module(PyInterpreterState *interp); static PyStatus init_import_site(void); static PyStatus init_set_builtins_open(void); static PyStatus init_sys_streams(PyThreadState *tstate); +#ifdef __ANDROID__ +static PyStatus init_android_streams(PyThreadState *tstate); +#endif static void wait_for_thread_shutdown(PyThreadState *tstate); static void call_ll_exitfuncs(_PyRuntimeState *runtime); @@ -1223,6 +1226,13 @@ init_interp_main(PyThreadState *tstate) return status; } +#ifdef __ANDROID__ + status = init_android_streams(tstate); + if (_PyStatus_EXCEPTION(status)) { + return status; + } +#endif + #ifdef Py_DEBUG run_presite(tstate); #endif @@ -2719,6 +2729,73 @@ done: } +#ifdef __ANDROID__ +#include <android/log.h> + +static PyObject * +android_log_write_impl(PyObject *self, PyObject *args) +{ + int prio = 0; + const char *tag = NULL; + const char *text = NULL; + if (!PyArg_ParseTuple(args, "isy", &prio, &tag, &text)) { + return NULL; + } + + // Despite its name, this function is part of the public API + // (https://developer.android.com/ndk/reference/group/logging). + __android_log_write(prio, tag, text); + Py_RETURN_NONE; +} + + +static PyMethodDef android_log_write_method = { + "android_log_write", android_log_write_impl, METH_VARARGS +}; + + +static PyStatus +init_android_streams(PyThreadState *tstate) +{ + PyStatus status = _PyStatus_OK(); + PyObject *_android_support = NULL; + PyObject *android_log_write = NULL; + PyObject *result = NULL; + + _android_support = PyImport_ImportModule("_android_support"); + if (_android_support == NULL) { + goto error; + } + + android_log_write = PyCFunction_New(&android_log_write_method, NULL); + if (android_log_write == NULL) { + goto error; + } + + // These log priorities match those used by Java's System.out and System.err. + result = PyObject_CallMethod( + _android_support, "init_streams", "Oii", + android_log_write, ANDROID_LOG_INFO, ANDROID_LOG_WARN); + if (result == NULL) { + goto error; + } + + goto done; + +error: + _PyErr_Print(tstate); + status = _PyStatus_ERR("failed to initialize Android streams"); + +done: + Py_XDECREF(result); + Py_XDECREF(android_log_write); + Py_XDECREF(_android_support); + return status; +} + +#endif // __ANDROID__ + + static void _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, PyThreadState *tstate) diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h index 08a66f4..f44abf1 100644 --- a/Python/stdlib_module_names.h +++ b/Python/stdlib_module_names.h @@ -5,6 +5,7 @@ static const char* _Py_stdlib_module_names[] = { "__future__", "_abc", "_aix_support", +"_android_support", "_ast", "_asyncio", "_bisect", |