summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
Diffstat (limited to 'Python')
-rw-r--r--Python/initconfig.c15
-rw-r--r--Python/pylifecycle.c82
-rw-r--r--Python/stdlib_module_names.h1
3 files changed, 98 insertions, 0 deletions
diff --git a/Python/initconfig.c b/Python/initconfig.c
index 438f8a5..7851b86 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -168,6 +168,9 @@ static const PyConfigSpec PYCONFIG_SPEC[] = {
SPEC(tracemalloc, UINT, READ_ONLY, NO_SYS),
SPEC(use_frozen_modules, BOOL, READ_ONLY, NO_SYS),
SPEC(use_hash_seed, BOOL, READ_ONLY, NO_SYS),
+#ifdef __APPLE__
+ SPEC(use_system_logger, BOOL, PUBLIC, NO_SYS),
+#endif
SPEC(user_site_directory, BOOL, READ_ONLY, NO_SYS), // sys.flags.no_user_site
SPEC(warn_default_encoding, BOOL, READ_ONLY, NO_SYS),
@@ -884,6 +887,9 @@ config_check_consistency(const PyConfig *config)
assert(config->cpu_count != 0);
// config->use_frozen_modules is initialized later
// by _PyConfig_InitImportConfig().
+#ifdef __APPLE__
+ assert(config->use_system_logger >= 0);
+#endif
#ifdef Py_STATS
assert(config->_pystats >= 0);
#endif
@@ -986,6 +992,9 @@ _PyConfig_InitCompatConfig(PyConfig *config)
config->_is_python_build = 0;
config->code_debug_ranges = 1;
config->cpu_count = -1;
+#ifdef __APPLE__
+ config->use_system_logger = 0;
+#endif
#ifdef Py_GIL_DISABLED
config->enable_gil = _PyConfig_GIL_DEFAULT;
config->tlbc_enabled = 1;
@@ -1015,6 +1024,9 @@ config_init_defaults(PyConfig *config)
#ifdef MS_WINDOWS
config->legacy_windows_stdio = 0;
#endif
+#ifdef __APPLE__
+ config->use_system_logger = 0;
+#endif
}
@@ -1049,6 +1061,9 @@ PyConfig_InitIsolatedConfig(PyConfig *config)
#ifdef MS_WINDOWS
config->legacy_windows_stdio = 0;
#endif
+#ifdef __APPLE__
+ config->use_system_logger = 0;
+#endif
}
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index ceb30e9..0641812 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -45,7 +45,9 @@
#endif
#if defined(__APPLE__)
+# include <AvailabilityMacros.h>
# include <mach-o/loader.h>
+# include <os/log.h>
#endif
#ifdef HAVE_SIGNAL_H
@@ -75,6 +77,9 @@ static PyStatus init_sys_streams(PyThreadState *tstate);
#ifdef __ANDROID__
static PyStatus init_android_streams(PyThreadState *tstate);
#endif
+#if defined(__APPLE__)
+static PyStatus init_apple_streams(PyThreadState *tstate);
+#endif
static void wait_for_thread_shutdown(PyThreadState *tstate);
static void finalize_subinterpreters(void);
static void call_ll_exitfuncs(_PyRuntimeState *runtime);
@@ -1257,6 +1262,14 @@ init_interp_main(PyThreadState *tstate)
return status;
}
#endif
+#if defined(__APPLE__)
+ if (config->use_system_logger) {
+ status = init_apple_streams(tstate);
+ if (_PyStatus_EXCEPTION(status)) {
+ return status;
+ }
+ }
+#endif
#ifdef Py_DEBUG
run_presite(tstate);
@@ -2933,6 +2946,75 @@ done:
#endif // __ANDROID__
+#if defined(__APPLE__)
+
+static PyObject *
+apple_log_write_impl(PyObject *self, PyObject *args)
+{
+ int logtype = 0;
+ const char *text = NULL;
+ if (!PyArg_ParseTuple(args, "iy", &logtype, &text)) {
+ return NULL;
+ }
+
+ // Call the underlying Apple logging API. The os_log unified logging APIs
+ // were introduced in macOS 10.12, iOS 10.0, tvOS 10.0, and watchOS 3.0;
+ // this call is a no-op on older versions.
+ #if TARGET_OS_IPHONE || (TARGET_OS_OSX && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12)
+ // Pass the user-provided text through explicit %s formatting
+ // to avoid % literals being interpreted as a formatting directive.
+ os_log_with_type(OS_LOG_DEFAULT, logtype, "%s", text);
+ #endif
+ Py_RETURN_NONE;
+}
+
+
+static PyMethodDef apple_log_write_method = {
+ "apple_log_write", apple_log_write_impl, METH_VARARGS
+};
+
+
+static PyStatus
+init_apple_streams(PyThreadState *tstate)
+{
+ PyStatus status = _PyStatus_OK();
+ PyObject *_apple_support = NULL;
+ PyObject *apple_log_write = NULL;
+ PyObject *result = NULL;
+
+ _apple_support = PyImport_ImportModule("_apple_support");
+ if (_apple_support == NULL) {
+ goto error;
+ }
+
+ apple_log_write = PyCFunction_New(&apple_log_write_method, NULL);
+ if (apple_log_write == NULL) {
+ goto error;
+ }
+
+ // Initialize the logging streams, sending stdout -> Default; stderr -> Error
+ result = PyObject_CallMethod(
+ _apple_support, "init_streams", "Oii",
+ apple_log_write, OS_LOG_TYPE_DEFAULT, OS_LOG_TYPE_ERROR);
+ if (result == NULL) {
+ goto error;
+ }
+
+ goto done;
+
+error:
+ _PyErr_Print(tstate);
+ status = _PyStatus_ERR("failed to initialize Apple log streams");
+
+done:
+ Py_XDECREF(result);
+ Py_XDECREF(apple_log_write);
+ Py_XDECREF(_apple_support);
+ return status;
+}
+
+#endif // __APPLE__
+
static void
_Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp,
diff --git a/Python/stdlib_module_names.h b/Python/stdlib_module_names.h
index c8cdb93..584b050 100644
--- a/Python/stdlib_module_names.h
+++ b/Python/stdlib_module_names.h
@@ -6,6 +6,7 @@ static const char* _Py_stdlib_module_names[] = {
"_abc",
"_aix_support",
"_android_support",
+"_apple_support",
"_ast",
"_asyncio",
"_bisect",