|
27 | 27 | # define PyObject_CallNoArgs(_o) PyObject_CallObject((_o), NULL) |
28 | 28 | #endif |
29 | 29 |
|
30 | | -static PyObject *sudo_type_LogHandler; |
31 | | - |
32 | 30 | static void |
33 | 31 | _debug_plugin(int log_level, const char *log_message) |
34 | 32 | { |
@@ -127,74 +125,58 @@ static PyMethodDef _sudo_LogHandler_class_methods[] = |
127 | 125 | {NULL, NULL, 0, NULL} |
128 | 126 | }; |
129 | 127 |
|
130 | | -// This function registers sudo.LogHandler class |
| 128 | +// This function creates the sudo.LogHandler class and adds it |
| 129 | +// to the root logger. |
131 | 130 | int |
132 | | -sudo_module_register_loghandler(PyObject *py_module) |
| 131 | +sudo_module_set_default_loghandler() |
133 | 132 | { |
134 | 133 | debug_decl(sudo_module_register_loghandler, PYTHON_DEBUG_INTERNAL); |
135 | 134 |
|
136 | | - PyObject *py_logging_module = NULL, *py_streamhandler = NULL; |
| 135 | + PyObject *py_sudo, *py_logging_module = NULL, *py_logger = NULL, |
| 136 | + *py_streamhandler = NULL, *py_class = NULL, |
| 137 | + *py_loghandler = NULL, *py_result = NULL; |
| 138 | + |
| 139 | + py_sudo = PyImport_ImportModule("sudo"); |
| 140 | + if (py_sudo == NULL) |
| 141 | + goto cleanup; |
137 | 142 |
|
138 | 143 | py_logging_module = PyImport_ImportModule("logging"); |
139 | 144 | if (py_logging_module == NULL) |
140 | 145 | goto cleanup; |
141 | 146 |
|
| 147 | + // Get the root logger which all loggers descend from. |
| 148 | + py_logger = PyObject_CallMethod(py_logging_module, "getLogger", NULL); |
| 149 | + if (py_logger == NULL) |
| 150 | + goto cleanup; |
| 151 | + |
142 | 152 | py_streamhandler = PyObject_GetAttrString(py_logging_module, "StreamHandler"); |
143 | 153 | if (py_streamhandler == NULL) |
144 | 154 | goto cleanup; |
145 | 155 |
|
146 | | - sudo_type_LogHandler = sudo_module_create_class("sudo.LogHandler", |
| 156 | + // Create our own handler that is a sub-class of StreamHandler |
| 157 | + py_class = sudo_module_create_class("sudo.LogHandler", |
147 | 158 | _sudo_LogHandler_class_methods, py_streamhandler); |
148 | | - if (sudo_type_LogHandler == NULL) |
| 159 | + if (py_class == NULL) |
149 | 160 | goto cleanup; |
150 | 161 |
|
151 | | - if (PyModule_AddObject(py_module, "LogHandler", sudo_type_LogHandler) < 0) { |
152 | | - Py_CLEAR(sudo_type_LogHandler); |
| 162 | + // PyModule_AddObject steals a reference to py_class on success |
| 163 | + if (PyModule_AddObject(py_sudo, "LogHandler", py_class) < 0) |
153 | 164 | goto cleanup; |
154 | | - } |
155 | | - |
156 | | - // PyModule_AddObject steals a reference to sudo_type_LogHandler on success |
157 | | - Py_INCREF(sudo_type_LogHandler); |
158 | | - |
159 | | -cleanup: |
160 | | - Py_CLEAR(py_streamhandler); |
161 | | - Py_CLEAR(py_logging_module); |
162 | | - debug_return_int(PyErr_Occurred() ? SUDO_RC_ERROR : SUDO_RC_OK); |
163 | | -} |
164 | | - |
165 | | -// This sets sudo.LogHandler as the default log handler: |
166 | | -// logging.getLogger().addHandler(sudo.LogHandler()) |
167 | | -int |
168 | | -sudo_module_set_default_loghandler(void) |
169 | | -{ |
170 | | - debug_decl(sudo_module_set_default_loghandler, PYTHON_DEBUG_INTERNAL); |
| 165 | + Py_INCREF(py_class); |
171 | 166 |
|
172 | | - PyObject *py_loghandler = NULL, *py_logging_module = NULL, |
173 | | - *py_logger = NULL, *py_result = NULL; |
174 | | - |
175 | | - py_loghandler = PyObject_CallNoArgs(sudo_type_LogHandler); |
| 167 | + py_loghandler = PyObject_CallNoArgs(py_class); |
176 | 168 | if (py_loghandler == NULL) |
177 | 169 | goto cleanup; |
178 | 170 |
|
179 | | - py_logging_module = PyImport_ImportModule("logging"); |
180 | | - if (py_logging_module == NULL) |
181 | | - goto cleanup; |
182 | | - |
183 | | - py_logger = PyObject_CallMethod(py_logging_module, "getLogger", NULL); |
184 | | - if (py_logger == NULL) |
185 | | - goto cleanup; |
186 | | - |
187 | 171 | py_result = PyObject_CallMethod(py_logger, "addHandler", "O", py_loghandler); |
188 | 172 |
|
189 | 173 | cleanup: |
190 | 174 | Py_CLEAR(py_result); |
| 175 | + Py_CLEAR(py_loghandler); |
| 176 | + Py_CLEAR(py_class); |
| 177 | + Py_CLEAR(py_streamhandler); |
191 | 178 | Py_CLEAR(py_logger); |
192 | 179 | Py_CLEAR(py_logging_module); |
193 | | -#if 0 |
194 | | - // XXX - If we don't leak py_loghandler here we may get a crash in |
195 | | - // Py_EndInterpreter() on Python 3.12. |
196 | | - Py_CLEAR(py_loghandler); |
197 | | -#endif |
198 | | - |
| 180 | + Py_CLEAR(py_sudo); |
199 | 181 | debug_return_int(PyErr_Occurred() ? SUDO_RC_ERROR : SUDO_RC_OK); |
200 | 182 | } |
0 commit comments