No issues found
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
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 *
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 *
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 (PyInt_Check(v))
189 mode.c_cc[i] = (cc_t) PyInt_AsLong(v);
190 else {
191 PyErr_SetString(PyExc_TypeError,
192 "tcsetattr: elements of attributes must be characters or integers");
193 return NULL;
194 }
195 }
196
197 if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
198 return PyErr_SetFromErrno(TermiosError);
199 if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
200 return PyErr_SetFromErrno(TermiosError);
201 if (tcsetattr(fd, when, &mode) == -1)
202 return PyErr_SetFromErrno(TermiosError);
203
204 Py_INCREF(Py_None);
205 return Py_None;
206 }
207
208 PyDoc_STRVAR(termios_tcsendbreak__doc__,
209 "tcsendbreak(fd, duration) -> None\n\
210 \n\
211 Send a break on file descriptor fd.\n\
212 A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\
213 has a system dependent meaning.");
214
215 static PyObject *
216 termios_tcsendbreak(PyObject *self, PyObject *args)
217 {
218 int fd, duration;
219
220 if (!PyArg_ParseTuple(args, "O&i:tcsendbreak",
221 fdconv, &fd, &duration))
222 return NULL;
223 if (tcsendbreak(fd, duration) == -1)
224 return PyErr_SetFromErrno(TermiosError);
225
226 Py_INCREF(Py_None);
227 return Py_None;
228 }
229
230 PyDoc_STRVAR(termios_tcdrain__doc__,
231 "tcdrain(fd) -> None\n\
232 \n\
233 Wait until all output written to file descriptor fd has been transmitted.");
234
235 static PyObject *
236 termios_tcdrain(PyObject *self, PyObject *args)
237 {
238 int fd;
239
240 if (!PyArg_ParseTuple(args, "O&:tcdrain",
241 fdconv, &fd))
242 return NULL;
243 if (tcdrain(fd) == -1)
244 return PyErr_SetFromErrno(TermiosError);
245
246 Py_INCREF(Py_None);
247 return Py_None;
248 }
249
250 PyDoc_STRVAR(termios_tcflush__doc__,
251 "tcflush(fd, queue) -> None\n\
252 \n\
253 Discard queued data on file descriptor fd.\n\
254 The queue selector specifies which queue: termios.TCIFLUSH for the input\n\
255 queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\
256 both queues. ");
257
258 static PyObject *
259 termios_tcflush(PyObject *self, PyObject *args)
260 {
261 int fd, queue;
262
263 if (!PyArg_ParseTuple(args, "O&i:tcflush",
264 fdconv, &fd, &queue))
265 return NULL;
266 if (tcflush(fd, queue) == -1)
267 return PyErr_SetFromErrno(TermiosError);
268
269 Py_INCREF(Py_None);
270 return Py_None;
271 }
272
273 PyDoc_STRVAR(termios_tcflow__doc__,
274 "tcflow(fd, action) -> None\n\
275 \n\
276 Suspend or resume input or output on file descriptor fd.\n\
277 The action argument can be termios.TCOOFF to suspend output,\n\
278 termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\
279 or termios.TCION to restart input.");
280
281 static PyObject *
282 termios_tcflow(PyObject *self, PyObject *args)
283 {
284 int fd, action;
285
286 if (!PyArg_ParseTuple(args, "O&i:tcflow",
287 fdconv, &fd, &action))
288 return NULL;
289 if (tcflow(fd, action) == -1)
290 return PyErr_SetFromErrno(TermiosError);
291
292 Py_INCREF(Py_None);
293 return Py_None;
294 }
295
296 static PyMethodDef termios_methods[] =
297 {
298 {"tcgetattr", termios_tcgetattr,
299 METH_VARARGS, termios_tcgetattr__doc__},
300 {"tcsetattr", termios_tcsetattr,
301 METH_VARARGS, termios_tcsetattr__doc__},
302 {"tcsendbreak", termios_tcsendbreak,
303 METH_VARARGS, termios_tcsendbreak__doc__},
304 {"tcdrain", termios_tcdrain,
305 METH_VARARGS, termios_tcdrain__doc__},
306 {"tcflush", termios_tcflush,
307 METH_VARARGS, termios_tcflush__doc__},
308 {"tcflow", termios_tcflow,
309 METH_VARARGS, termios_tcflow__doc__},
310 {NULL, NULL}
311 };
312
313
314 #if defined(VSWTCH) && !defined(VSWTC)
315 #define VSWTC VSWTCH
316 #endif
317
318 #if defined(VSWTC) && !defined(VSWTCH)
319 #define VSWTCH VSWTC
320 #endif
321
322 static struct constant {
323 char *name;
324 long value;
325 } termios_constants[] = {
326 /* cfgetospeed(), cfsetospeed() constants */
327 {"B0", B0},
328 {"B50", B50},
329 {"B75", B75},
330 {"B110", B110},
331 {"B134", B134},
332 {"B150", B150},
333 {"B200", B200},
334 {"B300", B300},
335 {"B600", B600},
336 {"B1200", B1200},
337 {"B1800", B1800},
338 {"B2400", B2400},
339 {"B4800", B4800},
340 {"B9600", B9600},
341 {"B19200", B19200},
342 {"B38400", B38400},
343 #ifdef B57600
344 {"B57600", B57600},
345 #endif
346 #ifdef B115200
347 {"B115200", B115200},
348 #endif
349 #ifdef B230400
350 {"B230400", B230400},
351 #endif
352 #ifdef CBAUDEX
353 {"CBAUDEX", CBAUDEX},
354 #endif
355
356 /* tcsetattr() constants */
357 {"TCSANOW", TCSANOW},
358 {"TCSADRAIN", TCSADRAIN},
359 {"TCSAFLUSH", TCSAFLUSH},
360 #ifdef TCSASOFT
361 {"TCSASOFT", TCSASOFT},
362 #endif
363
364 /* tcflush() constants */
365 {"TCIFLUSH", TCIFLUSH},
366 {"TCOFLUSH", TCOFLUSH},
367 {"TCIOFLUSH", TCIOFLUSH},
368
369 /* tcflow() constants */
370 {"TCOOFF", TCOOFF},
371 {"TCOON", TCOON},
372 {"TCIOFF", TCIOFF},
373 {"TCION", TCION},
374
375 /* struct termios.c_iflag constants */
376 {"IGNBRK", IGNBRK},
377 {"BRKINT", BRKINT},
378 {"IGNPAR", IGNPAR},
379 {"PARMRK", PARMRK},
380 {"INPCK", INPCK},
381 {"ISTRIP", ISTRIP},
382 {"INLCR", INLCR},
383 {"IGNCR", IGNCR},
384 {"ICRNL", ICRNL},
385 #ifdef IUCLC
386 {"IUCLC", IUCLC},
387 #endif
388 {"IXON", IXON},
389 {"IXANY", IXANY},
390 {"IXOFF", IXOFF},
391 #ifdef IMAXBEL
392 {"IMAXBEL", IMAXBEL},
393 #endif
394
395 /* struct termios.c_oflag constants */
396 {"OPOST", OPOST},
397 #ifdef OLCUC
398 {"OLCUC", OLCUC},
399 #endif
400 #ifdef ONLCR
401 {"ONLCR", ONLCR},
402 #endif
403 #ifdef OCRNL
404 {"OCRNL", OCRNL},
405 #endif
406 #ifdef ONOCR
407 {"ONOCR", ONOCR},
408 #endif
409 #ifdef ONLRET
410 {"ONLRET", ONLRET},
411 #endif
412 #ifdef OFILL
413 {"OFILL", OFILL},
414 #endif
415 #ifdef OFDEL
416 {"OFDEL", OFDEL},
417 #endif
418 #ifdef NLDLY
419 {"NLDLY", NLDLY},
420 #endif
421 #ifdef CRDLY
422 {"CRDLY", CRDLY},
423 #endif
424 #ifdef TABDLY
425 {"TABDLY", TABDLY},
426 #endif
427 #ifdef BSDLY
428 {"BSDLY", BSDLY},
429 #endif
430 #ifdef VTDLY
431 {"VTDLY", VTDLY},
432 #endif
433 #ifdef FFDLY
434 {"FFDLY", FFDLY},
435 #endif
436
437 /* struct termios.c_oflag-related values (delay mask) */
438 #ifdef NL0
439 {"NL0", NL0},
440 #endif
441 #ifdef NL1
442 {"NL1", NL1},
443 #endif
444 #ifdef CR0
445 {"CR0", CR0},
446 #endif
447 #ifdef CR1
448 {"CR1", CR1},
449 #endif
450 #ifdef CR2
451 {"CR2", CR2},
452 #endif
453 #ifdef CR3
454 {"CR3", CR3},
455 #endif
456 #ifdef TAB0
457 {"TAB0", TAB0},
458 #endif
459 #ifdef TAB1
460 {"TAB1", TAB1},
461 #endif
462 #ifdef TAB2
463 {"TAB2", TAB2},
464 #endif
465 #ifdef TAB3
466 {"TAB3", TAB3},
467 #endif
468 #ifdef XTABS
469 {"XTABS", XTABS},
470 #endif
471 #ifdef BS0
472 {"BS0", BS0},
473 #endif
474 #ifdef BS1
475 {"BS1", BS1},
476 #endif
477 #ifdef VT0
478 {"VT0", VT0},
479 #endif
480 #ifdef VT1
481 {"VT1", VT1},
482 #endif
483 #ifdef FF0
484 {"FF0", FF0},
485 #endif
486 #ifdef FF1
487 {"FF1", FF1},
488 #endif
489
490 /* struct termios.c_cflag constants */
491 {"CSIZE", CSIZE},
492 {"CSTOPB", CSTOPB},
493 {"CREAD", CREAD},
494 {"PARENB", PARENB},
495 {"PARODD", PARODD},
496 {"HUPCL", HUPCL},
497 {"CLOCAL", CLOCAL},
498 #ifdef CIBAUD
499 {"CIBAUD", CIBAUD},
500 #endif
501 #ifdef CRTSCTS
502 {"CRTSCTS", (long)CRTSCTS},
503 #endif
504
505 /* struct termios.c_cflag-related values (character size) */
506 {"CS5", CS5},
507 {"CS6", CS6},
508 {"CS7", CS7},
509 {"CS8", CS8},
510
511 /* struct termios.c_lflag constants */
512 {"ISIG", ISIG},
513 {"ICANON", ICANON},
514 #ifdef XCASE
515 {"XCASE", XCASE},
516 #endif
517 {"ECHO", ECHO},
518 {"ECHOE", ECHOE},
519 {"ECHOK", ECHOK},
520 {"ECHONL", ECHONL},
521 #ifdef ECHOCTL
522 {"ECHOCTL", ECHOCTL},
523 #endif
524 #ifdef ECHOPRT
525 {"ECHOPRT", ECHOPRT},
526 #endif
527 #ifdef ECHOKE
528 {"ECHOKE", ECHOKE},
529 #endif
530 #ifdef FLUSHO
531 {"FLUSHO", FLUSHO},
532 #endif
533 {"NOFLSH", NOFLSH},
534 {"TOSTOP", TOSTOP},
535 #ifdef PENDIN
536 {"PENDIN", PENDIN},
537 #endif
538 {"IEXTEN", IEXTEN},
539
540 /* indexes into the control chars array returned by tcgetattr() */
541 {"VINTR", VINTR},
542 {"VQUIT", VQUIT},
543 {"VERASE", VERASE},
544 {"VKILL", VKILL},
545 {"VEOF", VEOF},
546 {"VTIME", VTIME},
547 {"VMIN", VMIN},
548 #ifdef VSWTC
549 /* The #defines above ensure that if either is defined, both are,
550 * but both may be omitted by the system headers. ;-( */
551 {"VSWTC", VSWTC},
552 {"VSWTCH", VSWTCH},
553 #endif
554 {"VSTART", VSTART},
555 {"VSTOP", VSTOP},
556 {"VSUSP", VSUSP},
557 {"VEOL", VEOL},
558 #ifdef VREPRINT
559 {"VREPRINT", VREPRINT},
560 #endif
561 #ifdef VDISCARD
562 {"VDISCARD", VDISCARD},
563 #endif
564 #ifdef VWERASE
565 {"VWERASE", VWERASE},
566 #endif
567 #ifdef VLNEXT
568 {"VLNEXT", VLNEXT},
569 #endif
570 #ifdef VEOL2
571 {"VEOL2", VEOL2},
572 #endif
573
574
575 #ifdef B460800
576 {"B460800", B460800},
577 #endif
578 #ifdef CBAUD
579 {"CBAUD", CBAUD},
580 #endif
581 #ifdef CDEL
582 {"CDEL", CDEL},
583 #endif
584 #ifdef CDSUSP
585 {"CDSUSP", CDSUSP},
586 #endif
587 #ifdef CEOF
588 {"CEOF", CEOF},
589 #endif
590 #ifdef CEOL
591 {"CEOL", CEOL},
592 #endif
593 #ifdef CEOL2
594 {"CEOL2", CEOL2},
595 #endif
596 #ifdef CEOT
597 {"CEOT", CEOT},
598 #endif
599 #ifdef CERASE
600 {"CERASE", CERASE},
601 #endif
602 #ifdef CESC
603 {"CESC", CESC},
604 #endif
605 #ifdef CFLUSH
606 {"CFLUSH", CFLUSH},
607 #endif
608 #ifdef CINTR
609 {"CINTR", CINTR},
610 #endif
611 #ifdef CKILL
612 {"CKILL", CKILL},
613 #endif
614 #ifdef CLNEXT
615 {"CLNEXT", CLNEXT},
616 #endif
617 #ifdef CNUL
618 {"CNUL", CNUL},
619 #endif
620 #ifdef COMMON
621 {"COMMON", COMMON},
622 #endif
623 #ifdef CQUIT
624 {"CQUIT", CQUIT},
625 #endif
626 #ifdef CRPRNT
627 {"CRPRNT", CRPRNT},
628 #endif
629 #ifdef CSTART
630 {"CSTART", CSTART},
631 #endif
632 #ifdef CSTOP
633 {"CSTOP", CSTOP},
634 #endif
635 #ifdef CSUSP
636 {"CSUSP", CSUSP},
637 #endif
638 #ifdef CSWTCH
639 {"CSWTCH", CSWTCH},
640 #endif
641 #ifdef CWERASE
642 {"CWERASE", CWERASE},
643 #endif
644 #ifdef EXTA
645 {"EXTA", EXTA},
646 #endif
647 #ifdef EXTB
648 {"EXTB", EXTB},
649 #endif
650 #ifdef FIOASYNC
651 {"FIOASYNC", FIOASYNC},
652 #endif
653 #ifdef FIOCLEX
654 {"FIOCLEX", FIOCLEX},
655 #endif
656 #ifdef FIONBIO
657 {"FIONBIO", FIONBIO},
658 #endif
659 #ifdef FIONCLEX
660 {"FIONCLEX", FIONCLEX},
661 #endif
662 #ifdef FIONREAD
663 {"FIONREAD", FIONREAD},
664 #endif
665 #ifdef IBSHIFT
666 {"IBSHIFT", IBSHIFT},
667 #endif
668 #ifdef INIT_C_CC
669 {"INIT_C_CC", INIT_C_CC},
670 #endif
671 #ifdef IOCSIZE_MASK
672 {"IOCSIZE_MASK", IOCSIZE_MASK},
673 #endif
674 #ifdef IOCSIZE_SHIFT
675 {"IOCSIZE_SHIFT", IOCSIZE_SHIFT},
676 #endif
677 #ifdef NCC
678 {"NCC", NCC},
679 #endif
680 #ifdef NCCS
681 {"NCCS", NCCS},
682 #endif
683 #ifdef NSWTCH
684 {"NSWTCH", NSWTCH},
685 #endif
686 #ifdef N_MOUSE
687 {"N_MOUSE", N_MOUSE},
688 #endif
689 #ifdef N_PPP
690 {"N_PPP", N_PPP},
691 #endif
692 #ifdef N_SLIP
693 {"N_SLIP", N_SLIP},
694 #endif
695 #ifdef N_STRIP
696 {"N_STRIP", N_STRIP},
697 #endif
698 #ifdef N_TTY
699 {"N_TTY", N_TTY},
700 #endif
701 #ifdef TCFLSH
702 {"TCFLSH", TCFLSH},
703 #endif
704 #ifdef TCGETA
705 {"TCGETA", TCGETA},
706 #endif
707 #ifdef TCGETS
708 {"TCGETS", TCGETS},
709 #endif
710 #ifdef TCSBRK
711 {"TCSBRK", TCSBRK},
712 #endif
713 #ifdef TCSBRKP
714 {"TCSBRKP", TCSBRKP},
715 #endif
716 #ifdef TCSETA
717 {"TCSETA", TCSETA},
718 #endif
719 #ifdef TCSETAF
720 {"TCSETAF", TCSETAF},
721 #endif
722 #ifdef TCSETAW
723 {"TCSETAW", TCSETAW},
724 #endif
725 #ifdef TCSETS
726 {"TCSETS", TCSETS},
727 #endif
728 #ifdef TCSETSF
729 {"TCSETSF", TCSETSF},
730 #endif
731 #ifdef TCSETSW
732 {"TCSETSW", TCSETSW},
733 #endif
734 #ifdef TCXONC
735 {"TCXONC", TCXONC},
736 #endif
737 #ifdef TIOCCONS
738 {"TIOCCONS", TIOCCONS},
739 #endif
740 #ifdef TIOCEXCL
741 {"TIOCEXCL", TIOCEXCL},
742 #endif
743 #ifdef TIOCGETD
744 {"TIOCGETD", TIOCGETD},
745 #endif
746 #ifdef TIOCGICOUNT
747 {"TIOCGICOUNT", TIOCGICOUNT},
748 #endif
749 #ifdef TIOCGLCKTRMIOS
750 {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS},
751 #endif
752 #ifdef TIOCGPGRP
753 {"TIOCGPGRP", TIOCGPGRP},
754 #endif
755 #ifdef TIOCGSERIAL
756 {"TIOCGSERIAL", TIOCGSERIAL},
757 #endif
758 #ifdef TIOCGSOFTCAR
759 {"TIOCGSOFTCAR", TIOCGSOFTCAR},
760 #endif
761 #ifdef TIOCGWINSZ
762 {"TIOCGWINSZ", TIOCGWINSZ},
763 #endif
764 #ifdef TIOCINQ
765 {"TIOCINQ", TIOCINQ},
766 #endif
767 #ifdef TIOCLINUX
768 {"TIOCLINUX", TIOCLINUX},
769 #endif
770 #ifdef TIOCMBIC
771 {"TIOCMBIC", TIOCMBIC},
772 #endif
773 #ifdef TIOCMBIS
774 {"TIOCMBIS", TIOCMBIS},
775 #endif
776 #ifdef TIOCMGET
777 {"TIOCMGET", TIOCMGET},
778 #endif
779 #ifdef TIOCMIWAIT
780 {"TIOCMIWAIT", TIOCMIWAIT},
781 #endif
782 #ifdef TIOCMSET
783 {"TIOCMSET", TIOCMSET},
784 #endif
785 #ifdef TIOCM_CAR
786 {"TIOCM_CAR", TIOCM_CAR},
787 #endif
788 #ifdef TIOCM_CD
789 {"TIOCM_CD", TIOCM_CD},
790 #endif
791 #ifdef TIOCM_CTS
792 {"TIOCM_CTS", TIOCM_CTS},
793 #endif
794 #ifdef TIOCM_DSR
795 {"TIOCM_DSR", TIOCM_DSR},
796 #endif
797 #ifdef TIOCM_DTR
798 {"TIOCM_DTR", TIOCM_DTR},
799 #endif
800 #ifdef TIOCM_LE
801 {"TIOCM_LE", TIOCM_LE},
802 #endif
803 #ifdef TIOCM_RI
804 {"TIOCM_RI", TIOCM_RI},
805 #endif
806 #ifdef TIOCM_RNG
807 {"TIOCM_RNG", TIOCM_RNG},
808 #endif
809 #ifdef TIOCM_RTS
810 {"TIOCM_RTS", TIOCM_RTS},
811 #endif
812 #ifdef TIOCM_SR
813 {"TIOCM_SR", TIOCM_SR},
814 #endif
815 #ifdef TIOCM_ST
816 {"TIOCM_ST", TIOCM_ST},
817 #endif
818 #ifdef TIOCNOTTY
819 {"TIOCNOTTY", TIOCNOTTY},
820 #endif
821 #ifdef TIOCNXCL
822 {"TIOCNXCL", TIOCNXCL},
823 #endif
824 #ifdef TIOCOUTQ
825 {"TIOCOUTQ", TIOCOUTQ},
826 #endif
827 #ifdef TIOCPKT
828 {"TIOCPKT", TIOCPKT},
829 #endif
830 #ifdef TIOCPKT_DATA
831 {"TIOCPKT_DATA", TIOCPKT_DATA},
832 #endif
833 #ifdef TIOCPKT_DOSTOP
834 {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP},
835 #endif
836 #ifdef TIOCPKT_FLUSHREAD
837 {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD},
838 #endif
839 #ifdef TIOCPKT_FLUSHWRITE
840 {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE},
841 #endif
842 #ifdef TIOCPKT_NOSTOP
843 {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP},
844 #endif
845 #ifdef TIOCPKT_START
846 {"TIOCPKT_START", TIOCPKT_START},
847 #endif
848 #ifdef TIOCPKT_STOP
849 {"TIOCPKT_STOP", TIOCPKT_STOP},
850 #endif
851 #ifdef TIOCSCTTY
852 {"TIOCSCTTY", TIOCSCTTY},
853 #endif
854 #ifdef TIOCSERCONFIG
855 {"TIOCSERCONFIG", TIOCSERCONFIG},
856 #endif
857 #ifdef TIOCSERGETLSR
858 {"TIOCSERGETLSR", TIOCSERGETLSR},
859 #endif
860 #ifdef TIOCSERGETMULTI
861 {"TIOCSERGETMULTI", TIOCSERGETMULTI},
862 #endif
863 #ifdef TIOCSERGSTRUCT
864 {"TIOCSERGSTRUCT", TIOCSERGSTRUCT},
865 #endif
866 #ifdef TIOCSERGWILD
867 {"TIOCSERGWILD", TIOCSERGWILD},
868 #endif
869 #ifdef TIOCSERSETMULTI
870 {"TIOCSERSETMULTI", TIOCSERSETMULTI},
871 #endif
872 #ifdef TIOCSERSWILD
873 {"TIOCSERSWILD", TIOCSERSWILD},
874 #endif
875 #ifdef TIOCSER_TEMT
876 {"TIOCSER_TEMT", TIOCSER_TEMT},
877 #endif
878 #ifdef TIOCSETD
879 {"TIOCSETD", TIOCSETD},
880 #endif
881 #ifdef TIOCSLCKTRMIOS
882 {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS},
883 #endif
884 #ifdef TIOCSPGRP
885 {"TIOCSPGRP", TIOCSPGRP},
886 #endif
887 #ifdef TIOCSSERIAL
888 {"TIOCSSERIAL", TIOCSSERIAL},
889 #endif
890 #ifdef TIOCSSOFTCAR
891 {"TIOCSSOFTCAR", TIOCSSOFTCAR},
892 #endif
893 #ifdef TIOCSTI
894 {"TIOCSTI", TIOCSTI},
895 #endif
896 #ifdef TIOCSWINSZ
897 {"TIOCSWINSZ", TIOCSWINSZ},
898 #endif
899 #ifdef TIOCTTYGSTRUCT
900 {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT},
901 #endif
902
903 /* sentinel */
904 {NULL, 0}
905 };
906
907
908 PyMODINIT_FUNC
909 PyInit_termios(void)
910 {
911 PyObject *m;
912 struct constant *constant = termios_constants;
913
914 m = Py_InitModule4("termios", termios_methods, termios__doc__,
915 (PyObject *)NULL, PYTHON_API_VERSION);
916 if (m == NULL)
917 return;
918
919 if (TermiosError == NULL) {
920 TermiosError = PyErr_NewException("termios.error", NULL, NULL);
921 }
922 Py_INCREF(TermiosError);
923 PyModule_AddObject(m, "error", TermiosError);
924
925 while (constant->name != NULL) {
926 PyModule_AddIntConstant(m, constant->name, constant->value);
927 ++constant;
928 }
929 }