1 /* termiosmodule.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 PyDoc_STRVAR(termios__doc__,
33 "This module provides an interface to the Posix calls for tty I/O control.\n\
34 For a complete description of these calls, see the Posix or Unix manual\n\
35 pages. It is only available for those Unix versions that support Posix\n\
36 termios style tty I/O control.\n\
37 \n\
38 All functions in this module take a file descriptor fd as their first\n\
39 argument. This can be an integer file descriptor, such as returned by\n\
40 sys.stdin.fileno(), or a file object, such as sys.stdin itself.");
41
42 static PyObject *TermiosError;
43
fdconv(PyObject * obj,void * p)44 static int fdconv(PyObject* obj, void* p)
45 {
46 int fd;
47
48 fd = PyObject_AsFileDescriptor(obj);
49 if (fd >= 0) {
50 *(int*)p = fd;
51 return 1;
52 }
53 return 0;
54 }
55
56 PyDoc_STRVAR(termios_tcgetattr__doc__,
57 "tcgetattr(fd) -> list_of_attrs\n\
58 \n\
59 Get the tty attributes for file descriptor fd, as follows:\n\
60 [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\
61 of the tty special characters (each a string of length 1, except the items\n\
62 with indices VMIN and VTIME, which are integers when these fields are\n\
63 defined). The interpretation of the flags and the speeds as well as the\n\
64 indexing in the cc array must be done using the symbolic constants defined\n\
65 in this module.");
66
67 static PyObject *
termios_tcgetattr(PyObject * self,PyObject * args)68 termios_tcgetattr(PyObject *self, PyObject *args)
69 {
70 int fd;
71 struct termios mode;
72 PyObject *cc;
73 speed_t ispeed, ospeed;
74 PyObject *v;
75 int i;
76 char ch;
77
78 if (!PyArg_ParseTuple(args, "O&:tcgetattr",
79 fdconv, (void*)&fd))
80 return NULL;
81
82 if (tcgetattr(fd, &mode) == -1)
83 return PyErr_SetFromErrno(TermiosError);
84
85 ispeed = cfgetispeed(&mode);
86 ospeed = cfgetospeed(&mode);
87
88 cc = PyList_New(NCCS);
89 if (cc == NULL)
90 return NULL;
91 for (i = 0; i < NCCS; i++) {
92 ch = (char)mode.c_cc[i];
93 v = PyBytes_FromStringAndSize(&ch, 1);
94 if (v == NULL)
95 goto err;
96 PyList_SetItem(cc, i, v);
97 }
98
99 /* Convert the MIN and TIME slots to integer. On some systems, the
100 MIN and TIME slots are the same as the EOF and EOL slots. So we
101 only do this in noncanonical input mode. */
102 if ((mode.c_lflag & ICANON) == 0) {
103 v = PyLong_FromLong((long)mode.c_cc[VMIN]);
104 if (v == NULL)
105 goto err;
106 PyList_SetItem(cc, VMIN, v);
107 v = PyLong_FromLong((long)mode.c_cc[VTIME]);
108 if (v == NULL)
109 goto err;
110 PyList_SetItem(cc, VTIME, v);
111 }
112
113 if (!(v = PyList_New(7)))
114 goto err;
115
116 PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag));
117 PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag));
118 PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag));
119 PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag));
120 PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed));
121 PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed));
122 if (PyErr_Occurred()) {
123 Py_DECREF(v);
124 goto err;
125 }
126 PyList_SetItem(v, 6, cc);
127 return v;
128 err:
129 Py_DECREF(cc);
130 return NULL;
131 }
132
133 PyDoc_STRVAR(termios_tcsetattr__doc__,
134 "tcsetattr(fd, when, attributes) -> None\n\
135 \n\
136 Set the tty attributes for file descriptor fd.\n\
137 The attributes to be set are taken from the attributes argument, which\n\
138 is a list like the one returned by tcgetattr(). The when argument\n\
139 determines when the attributes are changed: termios.TCSANOW to\n\
140 change immediately, termios.TCSADRAIN to change after transmitting all\n\
141 queued output, or termios.TCSAFLUSH to change after transmitting all\n\
142 queued output and discarding all queued input. ");
143
144 static PyObject *
termios_tcsetattr(PyObject * self,PyObject * args)145 termios_tcsetattr(PyObject *self, PyObject *args)
146 {
147 int fd, when;
148 struct termios mode;
149 speed_t ispeed, ospeed;
150 PyObject *term, *cc, *v;
151 int i;
152
153 if (!PyArg_ParseTuple(args, "O&iO:tcsetattr",
154 fdconv, &fd, &when, &term))
155 return NULL;
156 if (!PyList_Check(term) || PyList_Size(term) != 7) {
157 PyErr_SetString(PyExc_TypeError,
158 "tcsetattr, arg 3: must be 7 element list");
159 return NULL;
160 }
161
162 /* Get the old mode, in case there are any hidden fields... */
163 if (tcgetattr(fd, &mode) == -1)
164 return PyErr_SetFromErrno(TermiosError);
165 mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
166 mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
167 mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
168 mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3));
169 ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
170 ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
171 cc = PyList_GetItem(term, 6);
172 if (PyErr_Occurred())
173 return NULL;
174
175 if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
176 PyErr_Format(PyExc_TypeError,
177 "tcsetattr: attributes[6] must be %d element list",
178 NCCS);
179 return NULL;
180 }
181
182 for (i = 0; i < NCCS; i++) {
183 v = PyList_GetItem(cc, i);
184
185 if (PyBytes_Check(v) && PyBytes_Size(v) == 1)
186 mode.c_cc[i] = (cc_t) * PyBytes_AsString(v);
187 else if (PyLong_Check(v))
188 mode.c_cc[i] = (cc_t) PyLong_AsLong(v);
189 else {
190 PyErr_SetString(PyExc_TypeError,
191 "tcsetattr: elements of attributes must be characters or integers");
192 return NULL;
193 }
194 }
195
196 if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
197 return PyErr_SetFromErrno(TermiosError);
198 if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
199 return PyErr_SetFromErrno(TermiosError);
200 if (tcsetattr(fd, when, &mode) == -1)
201 return PyErr_SetFromErrno(TermiosError);
202
203 Py_RETURN_NONE;
204 }
205
206 PyDoc_STRVAR(termios_tcsendbreak__doc__,
207 "tcsendbreak(fd, duration) -> None\n\
208 \n\
209 Send a break on file descriptor fd.\n\
210 A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\
211 has a system dependent meaning.");
212
213 static PyObject *
termios_tcsendbreak(PyObject * self,PyObject * args)214 termios_tcsendbreak(PyObject *self, PyObject *args)
215 {
216 int fd, duration;
217
218 if (!PyArg_ParseTuple(args, "O&i:tcsendbreak",
219 fdconv, &fd, &duration))
220 return NULL;
221 if (tcsendbreak(fd, duration) == -1)
222 return PyErr_SetFromErrno(TermiosError);
223
224 Py_RETURN_NONE;
225 }
226
227 PyDoc_STRVAR(termios_tcdrain__doc__,
228 "tcdrain(fd) -> None\n\
229 \n\
230 Wait until all output written to file descriptor fd has been transmitted.");
231
232 static PyObject *
termios_tcdrain(PyObject * self,PyObject * args)233 termios_tcdrain(PyObject *self, PyObject *args)
234 {
235 int fd;
236
237 if (!PyArg_ParseTuple(args, "O&:tcdrain",
238 fdconv, &fd))
239 return NULL;
240 if (tcdrain(fd) == -1)
241 return PyErr_SetFromErrno(TermiosError);
242
243 Py_RETURN_NONE;
244 }
245
246 PyDoc_STRVAR(termios_tcflush__doc__,
247 "tcflush(fd, queue) -> None\n\
248 \n\
249 Discard queued data on file descriptor fd.\n\
250 The queue selector specifies which queue: termios.TCIFLUSH for the input\n\
251 queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\
252 both queues. ");
253
254 static PyObject *
termios_tcflush(PyObject * self,PyObject * args)255 termios_tcflush(PyObject *self, PyObject *args)
256 {
257 int fd, queue;
258
259 if (!PyArg_ParseTuple(args, "O&i:tcflush",
260 fdconv, &fd, &queue))
261 return NULL;
262 if (tcflush(fd, queue) == -1)
263 return PyErr_SetFromErrno(TermiosError);
264
265 Py_RETURN_NONE;
266 }
267
268 PyDoc_STRVAR(termios_tcflow__doc__,
269 "tcflow(fd, action) -> None\n\
270 \n\
271 Suspend or resume input or output on file descriptor fd.\n\
272 The action argument can be termios.TCOOFF to suspend output,\n\
273 termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\
274 or termios.TCION to restart input.");
275
276 static PyObject *
termios_tcflow(PyObject * self,PyObject * args)277 termios_tcflow(PyObject *self, PyObject *args)
278 {
279 int fd, action;
280
281 if (!PyArg_ParseTuple(args, "O&i:tcflow",
282 fdconv, &fd, &action))
283 return NULL;
284 if (tcflow(fd, action) == -1)
285 return PyErr_SetFromErrno(TermiosError);
286
287 Py_RETURN_NONE;
288 }
289
290 static PyMethodDef termios_methods[] =
291 {
292 {"tcgetattr", termios_tcgetattr,
293 METH_VARARGS, termios_tcgetattr__doc__},
294 {"tcsetattr", termios_tcsetattr,
295 METH_VARARGS, termios_tcsetattr__doc__},
296 {"tcsendbreak", termios_tcsendbreak,
297 METH_VARARGS, termios_tcsendbreak__doc__},
298 {"tcdrain", termios_tcdrain,
299 METH_VARARGS, termios_tcdrain__doc__},
300 {"tcflush", termios_tcflush,
301 METH_VARARGS, termios_tcflush__doc__},
302 {"tcflow", termios_tcflow,
303 METH_VARARGS, termios_tcflow__doc__},
304 {NULL, NULL}
305 };
306
307
308 #if defined(VSWTCH) && !defined(VSWTC)
309 #define VSWTC VSWTCH
310 #endif
311
312 #if defined(VSWTC) && !defined(VSWTCH)
313 #define VSWTCH VSWTC
314 #endif
315
316 static struct constant {
317 char *name;
318 long value;
319 } termios_constants[] = {
320 /* cfgetospeed(), cfsetospeed() constants */
321 {"B0", B0},
322 {"B50", B50},
323 {"B75", B75},
324 {"B110", B110},
325 {"B134", B134},
326 {"B150", B150},
327 {"B200", B200},
328 {"B300", B300},
329 {"B600", B600},
330 {"B1200", B1200},
331 {"B1800", B1800},
332 {"B2400", B2400},
333 {"B4800", B4800},
334 {"B9600", B9600},
335 {"B19200", B19200},
336 {"B38400", B38400},
337 #ifdef B57600
338 {"B57600", B57600},
339 #endif
340 #ifdef B115200
341 {"B115200", B115200},
342 #endif
343 #ifdef B230400
344 {"B230400", B230400},
345 #endif
346 #ifdef B460800
347 {"B460800", B460800},
348 #endif
349 #ifdef B500000
350 {"B500000", B500000},
351 #endif
352 #ifdef B576000
353 {"B576000", B576000},
354 #endif
355 #ifdef B921600
356 {"B921600", B921600},
357 #endif
358 #ifdef B1000000
359 {"B1000000", B1000000},
360 #endif
361 #ifdef B1152000
362 {"B1152000", B1152000},
363 #endif
364 #ifdef B1500000
365 {"B1500000", B1500000},
366 #endif
367 #ifdef B2000000
368 {"B2000000", B2000000},
369 #endif
370 #ifdef B2500000
371 {"B2500000", B2500000},
372 #endif
373 #ifdef B3000000
374 {"B3000000", B3000000},
375 #endif
376 #ifdef B3500000
377 {"B3500000", B3500000},
378 #endif
379 #ifdef B4000000
380 {"B4000000", B4000000},
381 #endif
382
383 #ifdef CBAUDEX
384 {"CBAUDEX", CBAUDEX},
385 #endif
386
387 /* tcsetattr() constants */
388 {"TCSANOW", TCSANOW},
389 {"TCSADRAIN", TCSADRAIN},
390 {"TCSAFLUSH", TCSAFLUSH},
391 #ifdef TCSASOFT
392 {"TCSASOFT", TCSASOFT},
393 #endif
394
395 /* tcflush() constants */
396 {"TCIFLUSH", TCIFLUSH},
397 {"TCOFLUSH", TCOFLUSH},
398 {"TCIOFLUSH", TCIOFLUSH},
399
400 /* tcflow() constants */
401 {"TCOOFF", TCOOFF},
402 {"TCOON", TCOON},
403 {"TCIOFF", TCIOFF},
404 {"TCION", TCION},
405
406 /* struct termios.c_iflag constants */
407 {"IGNBRK", IGNBRK},
408 {"BRKINT", BRKINT},
409 {"IGNPAR", IGNPAR},
410 {"PARMRK", PARMRK},
411 {"INPCK", INPCK},
412 {"ISTRIP", ISTRIP},
413 {"INLCR", INLCR},
414 {"IGNCR", IGNCR},
415 {"ICRNL", ICRNL},
416 #ifdef IUCLC
417 {"IUCLC", IUCLC},
418 #endif
419 {"IXON", IXON},
420 {"IXANY", IXANY},
421 {"IXOFF", IXOFF},
422 #ifdef IMAXBEL
423 {"IMAXBEL", IMAXBEL},
424 #endif
425
426 /* struct termios.c_oflag constants */
427 {"OPOST", OPOST},
428 #ifdef OLCUC
429 {"OLCUC", OLCUC},
430 #endif
431 #ifdef ONLCR
432 {"ONLCR", ONLCR},
433 #endif
434 #ifdef OCRNL
435 {"OCRNL", OCRNL},
436 #endif
437 #ifdef ONOCR
438 {"ONOCR", ONOCR},
439 #endif
440 #ifdef ONLRET
441 {"ONLRET", ONLRET},
442 #endif
443 #ifdef OFILL
444 {"OFILL", OFILL},
445 #endif
446 #ifdef OFDEL
447 {"OFDEL", OFDEL},
448 #endif
449 #ifdef NLDLY
450 {"NLDLY", NLDLY},
451 #endif
452 #ifdef CRDLY
453 {"CRDLY", CRDLY},
454 #endif
455 #ifdef TABDLY
456 {"TABDLY", TABDLY},
457 #endif
458 #ifdef BSDLY
459 {"BSDLY", BSDLY},
460 #endif
461 #ifdef VTDLY
462 {"VTDLY", VTDLY},
463 #endif
464 #ifdef FFDLY
465 {"FFDLY", FFDLY},
466 #endif
467
468 /* struct termios.c_oflag-related values (delay mask) */
469 #ifdef NL0
470 {"NL0", NL0},
471 #endif
472 #ifdef NL1
473 {"NL1", NL1},
474 #endif
475 #ifdef CR0
476 {"CR0", CR0},
477 #endif
478 #ifdef CR1
479 {"CR1", CR1},
480 #endif
481 #ifdef CR2
482 {"CR2", CR2},
483 #endif
484 #ifdef CR3
485 {"CR3", CR3},
486 #endif
487 #ifdef TAB0
488 {"TAB0", TAB0},
489 #endif
490 #ifdef TAB1
491 {"TAB1", TAB1},
492 #endif
493 #ifdef TAB2
494 {"TAB2", TAB2},
495 #endif
496 #ifdef TAB3
497 {"TAB3", TAB3},
498 #endif
499 #ifdef XTABS
500 {"XTABS", XTABS},
501 #endif
502 #ifdef BS0
503 {"BS0", BS0},
504 #endif
505 #ifdef BS1
506 {"BS1", BS1},
507 #endif
508 #ifdef VT0
509 {"VT0", VT0},
510 #endif
511 #ifdef VT1
512 {"VT1", VT1},
513 #endif
514 #ifdef FF0
515 {"FF0", FF0},
516 #endif
517 #ifdef FF1
518 {"FF1", FF1},
519 #endif
520
521 /* struct termios.c_cflag constants */
522 {"CSIZE", CSIZE},
523 {"CSTOPB", CSTOPB},
524 {"CREAD", CREAD},
525 {"PARENB", PARENB},
526 {"PARODD", PARODD},
527 {"HUPCL", HUPCL},
528 {"CLOCAL", CLOCAL},
529 #ifdef CIBAUD
530 {"CIBAUD", CIBAUD},
531 #endif
532 #ifdef CRTSCTS
533 {"CRTSCTS", (long)CRTSCTS},
534 #endif
535
536 /* struct termios.c_cflag-related values (character size) */
537 {"CS5", CS5},
538 {"CS6", CS6},
539 {"CS7", CS7},
540 {"CS8", CS8},
541
542 /* struct termios.c_lflag constants */
543 {"ISIG", ISIG},
544 {"ICANON", ICANON},
545 #ifdef XCASE
546 {"XCASE", XCASE},
547 #endif
548 {"ECHO", ECHO},
549 {"ECHOE", ECHOE},
550 {"ECHOK", ECHOK},
551 {"ECHONL", ECHONL},
552 #ifdef ECHOCTL
553 {"ECHOCTL", ECHOCTL},
554 #endif
555 #ifdef ECHOPRT
556 {"ECHOPRT", ECHOPRT},
557 #endif
558 #ifdef ECHOKE
559 {"ECHOKE", ECHOKE},
560 #endif
561 #ifdef FLUSHO
562 {"FLUSHO", FLUSHO},
563 #endif
564 {"NOFLSH", NOFLSH},
565 {"TOSTOP", TOSTOP},
566 #ifdef PENDIN
567 {"PENDIN", PENDIN},
568 #endif
569 {"IEXTEN", IEXTEN},
570
571 /* indexes into the control chars array returned by tcgetattr() */
572 {"VINTR", VINTR},
573 {"VQUIT", VQUIT},
574 {"VERASE", VERASE},
575 {"VKILL", VKILL},
576 {"VEOF", VEOF},
577 {"VTIME", VTIME},
578 {"VMIN", VMIN},
579 #ifdef VSWTC
580 /* The #defines above ensure that if either is defined, both are,
581 * but both may be omitted by the system headers. ;-( */
582 {"VSWTC", VSWTC},
583 {"VSWTCH", VSWTCH},
584 #endif
585 {"VSTART", VSTART},
586 {"VSTOP", VSTOP},
587 {"VSUSP", VSUSP},
588 {"VEOL", VEOL},
589 #ifdef VREPRINT
590 {"VREPRINT", VREPRINT},
591 #endif
592 #ifdef VDISCARD
593 {"VDISCARD", VDISCARD},
594 #endif
595 #ifdef VWERASE
596 {"VWERASE", VWERASE},
597 #endif
598 #ifdef VLNEXT
599 {"VLNEXT", VLNEXT},
600 #endif
601 #ifdef VEOL2
602 {"VEOL2", VEOL2},
603 #endif
604
605
606 #ifdef B460800
607 {"B460800", B460800},
608 #endif
609 #ifdef CBAUD
610 {"CBAUD", CBAUD},
611 #endif
612 #ifdef CDEL
613 {"CDEL", CDEL},
614 #endif
615 #ifdef CDSUSP
616 {"CDSUSP", CDSUSP},
617 #endif
618 #ifdef CEOF
619 {"CEOF", CEOF},
620 #endif
621 #ifdef CEOL
622 {"CEOL", CEOL},
623 #endif
624 #ifdef CEOL2
625 {"CEOL2", CEOL2},
626 #endif
627 #ifdef CEOT
628 {"CEOT", CEOT},
629 #endif
630 #ifdef CERASE
631 {"CERASE", CERASE},
632 #endif
633 #ifdef CESC
634 {"CESC", CESC},
635 #endif
636 #ifdef CFLUSH
637 {"CFLUSH", CFLUSH},
638 #endif
639 #ifdef CINTR
640 {"CINTR", CINTR},
641 #endif
642 #ifdef CKILL
643 {"CKILL", CKILL},
644 #endif
645 #ifdef CLNEXT
646 {"CLNEXT", CLNEXT},
647 #endif
648 #ifdef CNUL
649 {"CNUL", CNUL},
650 #endif
651 #ifdef COMMON
652 {"COMMON", COMMON},
653 #endif
654 #ifdef CQUIT
655 {"CQUIT", CQUIT},
656 #endif
657 #ifdef CRPRNT
658 {"CRPRNT", CRPRNT},
659 #endif
660 #ifdef CSTART
661 {"CSTART", CSTART},
662 #endif
663 #ifdef CSTOP
664 {"CSTOP", CSTOP},
665 #endif
666 #ifdef CSUSP
667 {"CSUSP", CSUSP},
668 #endif
669 #ifdef CSWTCH
670 {"CSWTCH", CSWTCH},
671 #endif
672 #ifdef CWERASE
673 {"CWERASE", CWERASE},
674 #endif
675 #ifdef EXTA
676 {"EXTA", EXTA},
677 #endif
678 #ifdef EXTB
679 {"EXTB", EXTB},
680 #endif
681 #ifdef FIOASYNC
682 {"FIOASYNC", FIOASYNC},
683 #endif
684 #ifdef FIOCLEX
685 {"FIOCLEX", FIOCLEX},
686 #endif
687 #ifdef FIONBIO
688 {"FIONBIO", FIONBIO},
689 #endif
690 #ifdef FIONCLEX
691 {"FIONCLEX", FIONCLEX},
692 #endif
693 #ifdef FIONREAD
694 {"FIONREAD", FIONREAD},
695 #endif
696 #ifdef IBSHIFT
697 {"IBSHIFT", IBSHIFT},
698 #endif
699 #ifdef INIT_C_CC
700 {"INIT_C_CC", INIT_C_CC},
701 #endif
702 #ifdef IOCSIZE_MASK
703 {"IOCSIZE_MASK", IOCSIZE_MASK},
704 #endif
705 #ifdef IOCSIZE_SHIFT
706 {"IOCSIZE_SHIFT", IOCSIZE_SHIFT},
707 #endif
708 #ifdef NCC
709 {"NCC", NCC},
710 #endif
711 #ifdef NCCS
712 {"NCCS", NCCS},
713 #endif
714 #ifdef NSWTCH
715 {"NSWTCH", NSWTCH},
716 #endif
717 #ifdef N_MOUSE
718 {"N_MOUSE", N_MOUSE},
719 #endif
720 #ifdef N_PPP
721 {"N_PPP", N_PPP},
722 #endif
723 #ifdef N_SLIP
724 {"N_SLIP", N_SLIP},
725 #endif
726 #ifdef N_STRIP
727 {"N_STRIP", N_STRIP},
728 #endif
729 #ifdef N_TTY
730 {"N_TTY", N_TTY},
731 #endif
732 #ifdef TCFLSH
733 {"TCFLSH", TCFLSH},
734 #endif
735 #ifdef TCGETA
736 {"TCGETA", TCGETA},
737 #endif
738 #ifdef TCGETS
739 {"TCGETS", TCGETS},
740 #endif
741 #ifdef TCSBRK
742 {"TCSBRK", TCSBRK},
743 #endif
744 #ifdef TCSBRKP
745 {"TCSBRKP", TCSBRKP},
746 #endif
747 #ifdef TCSETA
748 {"TCSETA", TCSETA},
749 #endif
750 #ifdef TCSETAF
751 {"TCSETAF", TCSETAF},
752 #endif
753 #ifdef TCSETAW
754 {"TCSETAW", TCSETAW},
755 #endif
756 #ifdef TCSETS
757 {"TCSETS", TCSETS},
758 #endif
759 #ifdef TCSETSF
760 {"TCSETSF", TCSETSF},
761 #endif
762 #ifdef TCSETSW
763 {"TCSETSW", TCSETSW},
764 #endif
765 #ifdef TCXONC
766 {"TCXONC", TCXONC},
767 #endif
768 #ifdef TIOCCONS
769 {"TIOCCONS", TIOCCONS},
770 #endif
771 #ifdef TIOCEXCL
772 {"TIOCEXCL", TIOCEXCL},
773 #endif
774 #ifdef TIOCGETD
775 {"TIOCGETD", TIOCGETD},
776 #endif
777 #ifdef TIOCGICOUNT
778 {"TIOCGICOUNT", TIOCGICOUNT},
779 #endif
780 #ifdef TIOCGLCKTRMIOS
781 {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS},
782 #endif
783 #ifdef TIOCGPGRP
784 {"TIOCGPGRP", TIOCGPGRP},
785 #endif
786 #ifdef TIOCGSERIAL
787 {"TIOCGSERIAL", TIOCGSERIAL},
788 #endif
789 #ifdef TIOCGSOFTCAR
790 {"TIOCGSOFTCAR", TIOCGSOFTCAR},
791 #endif
792 #ifdef TIOCGWINSZ
793 {"TIOCGWINSZ", TIOCGWINSZ},
794 #endif
795 #ifdef TIOCINQ
796 {"TIOCINQ", TIOCINQ},
797 #endif
798 #ifdef TIOCLINUX
799 {"TIOCLINUX", TIOCLINUX},
800 #endif
801 #ifdef TIOCMBIC
802 {"TIOCMBIC", TIOCMBIC},
803 #endif
804 #ifdef TIOCMBIS
805 {"TIOCMBIS", TIOCMBIS},
806 #endif
807 #ifdef TIOCMGET
808 {"TIOCMGET", TIOCMGET},
809 #endif
810 #ifdef TIOCMIWAIT
811 {"TIOCMIWAIT", TIOCMIWAIT},
812 #endif
813 #ifdef TIOCMSET
814 {"TIOCMSET", TIOCMSET},
815 #endif
816 #ifdef TIOCM_CAR
817 {"TIOCM_CAR", TIOCM_CAR},
818 #endif
819 #ifdef TIOCM_CD
820 {"TIOCM_CD", TIOCM_CD},
821 #endif
822 #ifdef TIOCM_CTS
823 {"TIOCM_CTS", TIOCM_CTS},
824 #endif
825 #ifdef TIOCM_DSR
826 {"TIOCM_DSR", TIOCM_DSR},
827 #endif
828 #ifdef TIOCM_DTR
829 {"TIOCM_DTR", TIOCM_DTR},
830 #endif
831 #ifdef TIOCM_LE
832 {"TIOCM_LE", TIOCM_LE},
833 #endif
834 #ifdef TIOCM_RI
835 {"TIOCM_RI", TIOCM_RI},
836 #endif
837 #ifdef TIOCM_RNG
838 {"TIOCM_RNG", TIOCM_RNG},
839 #endif
840 #ifdef TIOCM_RTS
841 {"TIOCM_RTS", TIOCM_RTS},
842 #endif
843 #ifdef TIOCM_SR
844 {"TIOCM_SR", TIOCM_SR},
845 #endif
846 #ifdef TIOCM_ST
847 {"TIOCM_ST", TIOCM_ST},
848 #endif
849 #ifdef TIOCNOTTY
850 {"TIOCNOTTY", TIOCNOTTY},
851 #endif
852 #ifdef TIOCNXCL
853 {"TIOCNXCL", TIOCNXCL},
854 #endif
855 #ifdef TIOCOUTQ
856 {"TIOCOUTQ", TIOCOUTQ},
857 #endif
858 #ifdef TIOCPKT
859 {"TIOCPKT", TIOCPKT},
860 #endif
861 #ifdef TIOCPKT_DATA
862 {"TIOCPKT_DATA", TIOCPKT_DATA},
863 #endif
864 #ifdef TIOCPKT_DOSTOP
865 {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP},
866 #endif
867 #ifdef TIOCPKT_FLUSHREAD
868 {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD},
869 #endif
870 #ifdef TIOCPKT_FLUSHWRITE
871 {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE},
872 #endif
873 #ifdef TIOCPKT_NOSTOP
874 {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP},
875 #endif
876 #ifdef TIOCPKT_START
877 {"TIOCPKT_START", TIOCPKT_START},
878 #endif
879 #ifdef TIOCPKT_STOP
880 {"TIOCPKT_STOP", TIOCPKT_STOP},
881 #endif
882 #ifdef TIOCSCTTY
883 {"TIOCSCTTY", TIOCSCTTY},
884 #endif
885 #ifdef TIOCSERCONFIG
886 {"TIOCSERCONFIG", TIOCSERCONFIG},
887 #endif
888 #ifdef TIOCSERGETLSR
889 {"TIOCSERGETLSR", TIOCSERGETLSR},
890 #endif
891 #ifdef TIOCSERGETMULTI
892 {"TIOCSERGETMULTI", TIOCSERGETMULTI},
893 #endif
894 #ifdef TIOCSERGSTRUCT
895 {"TIOCSERGSTRUCT", TIOCSERGSTRUCT},
896 #endif
897 #ifdef TIOCSERGWILD
898 {"TIOCSERGWILD", TIOCSERGWILD},
899 #endif
900 #ifdef TIOCSERSETMULTI
901 {"TIOCSERSETMULTI", TIOCSERSETMULTI},
902 #endif
903 #ifdef TIOCSERSWILD
904 {"TIOCSERSWILD", TIOCSERSWILD},
905 #endif
906 #ifdef TIOCSER_TEMT
907 {"TIOCSER_TEMT", TIOCSER_TEMT},
908 #endif
909 #ifdef TIOCSETD
910 {"TIOCSETD", TIOCSETD},
911 #endif
912 #ifdef TIOCSLCKTRMIOS
913 {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS},
914 #endif
915 #ifdef TIOCSPGRP
916 {"TIOCSPGRP", TIOCSPGRP},
917 #endif
918 #ifdef TIOCSSERIAL
919 {"TIOCSSERIAL", TIOCSSERIAL},
920 #endif
921 #ifdef TIOCSSOFTCAR
922 {"TIOCSSOFTCAR", TIOCSSOFTCAR},
923 #endif
924 #ifdef TIOCSTI
925 {"TIOCSTI", TIOCSTI},
926 #endif
927 #ifdef TIOCSWINSZ
928 {"TIOCSWINSZ", TIOCSWINSZ},
929 #endif
930 #ifdef TIOCTTYGSTRUCT
931 {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT},
932 #endif
933
934 /* sentinel */
935 {NULL, 0}
936 };
937
938
939 static struct PyModuleDef termiosmodule = {
940 PyModuleDef_HEAD_INIT,
941 "termios",
942 termios__doc__,
943 -1,
944 termios_methods,
945 NULL,
946 NULL,
947 NULL,
948 NULL
949 };
950
951 PyMODINIT_FUNC
PyInit_termios(void)952 PyInit_termios(void)
953 {
954 PyObject *m;
955 struct constant *constant = termios_constants;
956
957 m = PyModule_Create(&termiosmodule);
958 if (m == NULL)
959 return NULL;
960
961 if (TermiosError == NULL) {
962 TermiosError = PyErr_NewException("termios.error", NULL, NULL);
963 }
964 Py_INCREF(TermiosError);
965 PyModule_AddObject(m, "error", TermiosError);
966
967 while (constant->name != NULL) {
968 PyModule_AddIntConstant(m, constant->name, constant->value);
969 ++constant;
970 }
971 return m;
972 }
973