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 } 930