@@ -39,7 +39,11 @@ All functions in this module take a file descriptor fd as their first\n\
3939argument. This can be an integer file descriptor, such as returned by\n\
4040sys.stdin.fileno(), or a file object, such as sys.stdin itself." );
4141
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))
4347
4448static int fdconv (PyObject * obj , void * p )
4549{
@@ -53,6 +57,8 @@ static int fdconv(PyObject* obj, void* p)
5357 return 0 ;
5458}
5559
60+ static struct PyModuleDef termiosmodule ;
61+
5662PyDoc_STRVAR (termios_tcgetattr__doc__ ,
5763"tcgetattr(fd) -> list_of_attrs\n\
5864\n\
@@ -80,7 +86,7 @@ termios_tcgetattr(PyObject *self, PyObject *args)
8086 return NULL ;
8187
8288 if (tcgetattr (fd , & mode ) == -1 )
83- return PyErr_SetFromErrno (TermiosError );
89+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
8490
8591 ispeed = cfgetispeed (& mode );
8692 ospeed = cfgetospeed (& mode );
@@ -160,8 +166,9 @@ termios_tcsetattr(PyObject *self, PyObject *args)
160166 }
161167
162168 /* Get the old mode, in case there are any hidden fields... */
169+ termiosmodulestate * state = modulestate_global ;
163170 if (tcgetattr (fd , & mode ) == -1 )
164- return PyErr_SetFromErrno (TermiosError );
171+ return PyErr_SetFromErrno (state -> TermiosError );
165172 mode .c_iflag = (tcflag_t ) PyLong_AsLong (PyList_GetItem (term , 0 ));
166173 mode .c_oflag = (tcflag_t ) PyLong_AsLong (PyList_GetItem (term , 1 ));
167174 mode .c_cflag = (tcflag_t ) PyLong_AsLong (PyList_GetItem (term , 2 ));
@@ -194,11 +201,11 @@ termios_tcsetattr(PyObject *self, PyObject *args)
194201 }
195202
196203 if (cfsetispeed (& mode , (speed_t ) ispeed ) == -1 )
197- return PyErr_SetFromErrno (TermiosError );
204+ return PyErr_SetFromErrno (state -> TermiosError );
198205 if (cfsetospeed (& mode , (speed_t ) ospeed ) == -1 )
199- return PyErr_SetFromErrno (TermiosError );
206+ return PyErr_SetFromErrno (state -> TermiosError );
200207 if (tcsetattr (fd , when , & mode ) == -1 )
201- return PyErr_SetFromErrno (TermiosError );
208+ return PyErr_SetFromErrno (state -> TermiosError );
202209
203210 Py_RETURN_NONE ;
204211}
@@ -219,7 +226,7 @@ termios_tcsendbreak(PyObject *self, PyObject *args)
219226 fdconv , & fd , & duration ))
220227 return NULL ;
221228 if (tcsendbreak (fd , duration ) == -1 )
222- return PyErr_SetFromErrno (TermiosError );
229+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
223230
224231 Py_RETURN_NONE ;
225232}
@@ -238,7 +245,7 @@ termios_tcdrain(PyObject *self, PyObject *args)
238245 fdconv , & fd ))
239246 return NULL ;
240247 if (tcdrain (fd ) == -1 )
241- return PyErr_SetFromErrno (TermiosError );
248+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
242249
243250 Py_RETURN_NONE ;
244251}
@@ -260,7 +267,7 @@ termios_tcflush(PyObject *self, PyObject *args)
260267 fdconv , & fd , & queue ))
261268 return NULL ;
262269 if (tcflush (fd , queue ) == -1 )
263- return PyErr_SetFromErrno (TermiosError );
270+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
264271
265272 Py_RETURN_NONE ;
266273}
@@ -282,7 +289,7 @@ termios_tcflow(PyObject *self, PyObject *args)
282289 fdconv , & fd , & action ))
283290 return NULL ;
284291 if (tcflow (fd , action ) == -1 )
285- return PyErr_SetFromErrno (TermiosError );
292+ return PyErr_SetFromErrno (modulestate_global -> TermiosError );
286293
287294 Py_RETURN_NONE ;
288295}
@@ -935,17 +942,30 @@ static struct constant {
935942 {NULL , 0 }
936943};
937944
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+ }
938958
939959static struct PyModuleDef termiosmodule = {
940960 PyModuleDef_HEAD_INIT ,
941961 "termios" ,
942962 termios__doc__ ,
943- -1 ,
963+ sizeof ( termiosmodulestate ) ,
944964 termios_methods ,
945965 NULL ,
946- NULL ,
947- NULL ,
948- NULL
966+ termiosmodule_traverse ,
967+ termiosmodule_clear ,
968+ termiosmodule_free ,
949969};
950970
951971PyMODINIT_FUNC
@@ -954,15 +974,22 @@ PyInit_termios(void)
954974 PyObject * m ;
955975 struct constant * constant = termios_constants ;
956976
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 ) {
959983 return NULL ;
984+ }
960985
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 ;
963990 }
964- Py_INCREF (TermiosError );
965- PyModule_AddObject (m , "error" , TermiosError );
991+ Py_INCREF (state -> TermiosError );
992+ PyModule_AddObject (m , "error" , state -> TermiosError );
966993
967994 while (constant -> name != NULL ) {
968995 PyModule_AddIntConstant (m , constant -> name , constant -> value );
0 commit comments