Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 15dcdb2

Browse files
authored
bpo-1635741: Port the termios to multi-phase init (PEP 489) (GH-22139)
1 parent b0ac5d7 commit 15dcdb2

File tree

2 files changed

+103
-81
lines changed

2 files changed

+103
-81
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Port the :mod:`termios` extension module to multi-phase initialization
2+
(:pep:`489`).

Modules/termios.c

+101-81
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ get_termios_state(PyObject *module)
5151
return (termiosmodulestate *)state;
5252
}
5353

54-
#define modulestate_global get_termios_state(PyState_FindModule(&termiosmodule))
55-
5654
static int fdconv(PyObject* obj, void* p)
5755
{
5856
int fd;
@@ -79,31 +77,32 @@ indexing in the cc array must be done using the symbolic constants defined\n\
7977
in this module.");
8078

8179
static PyObject *
82-
termios_tcgetattr(PyObject *self, PyObject *args)
80+
termios_tcgetattr(PyObject *module, PyObject *args)
8381
{
8482
int fd;
85-
struct termios mode;
86-
PyObject *cc;
87-
speed_t ispeed, ospeed;
88-
PyObject *v;
89-
int i;
90-
char ch;
91-
9283
if (!PyArg_ParseTuple(args, "O&:tcgetattr",
93-
fdconv, (void*)&fd))
84+
fdconv, (void*)&fd)) {
9485
return NULL;
86+
}
9587

96-
if (tcgetattr(fd, &mode) == -1)
97-
return PyErr_SetFromErrno(modulestate_global->TermiosError);
88+
termiosmodulestate *state = PyModule_GetState(module);
89+
struct termios mode;
90+
if (tcgetattr(fd, &mode) == -1) {
91+
return PyErr_SetFromErrno(state->TermiosError);
92+
}
9893

99-
ispeed = cfgetispeed(&mode);
100-
ospeed = cfgetospeed(&mode);
94+
speed_t ispeed = cfgetispeed(&mode);
95+
speed_t ospeed = cfgetospeed(&mode);
10196

102-
cc = PyList_New(NCCS);
103-
if (cc == NULL)
97+
PyObject *cc = PyList_New(NCCS);
98+
if (cc == NULL) {
10499
return NULL;
100+
}
101+
102+
PyObject *v;
103+
int i;
105104
for (i = 0; i < NCCS; i++) {
106-
ch = (char)mode.c_cc[i];
105+
char ch = (char)mode.c_cc[i];
107106
v = PyBytes_FromStringAndSize(&ch, 1);
108107
if (v == NULL)
109108
goto err;
@@ -156,36 +155,38 @@ queued output, or termios.TCSAFLUSH to change after transmitting all\n\
156155
queued output and discarding all queued input. ");
157156

158157
static PyObject *
159-
termios_tcsetattr(PyObject *self, PyObject *args)
158+
termios_tcsetattr(PyObject *module, PyObject *args)
160159
{
161160
int fd, when;
162-
struct termios mode;
163-
speed_t ispeed, ospeed;
164-
PyObject *term, *cc, *v;
165-
int i;
166-
161+
PyObject *term;
167162
if (!PyArg_ParseTuple(args, "O&iO:tcsetattr",
168-
fdconv, &fd, &when, &term))
163+
fdconv, &fd, &when, &term)) {
169164
return NULL;
165+
}
166+
170167
if (!PyList_Check(term) || PyList_Size(term) != 7) {
171168
PyErr_SetString(PyExc_TypeError,
172169
"tcsetattr, arg 3: must be 7 element list");
173170
return NULL;
174171
}
175172

176173
/* Get the old mode, in case there are any hidden fields... */
177-
termiosmodulestate *state = modulestate_global;
178-
if (tcgetattr(fd, &mode) == -1)
174+
termiosmodulestate *state = PyModule_GetState(module);
175+
struct termios mode;
176+
if (tcgetattr(fd, &mode) == -1) {
179177
return PyErr_SetFromErrno(state->TermiosError);
178+
}
179+
180180
mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
181181
mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
182182
mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
183183
mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3));
184-
ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
185-
ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
186-
cc = PyList_GetItem(term, 6);
187-
if (PyErr_Occurred())
184+
speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
185+
speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
186+
PyObject *cc = PyList_GetItem(term, 6);
187+
if (PyErr_Occurred()) {
188188
return NULL;
189+
}
189190

190191
if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
191192
PyErr_Format(PyExc_TypeError,
@@ -194,6 +195,8 @@ termios_tcsetattr(PyObject *self, PyObject *args)
194195
return NULL;
195196
}
196197

198+
int i;
199+
PyObject *v;
197200
for (i = 0; i < NCCS; i++) {
198201
v = PyList_GetItem(cc, i);
199202

@@ -226,15 +229,18 @@ A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\
226229
has a system dependent meaning.");
227230

228231
static PyObject *
229-
termios_tcsendbreak(PyObject *self, PyObject *args)
232+
termios_tcsendbreak(PyObject *module, PyObject *args)
230233
{
231234
int fd, duration;
232-
233235
if (!PyArg_ParseTuple(args, "O&i:tcsendbreak",
234-
fdconv, &fd, &duration))
236+
fdconv, &fd, &duration)) {
235237
return NULL;
236-
if (tcsendbreak(fd, duration) == -1)
237-
return PyErr_SetFromErrno(modulestate_global->TermiosError);
238+
}
239+
240+
termiosmodulestate *state = PyModule_GetState(module);
241+
if (tcsendbreak(fd, duration) == -1) {
242+
return PyErr_SetFromErrno(state->TermiosError);
243+
}
238244

