summaryrefslogtreecommitdiffstats
path: root/Modules/termios.c
diff options
context:
space:
mode:
authorDino Viehland <dinoviehland@gmail.com>2019-09-10 10:33:30 (GMT)
committerT. Wouters <thomas@python.org>2019-09-10 10:33:30 (GMT)
commitbd0c7a12d9e28ce74bfc16244d7694aca906838c (patch)
tree4e8fd449814d8fed68590c7aac2f48b399289a32 /Modules/termios.c
parent40a5313edfc18173d136bb5e19495880934b7d83 (diff)
downloadcpython-bd0c7a12d9e28ce74bfc16244d7694aca906838c.zip
cpython-bd0c7a12d9e28ce74bfc16244d7694aca906838c.tar.gz
cpython-bd0c7a12d9e28ce74bfc16244d7694aca906838c.tar.bz2
bpo-38071: Make termios PEP-384 compatible (GH-15785)
Make the termios module PEP-384 compatible.
Diffstat (limited to 'Modules/termios.c')
-rw-r--r--Modules/termios.c67
1 files changed, 47 insertions, 20 deletions
diff --git a/Modules/termios.c b/Modules/termios.c
index aee7f12..b3b8c72 100644
--- a/Modules/termios.c
+++ b/Modules/termios.c
@@ -39,7 +39,11 @@ All functions in this module take a file descriptor fd as their first\n\
argument. This can be an integer file descriptor, such as returned by\n\
sys.stdin.fileno(), or a file object, such as sys.stdin itself.");
-static PyObject *TermiosError;
+typedef struct {
+ PyObject *TermiosError;
+} termiosmodulestate;
+#define modulestate(o) ((termiosmodulestate *)PyModule_GetState(o))
+#define modulestate_global modulestate(PyState_FindModule(&termiosmodule))
static int fdconv(PyObject* obj, void* p)
{
@@ -53,6 +57,8 @@ static int fdconv(PyObject* obj, void* p)
return 0;
}
+static struct PyModuleDef termiosmodule;
+
PyDoc_STRVAR(termios_tcgetattr__doc__,
"tcgetattr(fd) -> list_of_attrs\n\
\n\
@@ -80,7 +86,7 @@ termios_tcgetattr(PyObject *self, PyObject *args)
return NULL;
if (tcgetattr(fd, &mode) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(modulestate_global->TermiosError);
ispeed = cfgetispeed(&mode);
ospeed = cfgetospeed(&mode);
@@ -160,8 +166,9 @@ termios_tcsetattr(PyObject *self, PyObject *args)
}
/* Get the old mode, in case there are any hidden fields... */
+ termiosmodulestate *state = modulestate_global;
if (tcgetattr(fd, &mode) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(state->TermiosError);
mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
@@ -194,11 +201,11 @@ termios_tcsetattr(PyObject *self, PyObject *args)
}
if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(state->TermiosError);
if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(state->TermiosError);
if (tcsetattr(fd, when, &mode) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(state->TermiosError);
Py_RETURN_NONE;
}
@@ -219,7 +226,7 @@ termios_tcsendbreak(PyObject *self, PyObject *args)
fdconv, &fd, &duration))
return NULL;
if (tcsendbreak(fd, duration) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE;
}
@@ -238,7 +245,7 @@ termios_tcdrain(PyObject *self, PyObject *args)
fdconv, &fd))
return NULL;
if (tcdrain(fd) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE;
}
@@ -260,7 +267,7 @@ termios_tcflush(PyObject *self, PyObject *args)
fdconv, &fd, &queue))
return NULL;
if (tcflush(fd, queue) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE;
}
@@ -282,7 +289,7 @@ termios_tcflow(PyObject *self, PyObject *args)
fdconv, &fd, &action))
return NULL;
if (tcflow(fd, action) == -1)
- return PyErr_SetFromErrno(TermiosError);
+ return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE;
}
@@ -935,17 +942,30 @@ static struct constant {
{NULL, 0}
};
+static int termiosmodule_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(modulestate(m)->TermiosError);
+ return 0;
+}
+
+static int termiosmodule_clear(PyObject *m) {
+ Py_CLEAR(modulestate(m)->TermiosError);
+ return 0;
+}
+
+static void termiosmodule_free(void *m) {
+ termiosmodule_clear((PyObject *)m);
+}
static struct PyModuleDef termiosmodule = {
PyModuleDef_HEAD_INIT,
"termios",
termios__doc__,
- -1,
+ sizeof(termiosmodulestate),
termios_methods,
NULL,
- NULL,
- NULL,
- NULL
+ termiosmodule_traverse,
+ termiosmodule_clear,
+ termiosmodule_free,
};
PyMODINIT_FUNC
@@ -954,15 +974,22 @@ PyInit_termios(void)
PyObject *m;
struct constant *constant = termios_constants;
- m = PyModule_Create(&termiosmodule);
- if (m == NULL)
+ if ((m = PyState_FindModule(&termiosmodule)) != NULL) {
+ Py_INCREF(m);
+ return m;
+ }
+
+ if ((m = PyModule_Create(&termiosmodule)) == NULL) {
return NULL;
+ }
- if (TermiosError == NULL) {
- TermiosError = PyErr_NewException("termios.error", NULL, NULL);
+ termiosmodulestate *state = PyModule_GetState(m);
+ state->TermiosError = PyErr_NewException("termios.error", NULL, NULL);
+ if (state->TermiosError == NULL) {
+ return NULL;
}
- Py_INCREF(TermiosError);
- PyModule_AddObject(m, "error", TermiosError);
+ Py_INCREF(state->TermiosError);
+ PyModule_AddObject(m, "error", state->TermiosError);
while (constant->name != NULL) {
PyModule_AddIntConstant(m, constant->name, constant->value);