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