Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Make termios extension module PEP-384 compatible
67 changes: 47 additions & 20 deletions Modules/termios.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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\
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand Down