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 (appearantly 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 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 * 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 * 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 * 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 * 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 * 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 * 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 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