Commit bd0c7a12 authored by Dino Viehland's avatar Dino Viehland Committed by T. Wouters

bpo-38071: Make termios PEP-384 compatible (GH-15785)

Make the termios module PEP-384 compatible.
parent 40a5313e
Make termios extension module PEP-384 compatible
\ No newline at end of file
...@@ -39,7 +39,11 @@ All functions in this module take a file descriptor fd as their first\n\ ...@@ -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\ 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."); 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) static int fdconv(PyObject* obj, void* p)
{ {
...@@ -53,6 +57,8 @@ static int fdconv(PyObject* obj, void* p) ...@@ -53,6 +57,8 @@ static int fdconv(PyObject* obj, void* p)
return 0; return 0;
} }
static struct PyModuleDef termiosmodule;
PyDoc_STRVAR(termios_tcgetattr__doc__, PyDoc_STRVAR(termios_tcgetattr__doc__,
"tcgetattr(fd) -> list_of_attrs\n\ "tcgetattr(fd) -> list_of_attrs\n\
\n\ \n\
...@@ -80,7 +86,7 @@ termios_tcgetattr(PyObject *self, PyObject *args) ...@@ -80,7 +86,7 @@ termios_tcgetattr(PyObject *self, PyObject *args)
return NULL; return NULL;
if (tcgetattr(fd, &mode) == -1) if (tcgetattr(fd, &mode) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(modulestate_global->TermiosError);
ispeed = cfgetispeed(&mode); ispeed = cfgetispeed(&mode);
ospeed = cfgetospeed(&mode); ospeed = cfgetospeed(&mode);
...@@ -160,8 +166,9 @@ termios_tcsetattr(PyObject *self, PyObject *args) ...@@ -160,8 +166,9 @@ termios_tcsetattr(PyObject *self, PyObject *args)
} }
/* Get the old mode, in case there are any hidden fields... */ /* Get the old mode, in case there are any hidden fields... */
termiosmodulestate *state = modulestate_global;
if (tcgetattr(fd, &mode) == -1) 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_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1)); mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2)); mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
...@@ -194,11 +201,11 @@ termios_tcsetattr(PyObject *self, PyObject *args) ...@@ -194,11 +201,11 @@ termios_tcsetattr(PyObject *self, PyObject *args)
} }
if (cfsetispeed(&mode, (speed_t) ispeed) == -1) if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(state->TermiosError);
if (cfsetospeed(&mode, (speed_t) ospeed) == -1) if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(state->TermiosError);
if (tcsetattr(fd, when, &mode) == -1) if (tcsetattr(fd, when, &mode) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(state->TermiosError);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
...@@ -219,7 +226,7 @@ termios_tcsendbreak(PyObject *self, PyObject *args) ...@@ -219,7 +226,7 @@ termios_tcsendbreak(PyObject *self, PyObject *args)
fdconv, &fd, &duration)) fdconv, &fd, &duration))
return NULL; return NULL;
if (tcsendbreak(fd, duration) == -1) if (tcsendbreak(fd, duration) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
...@@ -238,7 +245,7 @@ termios_tcdrain(PyObject *self, PyObject *args) ...@@ -238,7 +245,7 @@ termios_tcdrain(PyObject *self, PyObject *args)
fdconv, &fd)) fdconv, &fd))
return NULL; return NULL;
if (tcdrain(fd) == -1) if (tcdrain(fd) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
...@@ -260,7 +267,7 @@ termios_tcflush(PyObject *self, PyObject *args) ...@@ -260,7 +267,7 @@ termios_tcflush(PyObject *self, PyObject *args)
fdconv, &fd, &queue)) fdconv, &fd, &queue))
return NULL; return NULL;
if (tcflush(fd, queue) == -1) if (tcflush(fd, queue) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
...@@ -282,7 +289,7 @@ termios_tcflow(PyObject *self, PyObject *args) ...@@ -282,7 +289,7 @@ termios_tcflow(PyObject *self, PyObject *args)
fdconv, &fd, &action)) fdconv, &fd, &action))
return NULL; return NULL;
if (tcflow(fd, action) == -1) if (tcflow(fd, action) == -1)
return PyErr_SetFromErrno(TermiosError); return PyErr_SetFromErrno(modulestate_global->TermiosError);
Py_RETURN_NONE; Py_RETURN_NONE;
} }
...@@ -935,17 +942,30 @@ static struct constant { ...@@ -935,17 +942,30 @@ static struct constant {
{NULL, 0} {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 = { static struct PyModuleDef termiosmodule = {
PyModuleDef_HEAD_INIT, PyModuleDef_HEAD_INIT,
"termios", "termios",
termios__doc__, termios__doc__,
-1, sizeof(termiosmodulestate),
termios_methods, termios_methods,
NULL, NULL,
NULL, termiosmodule_traverse,
NULL, termiosmodule_clear,
NULL termiosmodule_free,
}; };
PyMODINIT_FUNC PyMODINIT_FUNC
...@@ -954,15 +974,22 @@ PyInit_termios(void) ...@@ -954,15 +974,22 @@ PyInit_termios(void)
PyObject *m; PyObject *m;
struct constant *constant = termios_constants; struct constant *constant = termios_constants;
m = PyModule_Create(&termiosmodule); if ((m = PyState_FindModule(&termiosmodule)) != NULL) {
if (m == NULL) Py_INCREF(m);
return m;
}
if ((m = PyModule_Create(&termiosmodule)) == NULL) {
return NULL; return NULL;
}
if (TermiosError == NULL) { termiosmodulestate *state = PyModule_GetState(m);
TermiosError = PyErr_NewException("termios.error", NULL, NULL); state->TermiosError = PyErr_NewException("termios.error", NULL, NULL);
if (state->TermiosError == NULL) {
return NULL;
} }
Py_INCREF(TermiosError); Py_INCREF(state->TermiosError);
PyModule_AddObject(m, "error", TermiosError); PyModule_AddObject(m, "error", state->TermiosError);
while (constant->name != NULL) { while (constant->name != NULL) {
PyModule_AddIntConstant(m, constant->name, constant->value); PyModule_AddIntConstant(m, constant->name, constant->value);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment