mirror of
https://github.com/python/cpython.git
synced 2025-08-22 09:45:06 +00:00
gh-116622: Redirect stdout and stderr to system log when embedded in an Android app (#118063)
This commit is contained in:
parent
11f8348d78
commit
3b268f4edc
7 changed files with 511 additions and 0 deletions
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue