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 | get_termios_state(PyObject *module) |
55 | { |
56 | void *state = PyModule_GetState(module); |
57 | assert(state != NULL); |
58 | 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 | termios_tcgetattr_impl(PyObject *module, int fd) |
81 | /*[clinic end generated code: output=2b3da39db870e629 input=54dad9779ebe74b1]*/ |
82 | { |
83 | termiosmodulestate *state = PyModule_GetState(module); |
84 | struct termios mode; |
85 | if (tcgetattr(fd, &mode) == -1) { |
86 | return PyErr_SetFromErrno(state->TermiosError); |
87 | } |
88 | |
89 | speed_t ispeed = cfgetispeed(&mode); |
90 | speed_t ospeed = cfgetospeed(&mode); |
91 | |
92 | PyObject *cc = PyList_New(NCCS); |
93 | if (cc == NULL) { |
94 | return NULL; |
95 | } |
96 | |
97 | PyObject *v; |
98 | int i; |
99 | for (i = 0; i < NCCS; i++) { |
100 | char ch = (char)mode.c_cc[i]; |
101 | v = PyBytes_FromStringAndSize(&ch, 1); |
102 | if (v == NULL) |
103 | goto err; |
104 | 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 | if ((mode.c_lflag & ICANON) == 0) { |
111 | v = PyLong_FromLong((long)mode.c_cc[VMIN]); |
112 | if (v == NULL) |
113 | goto err; |
114 | PyList_SetItem(cc, VMIN, v); |
115 | v = PyLong_FromLong((long)mode.c_cc[VTIME]); |
116 | if (v == NULL) |
117 | goto err; |
118 | PyList_SetItem(cc, VTIME, v); |
119 | } |
120 | |
121 | if (!(v = PyList_New(7))) |
122 | goto err; |
123 | |
124 | PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag)); |
125 | PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag)); |
126 | PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag)); |
127 | PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag)); |
128 | PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed)); |
129 | PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed)); |
130 | if (PyErr_Occurred()) { |
131 | Py_DECREF(v); |
132 | goto err; |
133 | } |
134 | PyList_SetItem(v, 6, cc); |
135 | return v; |
136 | err: |
137 | Py_DECREF(cc); |
138 | 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 | termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term) |
161 | /*[clinic end generated code: output=bcd2b0a7b98a4bf5 input=5dafabdd5a08f018]*/ |
162 | { |
163 | if (!PyList_Check(term) || PyList_Size(term) != 7) { |
164 | PyErr_SetString(PyExc_TypeError, |
165 | "tcsetattr, arg 3: must be 7 element list" ); |
166 | return NULL; |
167 | } |
168 | |
169 | /* Get the old mode, in case there are any hidden fields... */ |
170 | termiosmodulestate *state = PyModule_GetState(module); |
171 | struct termios mode; |
172 | if (tcgetattr(fd, &mode) == -1) { |
173 | return PyErr_SetFromErrno(state->TermiosError); |
174 | } |
175 | |
176 | mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0)); |
177 | mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1)); |
178 | mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2)); |
179 | mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3)); |
180 | speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4)); |
181 | speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5)); |
182 | PyObject *cc = PyList_GetItem(term, 6); |
183 | if (PyErr_Occurred()) { |
184 | return NULL; |
185 | } |
186 | |
187 | if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) { |
188 | PyErr_Format(PyExc_TypeError, |
189 | "tcsetattr: attributes[6] must be %d element list" , |
190 | NCCS); |
191 | return NULL; |
192 | } |
193 | |
194 | int i; |
195 | PyObject *v; |
196 | for (i = 0; i < NCCS; i++) { |
197 | v = PyList_GetItem(cc, i); |
198 | |
199 | if (PyBytes_Check(v) && PyBytes_Size(v) == 1) |
200 | mode.c_cc[i] = (cc_t) * PyBytes_AsString(v); |
201 | else if (PyLong_Check(v)) |
202 | mode.c_cc[i] = (cc_t) PyLong_AsLong(v); |
203 | else { |
204 | PyErr_SetString(PyExc_TypeError, |
205 | "tcsetattr: elements of attributes must be characters or integers" ); |
206 | return NULL; |
207 | } |
208 | } |
209 | |
210 | if (cfsetispeed(&mode, (speed_t) ispeed) == -1) |
211 | return PyErr_SetFromErrno(state->TermiosError); |
212 | if (cfsetospeed(&mode, (speed_t) ospeed) == -1) |
213 | return PyErr_SetFromErrno(state->TermiosError); |
214 | if (tcsetattr(fd, when, &mode) == -1) |
215 | return PyErr_SetFromErrno(state->TermiosError); |
216 | |
217 | 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 | termios_tcsendbreak_impl(PyObject *module, int fd, int duration) |
235 | /*[clinic end generated code: output=5945f589b5d3ac66 input=dc2f32417691f8ed]*/ |
236 | { |
237 | termiosmodulestate *state = PyModule_GetState(module); |
238 | if (tcsendbreak(fd, duration) == -1) { |
239 | return PyErr_SetFromErrno(state->TermiosError); |
240 | } |
241 | |
242 | 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 | termios_tcdrain_impl(PyObject *module, int fd) |
256 | /*[clinic end generated code: output=5fd86944c6255955 input=c99241b140b32447]*/ |
257 | { |
258 | termiosmodulestate *state = PyModule_GetState(module); |
259 | if (tcdrain(fd) == -1) { |
260 | return PyErr_SetFromErrno(state->TermiosError); |
261 | } |
262 | |
263 | 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 | termios_tcflush_impl(PyObject *module, int fd, int queue) |
282 | /*[clinic end generated code: output=2424f80312ec2f21 input=0f7d08122ddc07b5]*/ |
283 | { |
284 | termiosmodulestate *state = PyModule_GetState(module); |
285 | if (tcflush(fd, queue) == -1) { |
286 | return PyErr_SetFromErrno(state->TermiosError); |
287 | } |
288 | |
289 | 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 | termios_tcflow_impl(PyObject *module, int fd, int action) |
308 | /*[clinic end generated code: output=afd10928e6ea66eb input=c6aff0640b6efd9c]*/ |
309 | { |
310 | termiosmodulestate *state = PyModule_GetState(module); |
311 | if (tcflow(fd, action) == -1) { |
312 | return PyErr_SetFromErrno(state->TermiosError); |
313 | } |
314 | |
315 | Py_RETURN_NONE; |
316 | } |
317 | |
318 | static PyMethodDef termios_methods[] = |
319 | { |
320 | TERMIOS_TCGETATTR_METHODDEF |
321 | TERMIOS_TCSETATTR_METHODDEF |
322 | TERMIOS_TCSENDBREAK_METHODDEF |
323 | TERMIOS_TCDRAIN_METHODDEF |
324 | TERMIOS_TCFLUSH_METHODDEF |
325 | TERMIOS_TCFLOW_METHODDEF |
326 | {NULL, NULL} |
327 | }; |
328 | |
329 | |
330 | #if defined(VSWTCH) && !defined(VSWTC) |
331 | #define VSWTC VSWTCH |
332 | #endif |
333 | |
334 | #if defined(VSWTC) && !defined(VSWTCH) |
335 | #define VSWTCH VSWTC |
336 | #endif |
337 | |
338 | static struct constant { |
339 | char *name; |
340 | long value; |
341 | } termios_constants[] = { |
342 | /* cfgetospeed(), cfsetospeed() constants */ |
343 | {"B0" , B0}, |
344 | {"B50" , B50}, |
345 | {"B75" , B75}, |
346 | {"B110" , B110}, |
347 | {"B134" , B134}, |
348 | {"B150" , B150}, |
349 | {"B200" , B200}, |
350 | {"B300" , B300}, |
351 | {"B600" , B600}, |
352 | {"B1200" , B1200}, |
353 | {"B1800" , B1800}, |
354 | {"B2400" , B2400}, |
355 | {"B4800" , B4800}, |
356 | {"B9600" , B9600}, |
357 | {"B19200" , B19200}, |
358 | {"B38400" , B38400}, |
359 | #ifdef B57600 |
360 | {"B57600" , B57600}, |
361 | #endif |
362 | #ifdef B115200 |
363 | {"B115200" , B115200}, |
364 | #endif |
365 | #ifdef B230400 |
366 | {"B230400" , B230400}, |
367 | #endif |
368 | #ifdef B460800 |
369 | {"B460800" , B460800}, |
370 | #endif |
371 | #ifdef B500000 |
372 | {"B500000" , B500000}, |
373 | #endif |
374 | #ifdef B576000 |
375 | {"B576000" , B576000}, |
376 | #endif |
377 | #ifdef B921600 |
378 | {"B921600" , B921600}, |
379 | #endif |
380 | #ifdef B1000000 |
381 | {"B1000000" , B1000000}, |
382 | #endif |
383 | #ifdef B1152000 |
384 | {"B1152000" , B1152000}, |
385 | #endif |
386 | #ifdef B1500000 |
387 | {"B1500000" , B1500000}, |
388 | #endif |
389 | #ifdef B2000000 |
390 | {"B2000000" , B2000000}, |
391 | #endif |
392 | #ifdef B2500000 |
393 | {"B2500000" , B2500000}, |
394 | #endif |
395 | #ifdef B3000000 |
396 | {"B3000000" , B3000000}, |
397 | #endif |
398 | #ifdef B3500000 |
399 | {"B3500000" , B3500000}, |
400 | #endif |
401 | #ifdef B4000000 |
402 | {"B4000000" , B4000000}, |
403 | #endif |
404 | |
405 | #ifdef CBAUDEX |
406 | {"CBAUDEX" , CBAUDEX}, |
407 | #endif |
408 | |
409 | /* tcsetattr() constants */ |
410 | {"TCSANOW" , TCSANOW}, |
411 | {"TCSADRAIN" , TCSADRAIN}, |
412 | {"TCSAFLUSH" , TCSAFLUSH}, |
413 | #ifdef TCSASOFT |
414 | {"TCSASOFT" , TCSASOFT}, |
415 | #endif |
416 | |
417 | /* tcflush() constants */ |
418 | {"TCIFLUSH" , TCIFLUSH}, |
419 | {"TCOFLUSH" , TCOFLUSH}, |
420 | {"TCIOFLUSH" , TCIOFLUSH}, |
421 | |
422 | /* tcflow() constants */ |
423 | {"TCOOFF" , TCOOFF}, |
424 | {"TCOON" , TCOON}, |
425 | {"TCIOFF" , TCIOFF}, |
426 | {"TCION" , TCION}, |
427 | |
428 | /* struct termios.c_iflag constants */ |
429 | {"IGNBRK" , IGNBRK}, |
430 | {"BRKINT" , BRKINT}, |
431 | {"IGNPAR" , IGNPAR}, |
432 | {"PARMRK" , PARMRK}, |
433 | {"INPCK" , INPCK}, |
434 | {"ISTRIP" , ISTRIP}, |
435 | {"INLCR" , INLCR}, |
436 | {"IGNCR" , IGNCR}, |
437 | {"ICRNL" , ICRNL}, |
438 | #ifdef IUCLC |
439 | {"IUCLC" , IUCLC}, |
440 | #endif |
441 | {"IXON" , IXON}, |
442 | {"IXANY" , IXANY}, |
443 | {"IXOFF" , IXOFF}, |
444 | #ifdef IMAXBEL |
445 | {"IMAXBEL" , IMAXBEL}, |
446 | #endif |
447 | |
448 | /* struct termios.c_oflag constants */ |
449 | {"OPOST" , OPOST}, |
450 | #ifdef OLCUC |
451 | {"OLCUC" , OLCUC}, |
452 | #endif |
453 | #ifdef ONLCR |
454 | {"ONLCR" , ONLCR}, |
455 | #endif |
456 | #ifdef OCRNL |
457 | {"OCRNL" , OCRNL}, |
458 | #endif |
459 | #ifdef ONOCR |
460 | {"ONOCR" , ONOCR}, |
461 | #endif |
462 | #ifdef ONLRET |
463 | {"ONLRET" , ONLRET}, |
464 | #endif |
465 | #ifdef OFILL |
466 | {"OFILL" , OFILL}, |
467 | #endif |
468 | #ifdef OFDEL |
469 | {"OFDEL" , OFDEL}, |
470 | #endif |
471 | #ifdef NLDLY |
472 | {"NLDLY" , NLDLY}, |
473 | #endif |
474 | #ifdef CRDLY |
475 | {"CRDLY" , CRDLY}, |
476 | #endif |
477 | #ifdef TABDLY |
478 | {"TABDLY" , TABDLY}, |
479 | #endif |
480 | #ifdef BSDLY |
481 | {"BSDLY" , BSDLY}, |
482 | #endif |
483 | #ifdef VTDLY |
484 | {"VTDLY" , VTDLY}, |
485 | #endif |
486 | #ifdef FFDLY |
487 | {"FFDLY" , FFDLY}, |
488 | #endif |
489 | |
490 | /* struct termios.c_oflag-related values (delay mask) */ |
491 | #ifdef NL0 |
492 | {"NL0" , NL0}, |
493 | #endif |
494 | #ifdef NL1 |
495 | {"NL1" , NL1}, |
496 | #endif |
497 | #ifdef CR0 |
498 | {"CR0" , CR0}, |
499 | #endif |
500 | #ifdef CR1 |
501 | {"CR1" , CR1}, |
502 | #endif |
503 | #ifdef CR2 |
504 | {"CR2" , CR2}, |
505 | #endif |
506 | #ifdef CR3 |
507 | {"CR3" , CR3}, |
508 | #endif |
509 | #ifdef TAB0 |
510 | {"TAB0" , TAB0}, |
511 | #endif |
512 | #ifdef TAB1 |
513 | {"TAB1" , TAB1}, |
514 | #endif |
515 | #ifdef TAB2 |
516 | {"TAB2" , TAB2}, |
517 | #endif |
518 | #ifdef TAB3 |
519 | {"TAB3" , TAB3}, |
520 | #endif |
521 | #ifdef XTABS |
522 | {"XTABS" , XTABS}, |
523 | #endif |
524 | #ifdef BS0 |
525 | {"BS0" , BS0}, |
526 | #endif |
527 | #ifdef BS1 |
528 | {"BS1" , BS1}, |
529 | #endif |
530 | #ifdef VT0 |
531 | {"VT0" , VT0}, |
532 | #endif |
533 | #ifdef VT1 |
534 | {"VT1" , VT1}, |
535 | #endif |
536 | #ifdef FF0 |
537 | {"FF0" , FF0}, |
538 | #endif |
539 | #ifdef FF1 |
540 | {"FF1" , FF1}, |
541 | #endif |
542 | |
543 | /* struct termios.c_cflag constants */ |
544 | {"CSIZE" , CSIZE}, |
545 | {"CSTOPB" , CSTOPB}, |
546 | {"CREAD" , CREAD}, |
547 | {"PARENB" , PARENB}, |
548 | {"PARODD" , PARODD}, |
549 | {"HUPCL" , HUPCL}, |
550 | {"CLOCAL" , CLOCAL}, |
551 | #ifdef CIBAUD |
552 | {"CIBAUD" , CIBAUD}, |
553 | #endif |
554 | #ifdef CRTSCTS |
555 | {"CRTSCTS" , (long)CRTSCTS}, |
556 | #endif |
557 | |
558 | /* struct termios.c_cflag-related values (character size) */ |
559 | {"CS5" , CS5}, |
560 | {"CS6" , CS6}, |
561 | {"CS7" , CS7}, |
562 | {"CS8" , CS8}, |
563 | |
564 | /* struct termios.c_lflag constants */ |
565 | {"ISIG" , ISIG}, |
566 | {"ICANON" , ICANON}, |
567 | #ifdef XCASE |
568 | {"XCASE" , XCASE}, |
569 | #endif |
570 | {"ECHO" , ECHO}, |
571 | {"ECHOE" , ECHOE}, |
572 | {"ECHOK" , ECHOK}, |
573 | {"ECHONL" , ECHONL}, |
574 | #ifdef ECHOCTL |
575 | {"ECHOCTL" , ECHOCTL}, |
576 | #endif |
577 | #ifdef ECHOPRT |
578 | {"ECHOPRT" , ECHOPRT}, |
579 | #endif |
580 | #ifdef ECHOKE |
581 | {"ECHOKE" , ECHOKE}, |
582 | #endif |
583 | #ifdef FLUSHO |
584 | {"FLUSHO" , FLUSHO}, |
585 | #endif |
586 | {"NOFLSH" , NOFLSH}, |
587 | {"TOSTOP" , TOSTOP}, |
588 | #ifdef PENDIN |
589 | {"PENDIN" , PENDIN}, |
590 | #endif |
591 | {"IEXTEN" , IEXTEN}, |
592 | |
593 | /* indexes into the control chars array returned by tcgetattr() */ |
594 | {"VINTR" , VINTR}, |
595 | {"VQUIT" , VQUIT}, |
596 | {"VERASE" , VERASE}, |
597 | {"VKILL" , VKILL}, |
598 | {"VEOF" , VEOF}, |
599 | {"VTIME" , VTIME}, |
600 | {"VMIN" , VMIN}, |
601 | #ifdef VSWTC |
602 | /* The #defines above ensure that if either is defined, both are, |
603 | * but both may be omitted by the system headers. ;-( */ |
604 | {"VSWTC" , VSWTC}, |
605 | {"VSWTCH" , VSWTCH}, |
606 | #endif |
607 | {"VSTART" , VSTART}, |
608 | {"VSTOP" , VSTOP}, |
609 | {"VSUSP" , VSUSP}, |
610 | {"VEOL" , VEOL}, |
611 | #ifdef VREPRINT |
612 | {"VREPRINT" , VREPRINT}, |
613 | #endif |
614 | #ifdef VDISCARD |
615 | {"VDISCARD" , VDISCARD}, |
616 | #endif |
617 | #ifdef VWERASE |
618 | {"VWERASE" , VWERASE}, |
619 | #endif |
620 | #ifdef VLNEXT |
621 | {"VLNEXT" , VLNEXT}, |
622 | #endif |
623 | #ifdef VEOL2 |
624 | {"VEOL2" , VEOL2}, |
625 | #endif |
626 | |
627 | |
628 | #ifdef B460800 |
629 | {"B460800" , B460800}, |
630 | #endif |
631 | #ifdef B500000 |
632 | {"B500000" , B500000}, |
633 | #endif |
634 | #ifdef B576000 |
635 | { "B576000" , B576000}, |
636 | #endif |
637 | #ifdef B921600 |
638 | { "B921600" , B921600}, |
639 | #endif |
640 | #ifdef B1000000 |
641 | { "B1000000" , B1000000}, |
642 | #endif |
643 | #ifdef B1152000 |
644 | { "B1152000" , B1152000}, |
645 | #endif |
646 | #ifdef B1500000 |
647 | { "B1500000" , B1500000}, |
648 | #endif |
649 | #ifdef B2000000 |
650 | { "B2000000" , B2000000}, |
651 | #endif |
652 | #ifdef B2500000 |
653 | { "B2500000" , B2500000}, |
654 | #endif |
655 | #ifdef B3000000 |
656 | { "B3000000" , B3000000}, |
657 | #endif |
658 | #ifdef B3500000 |
659 | { "B3500000" , B3500000}, |
660 | #endif |
661 | #ifdef B4000000 |
662 | { "B4000000" , B4000000}, |
663 | #endif |
664 | #ifdef CBAUD |
665 | {"CBAUD" , CBAUD}, |
666 | #endif |
667 | #ifdef CDEL |
668 | {"CDEL" , CDEL}, |
669 | #endif |
670 | #ifdef CDSUSP |
671 | {"CDSUSP" , CDSUSP}, |
672 | #endif |
673 | #ifdef CEOF |
674 | {"CEOF" , CEOF}, |
675 | #endif |
676 | #ifdef CEOL |
677 | {"CEOL" , CEOL}, |
678 | #endif |
679 | #ifdef CEOL2 |
680 | {"CEOL2" , CEOL2}, |
681 | #endif |
682 | #ifdef CEOT |
683 | {"CEOT" , CEOT}, |
684 | #endif |
685 | #ifdef CERASE |
686 | {"CERASE" , CERASE}, |
687 | #endif |
688 | #ifdef CESC |
689 | {"CESC" , CESC}, |
690 | #endif |
691 | #ifdef CFLUSH |
692 | {"CFLUSH" , CFLUSH}, |
693 | #endif |
694 | #ifdef CINTR |
695 | {"CINTR" , CINTR}, |
696 | #endif |
697 | #ifdef CKILL |
698 | {"CKILL" , CKILL}, |
699 | #endif |
700 | #ifdef CLNEXT |
701 | {"CLNEXT" , CLNEXT}, |
702 | #endif |
703 | #ifdef CNUL |
704 | {"CNUL" , CNUL}, |
705 | #endif |
706 | #ifdef COMMON |
707 | {"COMMON" , COMMON}, |
708 | #endif |
709 | #ifdef CQUIT |
710 | {"CQUIT" , CQUIT}, |
711 | #endif |
712 | #ifdef CRPRNT |
713 | {"CRPRNT" , CRPRNT}, |
714 | #endif |
715 | #ifdef CSTART |
716 | {"CSTART" , CSTART}, |
717 | #endif |
718 | #ifdef CSTOP |
719 | {"CSTOP" , CSTOP}, |
720 | #endif |
721 | #ifdef CSUSP |
722 | {"CSUSP" , CSUSP}, |
723 | #endif |
724 | #ifdef CSWTCH |
725 | {"CSWTCH" , CSWTCH}, |
726 | #endif |
727 | #ifdef CWERASE |
728 | {"CWERASE" , CWERASE}, |
729 | #endif |
730 | #ifdef EXTA |
731 | {"EXTA" , EXTA}, |
732 | #endif |
733 | #ifdef EXTB |
734 | {"EXTB" , EXTB}, |
735 | #endif |
736 | #ifdef FIOASYNC |
737 | {"FIOASYNC" , FIOASYNC}, |
738 | #endif |
739 | #ifdef FIOCLEX |
740 | {"FIOCLEX" , FIOCLEX}, |
741 | #endif |
742 | #ifdef FIONBIO |
743 | {"FIONBIO" , FIONBIO}, |
744 | #endif |
745 | #ifdef FIONCLEX |
746 | {"FIONCLEX" , FIONCLEX}, |
747 | #endif |
748 | #ifdef FIONREAD |
749 | {"FIONREAD" , FIONREAD}, |
750 | #endif |
751 | #ifdef IBSHIFT |
752 | {"IBSHIFT" , IBSHIFT}, |
753 | #endif |
754 | #ifdef INIT_C_CC |
755 | {"INIT_C_CC" , INIT_C_CC}, |
756 | #endif |
757 | #ifdef IOCSIZE_MASK |
758 | {"IOCSIZE_MASK" , IOCSIZE_MASK}, |
759 | #endif |
760 | #ifdef IOCSIZE_SHIFT |
761 | {"IOCSIZE_SHIFT" , IOCSIZE_SHIFT}, |
762 | #endif |
763 | #ifdef NCC |
764 | {"NCC" , NCC}, |
765 | #endif |
766 | #ifdef NCCS |
767 | {"NCCS" , NCCS}, |
768 | #endif |
769 | #ifdef NSWTCH |
770 | {"NSWTCH" , NSWTCH}, |
771 | #endif |
772 | #ifdef N_MOUSE |
773 | {"N_MOUSE" , N_MOUSE}, |
774 | #endif |
775 | #ifdef N_PPP |
776 | {"N_PPP" , N_PPP}, |
777 | #endif |
778 | #ifdef N_SLIP |
779 | {"N_SLIP" , N_SLIP}, |
780 | #endif |
781 | #ifdef N_STRIP |
782 | {"N_STRIP" , N_STRIP}, |
783 | #endif |
784 | #ifdef N_TTY |
785 | {"N_TTY" , N_TTY}, |
786 | #endif |
787 | #ifdef TCFLSH |
788 | {"TCFLSH" , TCFLSH}, |
789 | #endif |
790 | #ifdef TCGETA |
791 | {"TCGETA" , TCGETA}, |
792 | #endif |
793 | #ifdef TCGETS |
794 | {"TCGETS" , TCGETS}, |
795 | #endif |
796 | #ifdef TCSBRK |
797 | {"TCSBRK" , TCSBRK}, |
798 | #endif |
799 | #ifdef TCSBRKP |
800 | {"TCSBRKP" , TCSBRKP}, |
801 | #endif |
802 | #ifdef TCSETA |
803 | {"TCSETA" , TCSETA}, |
804 | #endif |
805 | #ifdef TCSETAF |
806 | {"TCSETAF" , TCSETAF}, |
807 | #endif |
808 | #ifdef TCSETAW |
809 | {"TCSETAW" , TCSETAW}, |
810 | #endif |
811 | #ifdef TCSETS |
812 | {"TCSETS" , TCSETS}, |
813 | #endif |
814 | #ifdef TCSETSF |
815 | {"TCSETSF" , TCSETSF}, |
816 | #endif |
817 | #ifdef TCSETSW |
818 | {"TCSETSW" , TCSETSW}, |
819 | #endif |
820 | #ifdef TCXONC |
821 | {"TCXONC" , TCXONC}, |
822 | #endif |
823 | #ifdef TIOCCONS |
824 | {"TIOCCONS" , TIOCCONS}, |
825 | #endif |
826 | #ifdef TIOCEXCL |
827 | {"TIOCEXCL" , TIOCEXCL}, |
828 | #endif |
829 | #ifdef TIOCGETD |
830 | {"TIOCGETD" , TIOCGETD}, |
831 | #endif |
832 | #ifdef TIOCGICOUNT |
833 | {"TIOCGICOUNT" , TIOCGICOUNT}, |
834 | #endif |
835 | #ifdef TIOCGLCKTRMIOS |
836 | {"TIOCGLCKTRMIOS" , TIOCGLCKTRMIOS}, |
837 | #endif |
838 | #ifdef TIOCGPGRP |
839 | {"TIOCGPGRP" , TIOCGPGRP}, |
840 | #endif |
841 | #ifdef TIOCGSERIAL |
842 | {"TIOCGSERIAL" , TIOCGSERIAL}, |
843 | #endif |
844 | #ifdef TIOCGSOFTCAR |
845 | {"TIOCGSOFTCAR" , TIOCGSOFTCAR}, |
846 | #endif |
847 | #ifdef TIOCGWINSZ |
848 | {"TIOCGWINSZ" , TIOCGWINSZ}, |
849 | #endif |
850 | #ifdef TIOCINQ |
851 | {"TIOCINQ" , TIOCINQ}, |
852 | #endif |
853 | #ifdef TIOCLINUX |
854 | {"TIOCLINUX" , TIOCLINUX}, |
855 | #endif |
856 | #ifdef TIOCMBIC |
857 | {"TIOCMBIC" , TIOCMBIC}, |
858 | #endif |
859 | #ifdef TIOCMBIS |
860 | {"TIOCMBIS" , TIOCMBIS}, |
861 | #endif |
862 | #ifdef TIOCMGET |
863 | {"TIOCMGET" , TIOCMGET}, |
864 | #endif |
865 | #ifdef TIOCMIWAIT |
866 | {"TIOCMIWAIT" , TIOCMIWAIT}, |
867 | #endif |
868 | #ifdef TIOCMSET |
869 | {"TIOCMSET" , TIOCMSET}, |
870 | #endif |
871 | #ifdef TIOCM_CAR |
872 | {"TIOCM_CAR" , TIOCM_CAR}, |
873 | #endif |
874 | #ifdef TIOCM_CD |
875 | {"TIOCM_CD" , TIOCM_CD}, |
876 | #endif |
877 | #ifdef TIOCM_CTS |
878 | {"TIOCM_CTS" , TIOCM_CTS}, |
879 | #endif |
880 | #ifdef TIOCM_DSR |
881 | {"TIOCM_DSR" , TIOCM_DSR}, |
882 | #endif |
883 | #ifdef TIOCM_DTR |
884 | {"TIOCM_DTR" , TIOCM_DTR}, |
885 | #endif |
886 | #ifdef TIOCM_LE |
887 | {"TIOCM_LE" , TIOCM_LE}, |
888 | #endif |
889 | #ifdef TIOCM_RI |
890 | {"TIOCM_RI" , TIOCM_RI}, |
891 | #endif |
892 | #ifdef TIOCM_RNG |
893 | {"TIOCM_RNG" , TIOCM_RNG}, |
894 | #endif |
895 | #ifdef TIOCM_RTS |
896 | {"TIOCM_RTS" , TIOCM_RTS}, |
897 | #endif |
898 | #ifdef TIOCM_SR |
899 | {"TIOCM_SR" , TIOCM_SR}, |
900 | #endif |
901 | #ifdef TIOCM_ST |
902 | {"TIOCM_ST" , TIOCM_ST}, |
903 | #endif |
904 | #ifdef TIOCNOTTY |
905 | {"TIOCNOTTY" , TIOCNOTTY}, |
906 | #endif |
907 | #ifdef TIOCNXCL |
908 | {"TIOCNXCL" , TIOCNXCL}, |
909 | #endif |
910 | #ifdef TIOCOUTQ |
911 | {"TIOCOUTQ" , TIOCOUTQ}, |
912 | #endif |
913 | #ifdef TIOCPKT |
914 | {"TIOCPKT" , TIOCPKT}, |
915 | #endif |
916 | #ifdef TIOCPKT_DATA |
917 | {"TIOCPKT_DATA" , TIOCPKT_DATA}, |
918 | #endif |
919 | #ifdef TIOCPKT_DOSTOP |
920 | {"TIOCPKT_DOSTOP" , TIOCPKT_DOSTOP}, |
921 | #endif |
922 | #ifdef TIOCPKT_FLUSHREAD |
923 | {"TIOCPKT_FLUSHREAD" , TIOCPKT_FLUSHREAD}, |
924 | #endif |
925 | #ifdef TIOCPKT_FLUSHWRITE |
926 | {"TIOCPKT_FLUSHWRITE" , TIOCPKT_FLUSHWRITE}, |
927 | #endif |
928 | #ifdef TIOCPKT_NOSTOP |
929 | {"TIOCPKT_NOSTOP" , TIOCPKT_NOSTOP}, |
930 | #endif |
931 | #ifdef TIOCPKT_START |
932 | {"TIOCPKT_START" , TIOCPKT_START}, |
933 | #endif |
934 | #ifdef TIOCPKT_STOP |
935 | {"TIOCPKT_STOP" , TIOCPKT_STOP}, |
936 | #endif |
937 | #ifdef TIOCSCTTY |
938 | {"TIOCSCTTY" , TIOCSCTTY}, |
939 | #endif |
940 | #ifdef TIOCSERCONFIG |
941 | {"TIOCSERCONFIG" , TIOCSERCONFIG}, |
942 | #endif |
943 | #ifdef TIOCSERGETLSR |
944 | {"TIOCSERGETLSR" , TIOCSERGETLSR}, |
945 | #endif |
946 | #ifdef TIOCSERGETMULTI |
947 | {"TIOCSERGETMULTI" , TIOCSERGETMULTI}, |
948 | #endif |
949 | #ifdef TIOCSERGSTRUCT |
950 | {"TIOCSERGSTRUCT" , TIOCSERGSTRUCT}, |
951 | #endif |
952 | #ifdef TIOCSERGWILD |
953 | {"TIOCSERGWILD" , TIOCSERGWILD}, |
954 | #endif |
955 | #ifdef TIOCSERSETMULTI |
956 | {"TIOCSERSETMULTI" , TIOCSERSETMULTI}, |
957 | #endif |
958 | #ifdef TIOCSERSWILD |
959 | {"TIOCSERSWILD" , TIOCSERSWILD}, |
960 | #endif |
961 | #ifdef TIOCSER_TEMT |
962 | {"TIOCSER_TEMT" , TIOCSER_TEMT}, |
963 | #endif |
964 | #ifdef TIOCSETD |
965 | {"TIOCSETD" , TIOCSETD}, |
966 | #endif |
967 | #ifdef TIOCSLCKTRMIOS |
968 | {"TIOCSLCKTRMIOS" , TIOCSLCKTRMIOS}, |
969 | #endif |
970 | #ifdef TIOCSPGRP |
971 | {"TIOCSPGRP" , TIOCSPGRP}, |
972 | #endif |
973 | #ifdef TIOCSSERIAL |
974 | {"TIOCSSERIAL" , TIOCSSERIAL}, |
975 | #endif |
976 | #ifdef TIOCSSOFTCAR |
977 | {"TIOCSSOFTCAR" , TIOCSSOFTCAR}, |
978 | #endif |
979 | #ifdef TIOCSTI |
980 | {"TIOCSTI" , TIOCSTI}, |
981 | #endif |
982 | #ifdef TIOCSWINSZ |
983 | {"TIOCSWINSZ" , TIOCSWINSZ}, |
984 | #endif |
985 | #ifdef TIOCTTYGSTRUCT |
986 | {"TIOCTTYGSTRUCT" , TIOCTTYGSTRUCT}, |
987 | #endif |
988 | |
989 | /* sentinel */ |
990 | {NULL, 0} |
991 | }; |
992 | |
993 | static int termiosmodule_traverse(PyObject *m, visitproc visit, void *arg) { |
994 | Py_VISIT(get_termios_state(m)->TermiosError); |
995 | return 0; |
996 | } |
997 | |
998 | static int termiosmodule_clear(PyObject *m) { |
999 | Py_CLEAR(get_termios_state(m)->TermiosError); |
1000 | return 0; |
1001 | } |
1002 | |
1003 | static void termiosmodule_free(void *m) { |
1004 | termiosmodule_clear((PyObject *)m); |
1005 | } |
1006 | |
1007 | static int |
1008 | termios_exec(PyObject *mod) |
1009 | { |
1010 | struct constant *constant = termios_constants; |
1011 | termiosmodulestate *state = get_termios_state(mod); |
1012 | state->TermiosError = PyErr_NewException("termios.error" , NULL, NULL); |
1013 | if (state->TermiosError == NULL) { |
1014 | return -1; |
1015 | } |
1016 | Py_INCREF(state->TermiosError); |
1017 | if (PyModule_AddObject(mod, "error" , state->TermiosError) < 0) { |
1018 | Py_DECREF(state->TermiosError); |
1019 | return -1; |
1020 | } |
1021 | |
1022 | while (constant->name != NULL) { |
1023 | if (PyModule_AddIntConstant( |
1024 | mod, constant->name, constant->value) < 0) { |
1025 | return -1; |
1026 | } |
1027 | ++constant; |
1028 | } |
1029 | return 0; |
1030 | } |
1031 | |
1032 | static PyModuleDef_Slot termios_slots[] = { |
1033 | {Py_mod_exec, termios_exec}, |
1034 | {0, NULL} |
1035 | }; |
1036 | |
1037 | static struct PyModuleDef termiosmodule = { |
1038 | PyModuleDef_HEAD_INIT, |
1039 | .m_name = "termios" , |
1040 | .m_doc = termios__doc__, |
1041 | .m_size = sizeof(termiosmodulestate), |
1042 | .m_methods = termios_methods, |
1043 | .m_slots = termios_slots, |
1044 | .m_traverse = termiosmodule_traverse, |
1045 | .m_clear = termiosmodule_clear, |
1046 | .m_free = termiosmodule_free, |
1047 | }; |
1048 | |
1049 | PyMODINIT_FUNC PyInit_termios(void) |
1050 | { |
1051 | return PyModuleDef_Init(&termiosmodule); |
1052 | } |
1053 | |