Line data Source code
1 : /* termios.c -- POSIX terminal I/O module implementation. */
2 :
3 : #include "Python.h"
4 :
5 : /* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE
6 : is defined, so we define it here. */
7 : #if defined(__sgi)
8 : #define CTRL(c) ((c)&037)
9 : #endif
10 :
11 : #if defined(__sun)
12 : /* We could do better. Check issue-32660 */
13 : #include <sys/filio.h>
14 : #include <sys/sockio.h>
15 : #endif
16 :
17 : #include <termios.h>
18 : #include <sys/ioctl.h>
19 :
20 : /* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR,
21 : * MDTR, MRI, and MRTS (apparently used internally by some things
22 : * defined as macros; these are not used here directly).
23 : */
24 : #ifdef HAVE_SYS_MODEM_H
25 : #include <sys/modem.h>
26 : #endif
27 : /* HP-UX requires that this be included to pick up TIOCGPGRP and friends */
28 : #ifdef HAVE_SYS_BSDTTY_H
29 : #include <sys/bsdtty.h>
30 : #endif
31 :
32 : /*[clinic input]
33 : module termios
34 : [clinic start generated code]*/
35 : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=01105c85d0ca7252]*/
36 :
37 : #include "clinic/termios.c.h"
38 :
39 : PyDoc_STRVAR(termios__doc__,
40 : "This module provides an interface to the Posix calls for tty I/O control.\n\
41 : For a complete description of these calls, see the Posix or Unix manual\n\
42 : pages. It is only available for those Unix versions that support Posix\n\
43 : termios style tty I/O control.\n\
44 : \n\
45 : All functions in this module take a file descriptor fd as their first\n\
46 : argument. This can be an integer file descriptor, such as returned by\n\
47 : sys.stdin.fileno(), or a file object, such as sys.stdin itself.");
48 :
49 : typedef struct {
50 : PyObject *TermiosError;
51 : } termiosmodulestate;
52 :
53 : static inline termiosmodulestate*
54 86284 : get_termios_state(PyObject *module)
55 : {
56 86284 : void *state = PyModule_GetState(module);
57 86284 : assert(state != NULL);
58 86284 : return (termiosmodulestate *)state;
59 : }
60 :
61 : static struct PyModuleDef termiosmodule;
62 :
63 : /*[clinic input]
64 : termios.tcgetattr
65 :
66 : fd: fildes
67 : /
68 :
69 : Get the tty attributes for file descriptor fd.
70 :
71 : Returns a list [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]
72 : where cc is a list of the tty special characters (each a string of
73 : length 1, except the items with indices VMIN and VTIME, which are
74 : integers when these fields are defined). The interpretation of the
75 : flags and the speeds as well as the indexing in the cc array must be
76 : done using the symbolic constants defined in this module.
77 : [clinic start generated code]*/
78 :
79 : static PyObject *
80 6 : termios_tcgetattr_impl(PyObject *module, int fd)
81 : /*[clinic end generated code: output=2b3da39db870e629 input=54dad9779ebe74b1]*/
82 : {
83 6 : termiosmodulestate *state = PyModule_GetState(module);
84 : struct termios mode;
85 6 : if (tcgetattr(fd, &mode) == -1) {
86 3 : return PyErr_SetFromErrno(state->TermiosError);
87 : }
88 :
89 3 : speed_t ispeed = cfgetispeed(&mode);
90 3 : speed_t ospeed = cfgetospeed(&mode);
91 :
92 3 : PyObject *cc = PyList_New(NCCS);
93 3 : if (cc == NULL) {
94 0 : return NULL;
95 : }
96 :
97 : PyObject *v;
98 : int i;
99 99 : for (i = 0; i < NCCS; i++) {
100 96 : char ch = (char)mode.c_cc[i];
101 96 : v = PyBytes_FromStringAndSize(&ch, 1);
102 96 : if (v == NULL)
103 0 : goto err;
104 96 : PyList_SetItem(cc, i, v);
105 : }
106 :
107 : /* Convert the MIN and TIME slots to integer. On some systems, the
108 : MIN and TIME slots are the same as the EOF and EOL slots. So we
109 : only do this in noncanonical input mode. */
110 3 : if ((mode.c_lflag & ICANON) == 0) {
111 0 : v = PyLong_FromLong((long)mode.c_cc[VMIN]);
112 0 : if (v == NULL)
113 0 : goto err;
114 0 : PyList_SetItem(cc, VMIN, v);
115 0 : v = PyLong_FromLong((long)mode.c_cc[VTIME]);
116 0 : if (v == NULL)
117 0 : goto err;
118 0 : PyList_SetItem(cc, VTIME, v);
119 : }
120 :
121 3 : if (!(v = PyList_New(7)))
122 0 : goto err;
123 :
124 3 : PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag));
125 3 : PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag));
126 3 : PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag));
127 3 : PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag));
128 3 : PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed));
129 3 : PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed));
130 3 : if (PyErr_Occurred()) {
131 0 : Py_DECREF(v);
132 0 : goto err;
133 : }
134 3 : PyList_SetItem(v, 6, cc);
135 3 : return v;
136 0 : err:
137 0 : Py_DECREF(cc);
138 0 : return NULL;
139 : }
140 :
141 : /*[clinic input]
142 : termios.tcsetattr
143 :
144 : fd: fildes
145 : when: int
146 : attributes as term: object
147 : /
148 :
149 : Set the tty attributes for file descriptor fd.
150 :
151 : The attributes to be set are taken from the attributes argument, which
152 : is a list like the one returned by tcgetattr(). The when argument
153 : determines when the attributes are changed: termios.TCSANOW to
154 : change immediately, termios.TCSADRAIN to change after transmitting all
155 : queued output, or termios.TCSAFLUSH to change after transmitting all
156 : queued output and discarding all queued input.
157 : [clinic start generated code]*/
158 :
159 : static PyObject *
160 3 : termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term)
161 : /*[clinic end generated code: output=bcd2b0a7b98a4bf5 input=5dafabdd5a08f018]*/
162 : {
163 3 : if (!PyList_Check(term) || PyList_Size(term) != 7) {
164 0 : PyErr_SetString(PyExc_TypeError,
165 : "tcsetattr, arg 3: must be 7 element list");
166 0 : return NULL;
167 : }
168 :
169 : /* Get the old mode, in case there are any hidden fields... */
170 3 : termiosmodulestate *state = PyModule_GetState(module);
171 : struct termios mode;
172 3 : if (tcgetattr(fd, &mode) == -1) {
173 0 : return PyErr_SetFromErrno(state->TermiosError);
174 : }
175 :
176 3 : mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
177 3 : mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
178 3 : mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
179 3 : mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3));
180 3 : speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
181 3 : speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
182 3 : PyObject *cc = PyList_GetItem(term, 6);
183 3 : if (PyErr_Occurred()) {
184 0 : return NULL;
185 : }
186 :
187 3 : if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
188 0 : PyErr_Format(PyExc_TypeError,
189 : "tcsetattr: attributes[6] must be %d element list",
190 : NCCS);
191 0 : return NULL;
192 : }
193 :
194 : int i;
195 : PyObject *v;
196 99 : for (i = 0; i < NCCS; i++) {
197 96 : v = PyList_GetItem(cc, i);
198 :
199 96 : if (PyBytes_Check(v) && PyBytes_Size(v) == 1)
200 90 : mode.c_cc[i] = (cc_t) * PyBytes_AsString(v);
201 6 : else if (PyLong_Check(v))
202 6 : mode.c_cc[i] = (cc_t) PyLong_AsLong(v);
203 : else {
204 0 : PyErr_SetString(PyExc_TypeError,
205 : "tcsetattr: elements of attributes must be characters or integers");
206 0 : return NULL;
207 : }
208 : }
209 :
210 3 : if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
211 0 : return PyErr_SetFromErrno(state->TermiosError);
212 3 : if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
213 0 : return PyErr_SetFromErrno(state->TermiosError);
214 3 : if (tcsetattr(fd, when, &mode) == -1)
215 0 : return PyErr_SetFromErrno(state->TermiosError);
216 :
217 3 : Py_RETURN_NONE;
218 : }
219 :
220 : /*[clinic input]
221 : termios.tcsendbreak
222 :
223 : fd: fildes
224 : duration: int
225 : /
226 :
227 : Send a break on file descriptor fd.
228 :
229 : A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration
230 : has a system dependent meaning.
231 : [clinic start generated code]*/
232 :
233 : static PyObject *
234 0 : termios_tcsendbreak_impl(PyObject *module, int fd, int duration)
235 : /*[clinic end generated code: output=5945f589b5d3ac66 input=dc2f32417691f8ed]*/
236 : {
237 0 : termiosmodulestate *state = PyModule_GetState(module);
238 0 : if (tcsendbreak(fd, duration) == -1) {
239 0 : return PyErr_SetFromErrno(state->TermiosError);
240 : }
241 :
242 0 : Py_RETURN_NONE;
243 : }
244 :
245 : /*[clinic input]
246 : termios.tcdrain
247 :
248 : fd: fildes
249 : /
250 :
251 : Wait until all output written to file descriptor fd has been transmitted.
252 : [clinic start generated code]*/
253 :
254 : static PyObject *
255 0 : termios_tcdrain_impl(PyObject *module, int fd)
256 : /*[clinic end generated code: output=5fd86944c6255955 input=c99241b140b32447]*/
257 : {
258 0 : termiosmodulestate *state = PyModule_GetState(module);
259 0 : if (tcdrain(fd) == -1) {
260 0 : return PyErr_SetFromErrno(state->TermiosError);
261 : }
262 :
263 0 : Py_RETURN_NONE;
264 : }
265 :
266 : /*[clinic input]
267 : termios.tcflush
268 :
269 : fd: fildes
270 : queue: int
271 : /
272 :
273 : Discard queued data on file descriptor fd.
274 :
275 : The queue selector specifies which queue: termios.TCIFLUSH for the input
276 : queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for
277 : both queues.
278 : [clinic start generated code]*/
279 :
280 : static PyObject *
281 0 : termios_tcflush_impl(PyObject *module, int fd, int queue)
282 : /*[clinic end generated code: output=2424f80312ec2f21 input=0f7d08122ddc07b5]*/
283 : {
284 0 : termiosmodulestate *state = PyModule_GetState(module);
285 0 : if (tcflush(fd, queue) == -1) {
286 0 : return PyErr_SetFromErrno(state->TermiosError);
287 : }
288 :
289 0 : Py_RETURN_NONE;
290 : }
291 :
292 : /*[clinic input]
293 : termios.tcflow
294 :
295 : fd: fildes
296 : action: int
297 : /
298 :
299 : Suspend or resume input or output on file descriptor fd.
300 :
301 : The action argument can be termios.TCOOFF to suspend output,
302 : termios.TCOON to restart output, termios.TCIOFF to suspend input,
303 : or termios.TCION to restart input.
304 : [clinic start generated code]*/
305 :
306 : static PyObject *
307 0 : termios_tcflow_impl(PyObject *module, int fd, int action)
308 : /*[clinic end generated code: output=afd10928e6ea66eb input=c6aff0640b6efd9c]*/
309 : {
310 0 : termiosmodulestate *state = PyModule_GetState(module);
311 0 : if (tcflow(fd, action) == -1) {
312 0 : return PyErr_SetFromErrno(state->TermiosError);
313 : }
314 :
315 0 : Py_RETURN_NONE;
316 : }
317 :
318 : /*[clinic input]
319 : termios.tcgetwinsize
320 :
321 : fd: fildes
322 : /
323 :
324 : Get the tty winsize for file descriptor fd.
325 :
326 : Returns a tuple (ws_row, ws_col).
327 : [clinic start generated code]*/
328 :
329 : static PyObject *
330 0 : termios_tcgetwinsize_impl(PyObject *module, int fd)
331 : /*[clinic end generated code: output=31825977d5325fb6 input=5706c379d7fd984d]*/
332 : {
333 : #if defined(TIOCGWINSZ)
334 0 : termiosmodulestate *state = PyModule_GetState(module);
335 : struct winsize w;
336 0 : if (ioctl(fd, TIOCGWINSZ, &w) == -1) {
337 0 : return PyErr_SetFromErrno(state->TermiosError);
338 : }
339 :
340 : PyObject *v;
341 0 : if (!(v = PyTuple_New(2))) {
342 0 : return NULL;
343 : }
344 :
345 0 : PyTuple_SetItem(v, 0, PyLong_FromLong((long)w.ws_row));
346 0 : PyTuple_SetItem(v, 1, PyLong_FromLong((long)w.ws_col));
347 0 : if (PyErr_Occurred()) {
348 0 : Py_DECREF(v);
349 0 : return NULL;
350 : }
351 0 : return v;
352 : #elif defined(TIOCGSIZE)
353 : termiosmodulestate *state = PyModule_GetState(module);
354 : struct ttysize s;
355 : if (ioctl(fd, TIOCGSIZE, &s) == -1) {
356 : return PyErr_SetFromErrno(state->TermiosError);
357 : }
358 :
359 : PyObject *v;
360 : if (!(v = PyTuple_New(2))) {
361 : return NULL;
362 : }
363 :
364 : PyTuple_SetItem(v, 0, PyLong_FromLong((long)s.ts_lines));
365 : PyTuple_SetItem(v, 1, PyLong_FromLong((long)s.ts_cols));
366 : if (PyErr_Occurred()) {
367 : Py_DECREF(v);
368 : return NULL;
369 : }
370 : return v;
371 : #else
372 : PyErr_SetString(PyExc_NotImplementedError,
373 : "requires termios.TIOCGWINSZ and/or termios.TIOCGSIZE");
374 : return NULL;
375 : #endif /* defined(TIOCGWINSZ) */
376 : }
377 :
378 : /*[clinic input]
379 : termios.tcsetwinsize
380 :
381 : fd: fildes
382 : winsize as winsz: object
383 : /
384 :
385 : Set the tty winsize for file descriptor fd.
386 :
387 : The winsize to be set is taken from the winsize argument, which
388 : is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize().
389 : [clinic start generated code]*/
390 :
391 : static PyObject *
392 0 : termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz)
393 : /*[clinic end generated code: output=2ac3c9bb6eda83e1 input=4a06424465b24aee]*/
394 : {
395 0 : if (!PySequence_Check(winsz) || PySequence_Size(winsz) != 2) {
396 0 : PyErr_SetString(PyExc_TypeError,
397 : "tcsetwinsize, arg 2: must be a two-item sequence");
398 0 : return NULL;
399 : }
400 :
401 : PyObject *tmp_item;
402 : long winsz_0, winsz_1;
403 0 : tmp_item = PySequence_GetItem(winsz, 0);
404 0 : winsz_0 = PyLong_AsLong(tmp_item);
405 0 : if (winsz_0 == -1 && PyErr_Occurred()) {
406 0 : Py_XDECREF(tmp_item);
407 0 : return NULL;
408 : }
409 0 : Py_XDECREF(tmp_item);
410 0 : tmp_item = PySequence_GetItem(winsz, 1);
411 0 : winsz_1 = PyLong_AsLong(tmp_item);
412 0 : if (winsz_1 == -1 && PyErr_Occurred()) {
413 0 : Py_XDECREF(tmp_item);
414 0 : return NULL;
415 : }
416 0 : Py_XDECREF(tmp_item);
417 :
418 0 : termiosmodulestate *state = PyModule_GetState(module);
419 :
420 : #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
421 : struct winsize w;
422 : /* Get the old winsize because it might have
423 : more fields such as xpixel, ypixel. */
424 0 : if (ioctl(fd, TIOCGWINSZ, &w) == -1) {
425 0 : return PyErr_SetFromErrno(state->TermiosError);
426 : }
427 :
428 0 : w.ws_row = (unsigned short) winsz_0;
429 0 : w.ws_col = (unsigned short) winsz_1;
430 0 : if ((((long)w.ws_row) != winsz_0) || (((long)w.ws_col) != winsz_1)) {
431 0 : PyErr_SetString(PyExc_OverflowError,
432 : "winsize value(s) out of range.");
433 0 : return NULL;
434 : }
435 :
436 0 : if (ioctl(fd, TIOCSWINSZ, &w) == -1) {
437 0 : return PyErr_SetFromErrno(state->TermiosError);
438 : }
439 :
440 0 : Py_RETURN_NONE;
441 : #elif defined(TIOCGSIZE) && defined(TIOCSSIZE)
442 : struct ttysize s;
443 : /* Get the old ttysize because it might have more fields. */
444 : if (ioctl(fd, TIOCGSIZE, &s) == -1) {
445 : return PyErr_SetFromErrno(state->TermiosError);
446 : }
447 :
448 : s.ts_lines = (int) winsz_0;
449 : s.ts_cols = (int) winsz_1;
450 : if ((((long)s.ts_lines) != winsz_0) || (((long)s.ts_cols) != winsz_1)) {
451 : PyErr_SetString(PyExc_OverflowError,
452 : "winsize value(s) out of range.");
453 : return NULL;
454 : }
455 :
456 : if (ioctl(fd, TIOCSSIZE, &s) == -1) {
457 : return PyErr_SetFromErrno(state->TermiosError);
458 : }
459 :
460 : Py_RETURN_NONE;
461 : #else
462 : PyErr_SetString(PyExc_NotImplementedError,
463 : "requires termios.TIOCGWINSZ, termios.TIOCSWINSZ and/or termios.TIOCGSIZE, termios.TIOCSSIZE");
464 : return NULL;
465 : #endif /* defined(TIOCGWINSZ) && defined(TIOCSWINSZ) */
466 : }
467 :
468 : static PyMethodDef termios_methods[] =
469 : {
470 : TERMIOS_TCGETATTR_METHODDEF
471 : TERMIOS_TCSETATTR_METHODDEF
472 : TERMIOS_TCSENDBREAK_METHODDEF
473 : TERMIOS_TCDRAIN_METHODDEF
474 : TERMIOS_TCFLUSH_METHODDEF
475 : TERMIOS_TCFLOW_METHODDEF
476 : TERMIOS_TCGETWINSIZE_METHODDEF
477 : TERMIOS_TCSETWINSIZE_METHODDEF
478 : {NULL, NULL}
479 : };
480 :
481 :
482 : #if defined(VSWTCH) && !defined(VSWTC)
483 : #define VSWTC VSWTCH
484 : #endif
485 :
486 : #if defined(VSWTC) && !defined(VSWTCH)
487 : #define VSWTCH VSWTC
488 : #endif
489 :
490 : static struct constant {
491 : char *name;
492 : long value;
493 : } termios_constants[] = {
494 : /* cfgetospeed(), cfsetospeed() constants */
495 : {"B0", B0},
496 : {"B50", B50},
497 : {"B75", B75},
498 : {"B110", B110},
499 : {"B134", B134},
500 : {"B150", B150},
501 : {"B200", B200},
502 : {"B300", B300},
503 : {"B600", B600},
504 : {"B1200", B1200},
505 : {"B1800", B1800},
506 : {"B2400", B2400},
507 : {"B4800", B4800},
508 : {"B9600", B9600},
509 : {"B19200", B19200},
510 : {"B38400", B38400},
511 : #ifdef B57600
512 : {"B57600", B57600},
513 : #endif
514 : #ifdef B115200
515 : {"B115200", B115200},
516 : #endif
517 : #ifdef B230400
518 : {"B230400", B230400},
519 : #endif
520 : #ifdef B460800
521 : {"B460800", B460800},
522 : #endif
523 : #ifdef B500000
524 : {"B500000", B500000},
525 : #endif
526 : #ifdef B576000
527 : {"B576000", B576000},
528 : #endif
529 : #ifdef B921600
530 : {"B921600", B921600},
531 : #endif
532 : #ifdef B1000000
533 : {"B1000000", B1000000},
534 : #endif
535 : #ifdef B1152000
536 : {"B1152000", B1152000},
537 : #endif
538 : #ifdef B1500000
539 : {"B1500000", B1500000},
540 : #endif
541 : #ifdef B2000000
542 : {"B2000000", B2000000},
543 : #endif
544 : #ifdef B2500000
545 : {"B2500000", B2500000},
546 : #endif
547 : #ifdef B3000000
548 : {"B3000000", B3000000},
549 : #endif
550 : #ifdef B3500000
551 : {"B3500000", B3500000},
552 : #endif
553 : #ifdef B4000000
554 : {"B4000000", B4000000},
555 : #endif
556 :
557 : #ifdef CBAUDEX
558 : {"CBAUDEX", CBAUDEX},
559 : #endif
560 :
561 : /* tcsetattr() constants */
562 : {"TCSANOW", TCSANOW},
563 : {"TCSADRAIN", TCSADRAIN},
564 : {"TCSAFLUSH", TCSAFLUSH},
565 : #ifdef TCSASOFT
566 : {"TCSASOFT", TCSASOFT},
567 : #endif
568 :
569 : /* tcflush() constants */
570 : {"TCIFLUSH", TCIFLUSH},
571 : {"TCOFLUSH", TCOFLUSH},
572 : {"TCIOFLUSH", TCIOFLUSH},
573 :
574 : /* tcflow() constants */
575 : {"TCOOFF", TCOOFF},
576 : {"TCOON", TCOON},
577 : {"TCIOFF", TCIOFF},
578 : {"TCION", TCION},
579 :
580 : /* struct termios.c_iflag constants */
581 : {"IGNBRK", IGNBRK},
582 : {"BRKINT", BRKINT},
583 : {"IGNPAR", IGNPAR},
584 : {"PARMRK", PARMRK},
585 : {"INPCK", INPCK},
586 : {"ISTRIP", ISTRIP},
587 : {"INLCR", INLCR},
588 : {"IGNCR", IGNCR},
589 : {"ICRNL", ICRNL},
590 : #ifdef IUCLC
591 : {"IUCLC", IUCLC},
592 : #endif
593 : {"IXON", IXON},
594 : {"IXANY", IXANY},
595 : {"IXOFF", IXOFF},
596 : #ifdef IMAXBEL
597 : {"IMAXBEL", IMAXBEL},
598 : #endif
599 :
600 : /* struct termios.c_oflag constants */
601 : {"OPOST", OPOST},
602 : #ifdef OLCUC
603 : {"OLCUC", OLCUC},
604 : #endif
605 : #ifdef ONLCR
606 : {"ONLCR", ONLCR},
607 : #endif
608 : #ifdef OCRNL
609 : {"OCRNL", OCRNL},
610 : #endif
611 : #ifdef ONOCR
612 : {"ONOCR", ONOCR},
613 : #endif
614 : #ifdef ONLRET
615 : {"ONLRET", ONLRET},
616 : #endif
617 : #ifdef OFILL
618 : {"OFILL", OFILL},
619 : #endif
620 : #ifdef OFDEL
621 : {"OFDEL", OFDEL},
622 : #endif
623 : #ifdef NLDLY
624 : {"NLDLY", NLDLY},
625 : #endif
626 : #ifdef CRDLY
627 : {"CRDLY", CRDLY},
628 : #endif
629 : #ifdef TABDLY
630 : {"TABDLY", TABDLY},
631 : #endif
632 : #ifdef BSDLY
633 : {"BSDLY", BSDLY},
634 : #endif
635 : #ifdef VTDLY
636 : {"VTDLY", VTDLY},
637 : #endif
638 : #ifdef FFDLY
639 : {"FFDLY", FFDLY},
640 : #endif
641 :
642 : /* struct termios.c_oflag-related values (delay mask) */
643 : #ifdef NL0
644 : {"NL0", NL0},
645 : #endif
646 : #ifdef NL1
647 : {"NL1", NL1},
648 : #endif
649 : #ifdef CR0
650 : {"CR0", CR0},
651 : #endif
652 : #ifdef CR1
653 : {"CR1", CR1},
654 : #endif
655 : #ifdef CR2
656 : {"CR2", CR2},
657 : #endif
658 : #ifdef CR3
659 : {"CR3", CR3},
660 : #endif
661 : #ifdef TAB0
662 : {"TAB0", TAB0},
663 : #endif
664 : #ifdef TAB1
665 : {"TAB1", TAB1},
666 : #endif
667 : #ifdef TAB2
668 : {"TAB2", TAB2},
669 : #endif
670 : #ifdef TAB3
671 : {"TAB3", TAB3},
672 : #endif
673 : #ifdef XTABS
674 : {"XTABS", XTABS},
675 : #endif
676 : #ifdef BS0
677 : {"BS0", BS0},
678 : #endif
679 : #ifdef BS1
680 : {"BS1", BS1},
681 : #endif
682 : #ifdef VT0
683 : {"VT0", VT0},
684 : #endif
685 : #ifdef VT1
686 : {"VT1", VT1},
687 : #endif
688 : #ifdef FF0
689 : {"FF0", FF0},
690 : #endif
691 : #ifdef FF1
692 : {"FF1", FF1},
693 : #endif
694 :
695 : /* struct termios.c_cflag constants */
696 : {"CSIZE", CSIZE},
697 : {"CSTOPB", CSTOPB},
698 : {"CREAD", CREAD},
699 : {"PARENB", PARENB},
700 : {"PARODD", PARODD},
701 : {"HUPCL", HUPCL},
702 : {"CLOCAL", CLOCAL},
703 : #ifdef CIBAUD
704 : {"CIBAUD", CIBAUD},
705 : #endif
706 : #ifdef CRTSCTS
707 : {"CRTSCTS", (long)CRTSCTS},
708 : #endif
709 :
710 : /* struct termios.c_cflag-related values (character size) */
711 : {"CS5", CS5},
712 : {"CS6", CS6},
713 : {"CS7", CS7},
714 : {"CS8", CS8},
715 :
716 : /* struct termios.c_lflag constants */
717 : {"ISIG", ISIG},
718 : {"ICANON", ICANON},
719 : #ifdef XCASE
720 : {"XCASE", XCASE},
721 : #endif
722 : {"ECHO", ECHO},
723 : {"ECHOE", ECHOE},
724 : {"ECHOK", ECHOK},
725 : {"ECHONL", ECHONL},
726 : #ifdef ECHOCTL
727 : {"ECHOCTL", ECHOCTL},
728 : #endif
729 : #ifdef ECHOPRT
730 : {"ECHOPRT", ECHOPRT},
731 : #endif
732 : #ifdef ECHOKE
733 : {"ECHOKE", ECHOKE},
734 : #endif
735 : #ifdef FLUSHO
736 : {"FLUSHO", FLUSHO},
737 : #endif
738 : {"NOFLSH", NOFLSH},
739 : {"TOSTOP", TOSTOP},
740 : #ifdef PENDIN
741 : {"PENDIN", PENDIN},
742 : #endif
743 : {"IEXTEN", IEXTEN},
744 :
745 : /* indexes into the control chars array returned by tcgetattr() */
746 : {"VINTR", VINTR},
747 : {"VQUIT", VQUIT},
748 : {"VERASE", VERASE},
749 : {"VKILL", VKILL},
750 : {"VEOF", VEOF},
751 : {"VTIME", VTIME},
752 : {"VMIN", VMIN},
753 : #ifdef VSWTC
754 : /* The #defines above ensure that if either is defined, both are,
755 : * but both may be omitted by the system headers. ;-( */
756 : {"VSWTC", VSWTC},
757 : {"VSWTCH", VSWTCH},
758 : #endif
759 : {"VSTART", VSTART},
760 : {"VSTOP", VSTOP},
761 : {"VSUSP", VSUSP},
762 : {"VEOL", VEOL},
763 : #ifdef VREPRINT
764 : {"VREPRINT", VREPRINT},
765 : #endif
766 : #ifdef VDISCARD
767 : {"VDISCARD", VDISCARD},
768 : #endif
769 : #ifdef VWERASE
770 : {"VWERASE", VWERASE},
771 : #endif
772 : #ifdef VLNEXT
773 : {"VLNEXT", VLNEXT},
774 : #endif
775 : #ifdef VEOL2
776 : {"VEOL2", VEOL2},
777 : #endif
778 :
779 :
780 : #ifdef B460800
781 : {"B460800", B460800},
782 : #endif
783 : #ifdef B500000
784 : {"B500000", B500000},
785 : #endif
786 : #ifdef B576000
787 : { "B576000", B576000},
788 : #endif
789 : #ifdef B921600
790 : { "B921600", B921600},
791 : #endif
792 : #ifdef B1000000
793 : { "B1000000", B1000000},
794 : #endif
795 : #ifdef B1152000
796 : { "B1152000", B1152000},
797 : #endif
798 : #ifdef B1500000
799 : { "B1500000", B1500000},
800 : #endif
801 : #ifdef B2000000
802 : { "B2000000", B2000000},
803 : #endif
804 : #ifdef B2500000
805 : { "B2500000", B2500000},
806 : #endif
807 : #ifdef B3000000
808 : { "B3000000", B3000000},
809 : #endif
810 : #ifdef B3500000
811 : { "B3500000", B3500000},
812 : #endif
813 : #ifdef B4000000
814 : { "B4000000", B4000000},
815 : #endif
816 : #ifdef CBAUD
817 : {"CBAUD", CBAUD},
818 : #endif
819 : #ifdef CDEL
820 : {"CDEL", CDEL},
821 : #endif
822 : #ifdef CDSUSP
823 : {"CDSUSP", CDSUSP},
824 : #endif
825 : #ifdef CEOF
826 : {"CEOF", CEOF},
827 : #endif
828 : #ifdef CEOL
829 : {"CEOL", CEOL},
830 : #endif
831 : #ifdef CEOL2
832 : {"CEOL2", CEOL2},
833 : #endif
834 : #ifdef CEOT
835 : {"CEOT", CEOT},
836 : #endif
837 : #ifdef CERASE
838 : {"CERASE", CERASE},
839 : #endif
840 : #ifdef CESC
841 : {"CESC", CESC},
842 : #endif
843 : #ifdef CFLUSH
844 : {"CFLUSH", CFLUSH},
845 : #endif
846 : #ifdef CINTR
847 : {"CINTR", CINTR},
848 : #endif
849 : #ifdef CKILL
850 : {"CKILL", CKILL},
851 : #endif
852 : #ifdef CLNEXT
853 : {"CLNEXT", CLNEXT},
854 : #endif
855 : #ifdef CNUL
856 : {"CNUL", CNUL},
857 : #endif
858 : #ifdef COMMON
859 : {"COMMON", COMMON},
860 : #endif
861 : #ifdef CQUIT
862 : {"CQUIT", CQUIT},
863 : #endif
864 : #ifdef CRPRNT
865 : {"CRPRNT", CRPRNT},
866 : #endif
867 : #ifdef CSTART
868 : {"CSTART", CSTART},
869 : #endif
870 : #ifdef CSTOP
871 : {"CSTOP", CSTOP},
872 : #endif
873 : #ifdef CSUSP
874 : {"CSUSP", CSUSP},
875 : #endif
876 : #ifdef CSWTCH
877 : {"CSWTCH", CSWTCH},
878 : #endif
879 : #ifdef CWERASE
880 : {"CWERASE", CWERASE},
881 : #endif
882 : #ifdef EXTA
883 : {"EXTA", EXTA},
884 : #endif
885 : #ifdef EXTB
886 : {"EXTB", EXTB},
887 : #endif
888 : #ifdef FIOASYNC
889 : {"FIOASYNC", FIOASYNC},
890 : #endif
891 : #ifdef FIOCLEX
892 : {"FIOCLEX", FIOCLEX},
893 : #endif
894 : #ifdef FIONBIO
895 : {"FIONBIO", FIONBIO},
896 : #endif
897 : #ifdef FIONCLEX
898 : {"FIONCLEX", FIONCLEX},
899 : #endif
900 : #ifdef FIONREAD
901 : {"FIONREAD", FIONREAD},
902 : #endif
903 : #ifdef IBSHIFT
904 : {"IBSHIFT", IBSHIFT},
905 : #endif
906 : #ifdef INIT_C_CC
907 : {"INIT_C_CC", INIT_C_CC},
908 : #endif
909 : #ifdef IOCSIZE_MASK
910 : {"IOCSIZE_MASK", IOCSIZE_MASK},
911 : #endif
912 : #ifdef IOCSIZE_SHIFT
913 : {"IOCSIZE_SHIFT", IOCSIZE_SHIFT},
914 : #endif
915 : #ifdef NCC
916 : {"NCC", NCC},
917 : #endif
918 : #ifdef NCCS
919 : {"NCCS", NCCS},
920 : #endif
921 : #ifdef NSWTCH
922 : {"NSWTCH", NSWTCH},
923 : #endif
924 : #ifdef N_MOUSE
925 : {"N_MOUSE", N_MOUSE},
926 : #endif
927 : #ifdef N_PPP
928 : {"N_PPP", N_PPP},
929 : #endif
930 : #ifdef N_SLIP
931 : {"N_SLIP", N_SLIP},
932 : #endif
933 : #ifdef N_STRIP
934 : {"N_STRIP", N_STRIP},
935 : #endif
936 : #ifdef N_TTY
937 : {"N_TTY", N_TTY},
938 : #endif
939 : #ifdef TCFLSH
940 : {"TCFLSH", TCFLSH},
941 : #endif
942 : #ifdef TCGETA
943 : {"TCGETA", TCGETA},
944 : #endif
945 : #ifdef TCGETS
946 : {"TCGETS", TCGETS},
947 : #endif
948 : #ifdef TCSBRK
949 : {"TCSBRK", TCSBRK},
950 : #endif
951 : #ifdef TCSBRKP
952 : {"TCSBRKP", TCSBRKP},
953 : #endif
954 : #ifdef TCSETA
955 : {"TCSETA", TCSETA},
956 : #endif
957 : #ifdef TCSETAF
958 : {"TCSETAF", TCSETAF},
959 : #endif
960 : #ifdef TCSETAW
961 : {"TCSETAW", TCSETAW},
962 : #endif
963 : #ifdef TCSETS
964 : {"TCSETS", TCSETS},
965 : #endif
966 : #ifdef TCSETSF
967 : {"TCSETSF", TCSETSF},
968 : #endif
969 : #ifdef TCSETSW
970 : {"TCSETSW", TCSETSW},
971 : #endif
972 : #ifdef TCXONC
973 : {"TCXONC", TCXONC},
974 : #endif
975 : #ifdef TIOCCONS
976 : {"TIOCCONS", TIOCCONS},
977 : #endif
978 : #ifdef TIOCEXCL
979 : {"TIOCEXCL", TIOCEXCL},
980 : #endif
981 : #ifdef TIOCGETD
982 : {"TIOCGETD", TIOCGETD},
983 : #endif
984 : #ifdef TIOCGICOUNT
985 : {"TIOCGICOUNT", TIOCGICOUNT},
986 : #endif
987 : #ifdef TIOCGLCKTRMIOS
988 : {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS},
989 : #endif
990 : #ifdef TIOCGPGRP
991 : {"TIOCGPGRP", TIOCGPGRP},
992 : #endif
993 : #ifdef TIOCGSERIAL
994 : {"TIOCGSERIAL", TIOCGSERIAL},
995 : #endif
996 : #ifdef TIOCGSIZE
997 : {"TIOCGSIZE", TIOCGSIZE},
998 : #endif
999 : #ifdef TIOCGSOFTCAR
1000 : {"TIOCGSOFTCAR", TIOCGSOFTCAR},
1001 : #endif
1002 : #ifdef TIOCGWINSZ
1003 : {"TIOCGWINSZ", TIOCGWINSZ},
1004 : #endif
1005 : #ifdef TIOCINQ
1006 : {"TIOCINQ", TIOCINQ},
1007 : #endif
1008 : #ifdef TIOCLINUX
1009 : {"TIOCLINUX", TIOCLINUX},
1010 : #endif
1011 : #ifdef TIOCMBIC
1012 : {"TIOCMBIC", TIOCMBIC},
1013 : #endif
1014 : #ifdef TIOCMBIS
1015 : {"TIOCMBIS", TIOCMBIS},
1016 : #endif
1017 : #ifdef TIOCMGET
1018 : {"TIOCMGET", TIOCMGET},
1019 : #endif
1020 : #ifdef TIOCMIWAIT
1021 : {"TIOCMIWAIT", TIOCMIWAIT},
1022 : #endif
1023 : #ifdef TIOCMSET
1024 : {"TIOCMSET", TIOCMSET},
1025 : #endif
1026 : #ifdef TIOCM_CAR
1027 : {"TIOCM_CAR", TIOCM_CAR},
1028 : #endif
1029 : #ifdef TIOCM_CD
1030 : {"TIOCM_CD", TIOCM_CD},
1031 : #endif
1032 : #ifdef TIOCM_CTS
1033 : {"TIOCM_CTS", TIOCM_CTS},
1034 : #endif
1035 : #ifdef TIOCM_DSR
1036 : {"TIOCM_DSR", TIOCM_DSR},
1037 : #endif
1038 : #ifdef TIOCM_DTR
1039 : {"TIOCM_DTR", TIOCM_DTR},
1040 : #endif
1041 : #ifdef TIOCM_LE
1042 : {"TIOCM_LE", TIOCM_LE},
1043 : #endif
1044 : #ifdef TIOCM_RI
1045 : {"TIOCM_RI", TIOCM_RI},
1046 : #endif
1047 : #ifdef TIOCM_RNG
1048 : {"TIOCM_RNG", TIOCM_RNG},
1049 : #endif
1050 : #ifdef TIOCM_RTS
1051 : {"TIOCM_RTS", TIOCM_RTS},
1052 : #endif
1053 : #ifdef TIOCM_SR
1054 : {"TIOCM_SR", TIOCM_SR},
1055 : #endif
1056 : #ifdef TIOCM_ST
1057 : {"TIOCM_ST", TIOCM_ST},
1058 : #endif
1059 : #ifdef TIOCNOTTY
1060 : {"TIOCNOTTY", TIOCNOTTY},
1061 : #endif
1062 : #ifdef TIOCNXCL
1063 : {"TIOCNXCL", TIOCNXCL},
1064 : #endif
1065 : #ifdef TIOCOUTQ
1066 : {"TIOCOUTQ", TIOCOUTQ},
1067 : #endif
1068 : #ifdef TIOCPKT
1069 : {"TIOCPKT", TIOCPKT},
1070 : #endif
1071 : #ifdef TIOCPKT_DATA
1072 : {"TIOCPKT_DATA", TIOCPKT_DATA},
1073 : #endif
1074 : #ifdef TIOCPKT_DOSTOP
1075 : {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP},
1076 : #endif
1077 : #ifdef TIOCPKT_FLUSHREAD
1078 : {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD},
1079 : #endif
1080 : #ifdef TIOCPKT_FLUSHWRITE
1081 : {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE},
1082 : #endif
1083 : #ifdef TIOCPKT_NOSTOP
1084 : {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP},
1085 : #endif
1086 : #ifdef TIOCPKT_START
1087 : {"TIOCPKT_START", TIOCPKT_START},
1088 : #endif
1089 : #ifdef TIOCPKT_STOP
1090 : {"TIOCPKT_STOP", TIOCPKT_STOP},
1091 : #endif
1092 : #ifdef TIOCSCTTY
1093 : {"TIOCSCTTY", TIOCSCTTY},
1094 : #endif
1095 : #ifdef TIOCSERCONFIG
1096 : {"TIOCSERCONFIG", TIOCSERCONFIG},
1097 : #endif
1098 : #ifdef TIOCSERGETLSR
1099 : {"TIOCSERGETLSR", TIOCSERGETLSR},
1100 : #endif
1101 : #ifdef TIOCSERGETMULTI
1102 : {"TIOCSERGETMULTI", TIOCSERGETMULTI},
1103 : #endif
1104 : #ifdef TIOCSERGSTRUCT
1105 : {"TIOCSERGSTRUCT", TIOCSERGSTRUCT},
1106 : #endif
1107 : #ifdef TIOCSERGWILD
1108 : {"TIOCSERGWILD", TIOCSERGWILD},
1109 : #endif
1110 : #ifdef TIOCSERSETMULTI
1111 : {"TIOCSERSETMULTI", TIOCSERSETMULTI},
1112 : #endif
1113 : #ifdef TIOCSERSWILD
1114 : {"TIOCSERSWILD", TIOCSERSWILD},
1115 : #endif
1116 : #ifdef TIOCSER_TEMT
1117 : {"TIOCSER_TEMT", TIOCSER_TEMT},
1118 : #endif
1119 : #ifdef TIOCSETD
1120 : {"TIOCSETD", TIOCSETD},
1121 : #endif
1122 : #ifdef TIOCSLCKTRMIOS
1123 : {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS},
1124 : #endif
1125 : #ifdef TIOCSPGRP
1126 : {"TIOCSPGRP", TIOCSPGRP},
1127 : #endif
1128 : #ifdef TIOCSSERIAL
1129 : {"TIOCSSERIAL", TIOCSSERIAL},
1130 : #endif
1131 : #ifdef TIOCSSIZE
1132 : {"TIOCSSIZE", TIOCSSIZE},
1133 : #endif
1134 : #ifdef TIOCSSOFTCAR
1135 : {"TIOCSSOFTCAR", TIOCSSOFTCAR},
1136 : #endif
1137 : #ifdef TIOCSTI
1138 : {"TIOCSTI", TIOCSTI},
1139 : #endif
1140 : #ifdef TIOCSWINSZ
1141 : {"TIOCSWINSZ", TIOCSWINSZ},
1142 : #endif
1143 : #ifdef TIOCTTYGSTRUCT
1144 : {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT},
1145 : #endif
1146 :
1147 : /* sentinel */
1148 : {NULL, 0}
1149 : };
1150 :
1151 41095 : static int termiosmodule_traverse(PyObject *m, visitproc visit, void *arg) {
1152 41095 : Py_VISIT(get_termios_state(m)->TermiosError);
1153 41095 : return 0;
1154 : }
1155 :
1156 1766 : static int termiosmodule_clear(PyObject *m) {
1157 1766 : Py_CLEAR(get_termios_state(m)->TermiosError);
1158 1766 : return 0;
1159 : }
1160 :
1161 1163 : static void termiosmodule_free(void *m) {
1162 1163 : termiosmodule_clear((PyObject *)m);
1163 1163 : }
1164 :
1165 : static int
1166 1165 : termios_exec(PyObject *mod)
1167 : {
1168 1165 : struct constant *constant = termios_constants;
1169 1165 : termiosmodulestate *state = get_termios_state(mod);
1170 1165 : state->TermiosError = PyErr_NewException("termios.error", NULL, NULL);
1171 1165 : if (state->TermiosError == NULL) {
1172 0 : return -1;
1173 : }
1174 1165 : Py_INCREF(state->TermiosError);
1175 1165 : if (PyModule_AddObject(mod, "error", state->TermiosError) < 0) {
1176 0 : Py_DECREF(state->TermiosError);
1177 0 : return -1;
1178 : }
1179 :
1180 284260 : while (constant->name != NULL) {
1181 283095 : if (PyModule_AddIntConstant(
1182 283095 : mod, constant->name, constant->value) < 0) {
1183 0 : return -1;
1184 : }
1185 283095 : ++constant;
1186 : }
1187 1165 : return 0;
1188 : }
1189 :
1190 : static PyModuleDef_Slot termios_slots[] = {
1191 : {Py_mod_exec, termios_exec},
1192 : {0, NULL}
1193 : };
1194 :
1195 : static struct PyModuleDef termiosmodule = {
1196 : PyModuleDef_HEAD_INIT,
1197 : .m_name = "termios",
1198 : .m_doc = termios__doc__,
1199 : .m_size = sizeof(termiosmodulestate),
1200 : .m_methods = termios_methods,
1201 : .m_slots = termios_slots,
1202 : .m_traverse = termiosmodule_traverse,
1203 : .m_clear = termiosmodule_clear,
1204 : .m_free = termiosmodule_free,
1205 : };
1206 :
1207 1165 : PyMODINIT_FUNC PyInit_termios(void)
1208 : {
1209 1165 : return PyModuleDef_Init(&termiosmodule);
1210 : }
|