239245
Py_RETURN_NONE;
240246
}
@@ -245,15 +251,18 @@ PyDoc_STRVAR(termios_tcdrain__doc__,
245251
Wait until all output written to file descriptor fd has been transmitted.");
246252

247253
static PyObject *
248-
termios_tcdrain(PyObject *self, PyObject *args)
254+
termios_tcdrain(PyObject *module, PyObject *args)
249255
{
250256
int fd;
251-
252257
if (!PyArg_ParseTuple(args, "O&:tcdrain",
253-
fdconv, &fd))
258+
fdconv, &fd)) {
254259
return NULL;
255-
if (tcdrain(fd) == -1)
256-
return PyErr_SetFromErrno(modulestate_global->TermiosError);
260+
}
261+
262+
termiosmodulestate *state = PyModule_GetState(module);
263+
if (tcdrain(fd) == -1) {
264+
return PyErr_SetFromErrno(state->TermiosError);
265+
}
257266

258267
Py_RETURN_NONE;
259268
}
@@ -267,15 +276,18 @@ queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\
267276
both queues. ");
268277

269278
static PyObject *
270-
termios_tcflush(PyObject *self, PyObject *args)
279+
termios_tcflush(PyObject *module, PyObject *args)
271280
{
272281
int fd, queue;
273-
274282
if (!PyArg_ParseTuple(args, "O&i:tcflush",
275-
fdconv, &fd, &queue))
283+
fdconv, &fd, &queue)) {
276284
return NULL;
277-
if (tcflush(fd, queue) == -1)
278-
return PyErr_SetFromErrno(modulestate_global->TermiosError);
285+
}
286+
287+
termiosmodulestate *state = PyModule_GetState(module);
288+
if (tcflush(fd, queue) == -1) {
289+
return PyErr_SetFromErrno(state->TermiosError);
290+
}
279291

280292
Py_RETURN_NONE;
281293
}
@@ -289,15 +301,18 @@ termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\
289301
or termios.TCION to restart input.");
290302

291303
static PyObject *
292-
termios_tcflow(PyObject *self, PyObject *args)
304+
termios_tcflow(PyObject *module, PyObject *args)
293305
{
294306
int fd, action;
295-
296307
if (!PyArg_ParseTuple(args, "O&i:tcflow",
297-
fdconv, &fd, &action))
308+
fdconv, &fd, &action)) {
298309
return NULL;
299-
if (tcflow(fd, action) == -1)
300-
return PyErr_SetFromErrno(modulestate_global->TermiosError);
310+
}
311+
312+
termiosmodulestate *state = PyModule_GetState(module);
313+
if (tcflow(fd, action) == -1) {
314+
return PyErr_SetFromErrno(state->TermiosError);
315+
}
301316

302317
Py_RETURN_NONE;
303318
}
@@ -997,44 +1012,49 @@ static void termiosmodule_free(void *m) {
9971012
termiosmodule_clear((PyObject *)m);
9981013
}
9991014

1000-
static struct PyModuleDef termiosmodule = {
1001-
PyModuleDef_HEAD_INIT,
1002-
"termios",
1003-
termios__doc__,
1004-
sizeof(termiosmodulestate),
1005-
termios_methods,
1006-
NULL,
1007-
termiosmodule_traverse,
1008-
termiosmodule_clear,
1009-
termiosmodule_free,
1010-
};
1011-
1012-
PyMODINIT_FUNC
1013-
PyInit_termios(void)
1015+
static int
1016+
termios_exec(PyObject *mod)
10141017
{
1015-
PyObject *m;
10161018
struct constant *constant = termios_constants;
1017-
1018-
if ((m = PyState_FindModule(&termiosmodule)) != NULL) {
1019-
Py_INCREF(m);
1020-
return m;
1021-
}
1022-
1023-
if ((m = PyModule_Create(&termiosmodule)) == NULL) {
1024-
return NULL;
1025-
}
1026-
1027-
termiosmodulestate *state = get_termios_state(m);
1019+
termiosmodulestate *state = get_termios_state(mod);
10281020
state->TermiosError = PyErr_NewException("termios.error", NULL, NULL);
10291021
if (state->TermiosError == NULL) {
1030-
return NULL;
1022+
return -1;
10311023
}
10321024
Py_INCREF(state->TermiosError);
1033-
PyModule_AddObject(m, "error", state->TermiosError);
1025+
if (PyModule_AddObject(mod, "error", state->TermiosError) < 0) {
1026+
Py_DECREF(state->TermiosError);
1027+
return -1;
1028+
}
10341029

10351030
while (constant->name != NULL) {
1036-
PyModule_AddIntConstant(m, constant->name, constant->value);
1031+
if (PyModule_AddIntConstant(
1032+
mod, constant->name, constant->value) < 0) {
1033+
return -1;
1034+
}
10371035
++constant;
10381036
}
1039-
return m;
1037+
return 0;
1038+
}
1039+
1040+
static PyModuleDef_Slot termios_slots[] = {
1041+
{Py_mod_exec, termios_exec},
1042+
{0, NULL}
1043+
};
1044+
1045+
static struct PyModuleDef termiosmodule = {
1046+
PyModuleDef_HEAD_INIT,
1047+
.m_name = "termios",
1048+
.m_doc = termios__doc__,
1049+
.m_size = sizeof(termiosmodulestate),
1050+
.m_methods = termios_methods,
1051+
.m_slots = termios_slots,
1052+
.m_traverse = termiosmodule_traverse,
1053+
.m_clear = termiosmodule_clear,
1054+
.m_free = termiosmodule_free,
1055+
};
1056+
1057+
PyMODINIT_FUNC PyInit_termios(void)
1058+
{
1059+
return PyModuleDef_Init(&termiosmodule);
10401060
}

0 commit comments

Comments
 (0)