@@ -61,10 +61,19 @@ module syslog
61
61
62
62
#include "clinic/syslogmodule.c.h"
63
63
64
- /* only one instance, only one syslog, so globals should be ok */
65
- static PyObject * S_ident_o = NULL ; /* identifier, held by openlog() */
66
- static char S_log_open = 0 ;
67
-
64
+ typedef struct {
65
+ /* only one instance, only one syslog, */
66
+ PyObject * S_ident_o ; /* identifier, held by openlog() */
67
+ char S_log_open ;
68
+ } _syslog_state ;
69
+
70
+ static inline _syslog_state *
71
+ get_syslog_state (PyObject * module )
72
+ {
73
+ void * state = PyModule_GetState (module );
74
+ assert (state != NULL );
75
+ return (_syslog_state * )state ;
76
+ }
68
77
69
78
static PyObject *
70
79
syslog_get_argv (void )
@@ -162,8 +171,9 @@ syslog_openlog_impl(PyObject *module, PyObject *ident, long logopt,
162
171
}
163
172
164
173
openlog (ident_str , logopt , facility );
165
- S_log_open = 1 ;
166
- Py_XSETREF (S_ident_o , ident );
174
+ _syslog_state * state = get_syslog_state (module );
175
+ state -> S_log_open = 1 ;
176
+ Py_XSETREF (state -> S_ident_o , ident );
167
177
168
178
Py_RETURN_NONE ;
169
179
}
@@ -193,8 +203,9 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int priority,
193
203
return NULL ;
194
204
}
195
205
206
+ _syslog_state * state = get_syslog_state (module );
196
207
/* if log is not opened, open it now */
197
- if (!S_log_open ) {
208
+ if (!state -> S_log_open ) {
198
209
PyObject * openlog_ret = syslog_openlog_impl (module , NULL , 0 , LOG_USER );
199
210
if (openlog_ret == NULL ) {
200
211
return NULL ;
@@ -205,7 +216,7 @@ syslog_syslog_impl(PyObject *module, int group_left_1, int priority,
205
216
/* Incref ident, because it can be decrefed if syslog.openlog() is
206
217
* called when the GIL is released.
207
218
*/
208
- PyObject * ident = S_ident_o ;
219
+ PyObject * ident = state -> S_ident_o ;
209
220
Py_XINCREF (ident );
210
221
#ifdef __APPLE__
211
222
// gh-98178: On macOS, libc syslog() is not thread-safe
@@ -233,10 +244,12 @@ syslog_closelog_impl(PyObject *module)
233
244
if (PySys_Audit ("syslog.closelog" , NULL ) < 0 ) {
234
245
return NULL ;
235
246
}
236
- if (S_log_open ) {
247
+
248
+ _syslog_state * state = get_syslog_state (module );
249
+ if (state -> S_log_open ) {
237
250
closelog ();
238
- Py_CLEAR (S_ident_o );
239
- S_log_open = 0 ;
251
+ Py_CLEAR (state -> S_ident_o );
252
+ state -> S_log_open = 0 ;
240
253
}
241
254
Py_RETURN_NONE ;
242
255
}
@@ -315,6 +328,11 @@ syslog_exec(PyObject *module)
315
328
return -1; \
316
329
} \
317
330
} while (0)
331
+
332
+ _syslog_state * state = get_syslog_state (module );
333
+ state -> S_ident_o = NULL ;
334
+ state -> S_log_open = 0 ;
335
+
318
336
/* Priorities */
319
337
ADD_INT_MACRO (module , LOG_EMERG );
320
338
ADD_INT_MACRO (module , LOG_ALERT );
@@ -380,6 +398,29 @@ syslog_exec(PyObject *module)
380
398
return 0 ;
381
399
}
382
400
401
+ static int
402
+ _syslog_traverse (PyObject * module , visitproc visit , void * arg )
403
+ {
404
+ _syslog_state * state = get_syslog_state (module );
405
+ Py_VISIT (state -> S_ident_o );
406
+ return 0 ;
407
+ }
408
+
409
+ static int
410
+ _syslog_clear (PyObject * module )
411
+ {
412
+ _syslog_state * state = get_syslog_state (module );
413
+ Py_CLEAR (state -> S_ident_o );
414
+ state -> S_log_open = 0 ;
415
+ return 0 ;
416
+ }
417
+
418
+ static void
419
+ _syslog_free (void * module )
420
+ {
421
+ _syslog_clear ((PyObject * )module );
422
+ }
423
+
383
424
static PyModuleDef_Slot syslog_slots [] = {
384
425
{Py_mod_exec , syslog_exec },
385
426
{0 , NULL }
@@ -390,9 +431,12 @@ static PyModuleDef_Slot syslog_slots[] = {
390
431
static struct PyModuleDef syslogmodule = {
391
432
PyModuleDef_HEAD_INIT ,
392
433
.m_name = "syslog" ,
393
- .m_size = 0 ,
434
+ .m_size = sizeof ( _syslog_state ) ,
394
435
.m_methods = syslog_methods ,
395
436
.m_slots = syslog_slots ,
437
+ .m_traverse = _syslog_traverse ,
438
+ .m_clear = _syslog_clear ,
439
+ .m_free = _syslog_free ,
396
440
};
397
441
398
442
PyMODINIT_FUNC
0 commit comments