@@ -39,7 +39,11 @@ All functions in this module take a file descriptor fd as their first\n\
39
39
argument. This can be an integer file descriptor, such as returned by\n\
40
40
sys.stdin.fileno(), or a file object, such as sys.stdin itself." );
41
41
42
- static PyObject * TermiosError ;
42
+ typedef struct {
43
+ PyObject * TermiosError ;
44
+ } termiosmodulestate ;
45
+ #define modulestate (o ) ((termiosmodulestate *)PyModule_GetState(o))
46
+ #define modulestate_global modulestate(PyState_FindModule(&termiosmodule))
43
47
44
48
static int fdconv (PyObject * obj , void * p )
45
49
{
@@ -53,6 +57,8 @@ static int fdconv(PyObject* obj, void* p)
53
57
return 0 ;
54
58
}
55
59
60
+ static struct PyModuleDef termiosmodule ;
61
+
56
62
PyDoc_STRVAR (termios_tcgetattr__doc__ ,
57
63
"tcgetattr(fd) -> list_of_attrs\n\
58
64
\n\
@@ -80,7 +86,7 @@ termios_tcgetattr(PyObject *self, PyObject *args)
80
86
return NULL ;
81
87
82
88
if (tcgetattr (fd , & mode ) == -1 )
83
- return PyErr_SetFromErrno (TermiosError );
89
+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
84
90
85
91
ispeed = cfgetispeed (& mode );
86
92
ospeed = cfgetospeed (& mode );
@@ -160,8 +166,9 @@ termios_tcsetattr(PyObject *self, PyObject *args)
160
166
}
161
167
162
168
/* Get the old mode, in case there are any hidden fields... */
169
+ termiosmodulestate * state = modulestate_global ;
163
170
if (tcgetattr (fd , & mode ) == -1 )
164
- return PyErr_SetFromErrno (TermiosError );
171
+ return PyErr_SetFromErrno (state -> TermiosError );
165
172
mode .c_iflag = (tcflag_t ) PyLong_AsLong (PyList_GetItem (term , 0 ));
166
173
mode .c_oflag = (tcflag_t ) PyLong_AsLong (PyList_GetItem (term , 1 ));
167
174
mode .c_cflag = (tcflag_t ) PyLong_AsLong (PyList_GetItem (term , 2 ));
@@ -194,11 +201,11 @@ termios_tcsetattr(PyObject *self, PyObject *args)
194
201
}
195
202
196
203
if (cfsetispeed (& mode , (speed_t ) ispeed ) == -1 )
197
- return PyErr_SetFromErrno (TermiosError );
204
+ return PyErr_SetFromErrno (state -> TermiosError );
198
205
if (cfsetospeed (& mode , (speed_t ) ospeed ) == -1 )
199
- return PyErr_SetFromErrno (TermiosError );
206
+ return PyErr_SetFromErrno (state -> TermiosError );
200
207
if (tcsetattr (fd , when , & mode ) == -1 )
201
- return PyErr_SetFromErrno (TermiosError );
208
+ return PyErr_SetFromErrno (state -> TermiosError );
202
209
203
210
Py_RETURN_NONE ;
204
211
}
@@ -219,7 +226,7 @@ termios_tcsendbreak(PyObject *self, PyObject *args)
219
226
fdconv , & fd , & duration ))
220
227
return NULL ;
221
228
if (tcsendbreak (fd , duration ) == -1 )
222
- return PyErr_SetFromErrno (TermiosError );
229
+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
223
230
224
231
Py_RETURN_NONE ;
225
232
}
@@ -238,7 +245,7 @@ termios_tcdrain(PyObject *self, PyObject *args)
238
245
fdconv , & fd ))
239
246
return NULL ;
240
247
if (tcdrain (fd ) == -1 )
241
- return PyErr_SetFromErrno (TermiosError );
248
+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
242
249
243
250
Py_RETURN_NONE ;
244
251
}
@@ -260,7 +267,7 @@ termios_tcflush(PyObject *self, PyObject *args)
260
267
fdconv , & fd , & queue ))
261
268
return NULL ;
262
269
if (tcflush (fd , queue ) == -1 )
263
- return PyErr_SetFromErrno (TermiosError );
270
+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
264
271
265
272
Py_RETURN_NONE ;
266
273
}
@@ -282,7 +289,7 @@ termios_tcflow(PyObject *self, PyObject *args)
282
289
fdconv , & fd , & action ))
283
290
return NULL ;
284
291
if (tcflow (fd , action ) == -1 )
285
- return PyErr_SetFromErrno (TermiosError );
292
+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
286
293
287
294
Py_RETURN_NONE ;
288
295
}
@@ -935,17 +942,30 @@ static struct constant {
935
942
{NULL , 0 }
936
943
};
937
944
945
+ static int termiosmodule_traverse (PyObject * m , visitproc visit , void * arg ) {
946
+ Py_VISIT (modulestate (m )-> TermiosError );
947
+ return 0 ;
948
+ }
949
+
950
+ static int termiosmodule_clear (PyObject * m ) {
951
+ Py_CLEAR (modulestate (m )-> TermiosError );
952
+ return 0 ;
953
+ }
954
+
955
+ static void termiosmodule_free (void * m ) {
956
+ termiosmodule_clear ((PyObject * )m );
957
+ }
938
958
939
959
static struct PyModuleDef termiosmodule = {
940
960
PyModuleDef_HEAD_INIT ,
941
961
"termios" ,
942
962
termios__doc__ ,
943
- -1 ,
963
+ sizeof ( termiosmodulestate ) ,
944
964
termios_methods ,
945
965
NULL ,
946
- NULL ,
947
- NULL ,
948
- NULL
966
+ termiosmodule_traverse ,
967
+ termiosmodule_clear ,
968
+ termiosmodule_free ,
949
969
};
950
970
951
971
PyMODINIT_FUNC
@@ -954,15 +974,22 @@ PyInit_termios(void)
954
974
PyObject * m ;
955
975
struct constant * constant = termios_constants ;
956
976
957
- m = PyModule_Create (& termiosmodule );
958
- if (m == NULL )
977
+ if ((m = PyState_FindModule (& termiosmodule )) != NULL ) {
978
+ Py_INCREF (m );
979
+ return m ;
980
+ }
981
+
982
+ if ((m = PyModule_Create (& termiosmodule )) == NULL ) {
959
983
return NULL ;
984
+ }
960
985
961
- if (TermiosError == NULL ) {
962
- TermiosError = PyErr_NewException ("termios.error" , NULL , NULL );
986
+ termiosmodulestate * state = PyModule_GetState (m );
987
+ state -> TermiosError = PyErr_NewException ("termios.error" , NULL , NULL );
988
+ if (state -> TermiosError == NULL ) {
989
+ return NULL ;
963
990
}
964
- Py_INCREF (TermiosError );
965
- PyModule_AddObject (m , "error" , TermiosError );
991
+ Py_INCREF (state -> TermiosError );
992
+ PyModule_AddObject (m , "error" , state -> TermiosError );
966
993
967
994
while (constant -> name != NULL ) {
968
995
PyModule_AddIntConstant (m , constant -> name , constant -> value );
0 commit comments