LCOV - code coverage report
Current view: top level - Modules - termios.c (source / functions) Hit Total Coverage
Test: CPython lcov report Lines: 74 164 45.1 %
Date: 2022-07-07 18:19:46 Functions: 8 14 57.1 %

          Line data    Source code
       1             : /* termios.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             : /*[clinic input]
      33             : module termios
      34             : [clinic start generated code]*/
      35             : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=01105c85d0ca7252]*/
      36             : 
      37             : #include "clinic/termios.c.h"
      38             : 
      39             : PyDoc_STRVAR(termios__doc__,
      40             : "This module provides an interface to the Posix calls for tty I/O control.\n\
      41             : For a complete description of these calls, see the Posix or Unix manual\n\
      42             : pages. It is only available for those Unix versions that support Posix\n\
      43             : termios style tty I/O control.\n\
      44             : \n\
      45             : All functions in this module take a file descriptor fd as their first\n\
      46             : argument. This can be an integer file descriptor, such as returned by\n\
      47             : sys.stdin.fileno(), or a file object, such as sys.stdin itself.");
      48             : 
      49             : typedef struct {
      50             :   PyObject *TermiosError;
      51             : } termiosmodulestate;
      52             : 
      53             : static inline termiosmodulestate*
      54       86284 : get_termios_state(PyObject *module)
      55             : {
      56       86284 :     void *state = PyModule_GetState(module);
      57       86284 :     assert(state != NULL);
      58       86284 :     return (termiosmodulestate *)state;
      59             : }
      60             : 
      61             : static struct PyModuleDef termiosmodule;
      62             : 
      63             : /*[clinic input]
      64             : termios.tcgetattr
      65             : 
      66             :     fd: fildes
      67             :     /
      68             : 
      69             : Get the tty attributes for file descriptor fd.
      70             : 
      71             : Returns a list [iflag, oflag, cflag, lflag, ispeed, ospeed, cc]
      72             : where cc is a list of the tty special characters (each a string of
      73             : length 1, except the items with indices VMIN and VTIME, which are
      74             : integers when these fields are defined).  The interpretation of the
      75             : flags and the speeds as well as the indexing in the cc array must be
      76             : done using the symbolic constants defined in this module.
      77             : [clinic start generated code]*/
      78             : 
      79             : static PyObject *
      80           6 : termios_tcgetattr_impl(PyObject *module, int fd)
      81             : /*[clinic end generated code: output=2b3da39db870e629 input=54dad9779ebe74b1]*/
      82             : {
      83           6 :     termiosmodulestate *state = PyModule_GetState(module);
      84             :     struct termios mode;
      85           6 :     if (tcgetattr(fd, &mode) == -1) {
      86           3 :         return PyErr_SetFromErrno(state->TermiosError);
      87             :     }
      88             : 
      89           3 :     speed_t ispeed = cfgetispeed(&mode);
      90           3 :     speed_t ospeed = cfgetospeed(&mode);
      91             : 
      92           3 :     PyObject *cc = PyList_New(NCCS);
      93           3 :     if (cc == NULL) {
      94           0 :         return NULL;
      95             :     }
      96             : 
      97             :     PyObject *v;
      98             :     int i;
      99          99 :     for (i = 0; i < NCCS; i++) {
     100          96 :         char ch = (char)mode.c_cc[i];
     101          96 :         v = PyBytes_FromStringAndSize(&ch, 1);
     102          96 :         if (v == NULL)
     103           0 :             goto err;
     104          96 :         PyList_SetItem(cc, i, v);
     105             :     }
     106             : 
     107             :     /* Convert the MIN and TIME slots to integer.  On some systems, the
     108             :        MIN and TIME slots are the same as the EOF and EOL slots.  So we
     109             :        only do this in noncanonical input mode.  */
     110           3 :     if ((mode.c_lflag & ICANON) == 0) {
     111           0 :         v = PyLong_FromLong((long)mode.c_cc[VMIN]);
     112           0 :         if (v == NULL)
     113           0 :             goto err;
     114           0 :         PyList_SetItem(cc, VMIN, v);
     115           0 :         v = PyLong_FromLong((long)mode.c_cc[VTIME]);
     116           0 :         if (v == NULL)
     117           0 :             goto err;
     118           0 :         PyList_SetItem(cc, VTIME, v);
     119             :     }
     120             : 
     121           3 :     if (!(v = PyList_New(7)))
     122           0 :         goto err;
     123             : 
     124           3 :     PyList_SetItem(v, 0, PyLong_FromLong((long)mode.c_iflag));
     125           3 :     PyList_SetItem(v, 1, PyLong_FromLong((long)mode.c_oflag));
     126           3 :     PyList_SetItem(v, 2, PyLong_FromLong((long)mode.c_cflag));
     127           3 :     PyList_SetItem(v, 3, PyLong_FromLong((long)mode.c_lflag));
     128           3 :     PyList_SetItem(v, 4, PyLong_FromLong((long)ispeed));
     129           3 :     PyList_SetItem(v, 5, PyLong_FromLong((long)ospeed));
     130           3 :     if (PyErr_Occurred()) {
     131           0 :         Py_DECREF(v);
     132           0 :         goto err;
     133             :     }
     134           3 :     PyList_SetItem(v, 6, cc);
     135           3 :     return v;
     136           0 :   err:
     137           0 :     Py_DECREF(cc);
     138           0 :     return NULL;
     139             : }
     140             : 
     141             : /*[clinic input]
     142             : termios.tcsetattr
     143             : 
     144             :     fd: fildes
     145             :     when: int
     146             :     attributes as term: object
     147             :     /
     148             : 
     149             : Set the tty attributes for file descriptor fd.
     150             : 
     151             : The attributes to be set are taken from the attributes argument, which
     152             : is a list like the one returned by tcgetattr(). The when argument
     153             : determines when the attributes are changed: termios.TCSANOW to
     154             : change immediately, termios.TCSADRAIN to change after transmitting all
     155             : queued output, or termios.TCSAFLUSH to change after transmitting all
     156             : queued output and discarding all queued input.
     157             : [clinic start generated code]*/
     158             : 
     159             : static PyObject *
     160           3 : termios_tcsetattr_impl(PyObject *module, int fd, int when, PyObject *term)
     161             : /*[clinic end generated code: output=bcd2b0a7b98a4bf5 input=5dafabdd5a08f018]*/
     162             : {
     163           3 :     if (!PyList_Check(term) || PyList_Size(term) != 7) {
     164           0 :         PyErr_SetString(PyExc_TypeError,
     165             :                      "tcsetattr, arg 3: must be 7 element list");
     166           0 :         return NULL;
     167             :     }
     168             : 
     169             :     /* Get the old mode, in case there are any hidden fields... */
     170           3 :     termiosmodulestate *state = PyModule_GetState(module);
     171             :     struct termios mode;
     172           3 :     if (tcgetattr(fd, &mode) == -1) {
     173           0 :         return PyErr_SetFromErrno(state->TermiosError);
     174             :     }
     175             : 
     176           3 :     mode.c_iflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 0));
     177           3 :     mode.c_oflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 1));
     178           3 :     mode.c_cflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 2));
     179           3 :     mode.c_lflag = (tcflag_t) PyLong_AsLong(PyList_GetItem(term, 3));
     180           3 :     speed_t ispeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 4));
     181           3 :     speed_t ospeed = (speed_t) PyLong_AsLong(PyList_GetItem(term, 5));
     182           3 :     PyObject *cc = PyList_GetItem(term, 6);
     183           3 :     if (PyErr_Occurred()) {
     184           0 :         return NULL;
     185             :     }
     186             : 
     187           3 :     if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
     188           0 :         PyErr_Format(PyExc_TypeError,
     189             :             "tcsetattr: attributes[6] must be %d element list",
     190             :                  NCCS);
     191           0 :         return NULL;
     192             :     }
     193             : 
     194             :     int i;
     195             :     PyObject *v;
     196          99 :     for (i = 0; i < NCCS; i++) {
     197          96 :         v = PyList_GetItem(cc, i);
     198             : 
     199          96 :         if (PyBytes_Check(v) && PyBytes_Size(v) == 1)
     200          90 :             mode.c_cc[i] = (cc_t) * PyBytes_AsString(v);
     201           6 :         else if (PyLong_Check(v))
     202           6 :             mode.c_cc[i] = (cc_t) PyLong_AsLong(v);
     203             :         else {
     204           0 :             PyErr_SetString(PyExc_TypeError,
     205             :      "tcsetattr: elements of attributes must be characters or integers");
     206           0 :                         return NULL;
     207             :                 }
     208             :     }
     209             : 
     210           3 :     if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
     211           0 :         return PyErr_SetFromErrno(state->TermiosError);
     212           3 :     if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
     213           0 :         return PyErr_SetFromErrno(state->TermiosError);
     214           3 :     if (tcsetattr(fd, when, &mode) == -1)
     215           0 :         return PyErr_SetFromErrno(state->TermiosError);
     216             : 
     217           3 :     Py_RETURN_NONE;
     218             : }
     219             : 
     220             : /*[clinic input]
     221             : termios.tcsendbreak
     222             : 
     223             :     fd: fildes
     224             :     duration: int
     225             :     /
     226             : 
     227             : Send a break on file descriptor fd.
     228             : 
     229             : A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration
     230             : has a system dependent meaning.
     231             : [clinic start generated code]*/
     232             : 
     233             : static PyObject *
     234           0 : termios_tcsendbreak_impl(PyObject *module, int fd, int duration)
     235             : /*[clinic end generated code: output=5945f589b5d3ac66 input=dc2f32417691f8ed]*/
     236             : {
     237           0 :     termiosmodulestate *state = PyModule_GetState(module);
     238           0 :     if (tcsendbreak(fd, duration) == -1) {
     239           0 :         return PyErr_SetFromErrno(state->TermiosError);
     240             :     }
     241             : 
     242           0 :     Py_RETURN_NONE;
     243             : }
     244             : 
     245             : /*[clinic input]
     246             : termios.tcdrain
     247             : 
     248             :     fd: fildes
     249             :     /
     250             : 
     251             : Wait until all output written to file descriptor fd has been transmitted.
     252             : [clinic start generated code]*/
     253             : 
     254             : static PyObject *
     255           0 : termios_tcdrain_impl(PyObject *module, int fd)
     256             : /*[clinic end generated code: output=5fd86944c6255955 input=c99241b140b32447]*/
     257             : {
     258           0 :     termiosmodulestate *state = PyModule_GetState(module);
     259           0 :     if (tcdrain(fd) == -1) {
     260           0 :         return PyErr_SetFromErrno(state->TermiosError);
     261             :     }
     262             : 
     263           0 :     Py_RETURN_NONE;
     264             : }
     265             : 
     266             : /*[clinic input]
     267             : termios.tcflush
     268             : 
     269             :     fd: fildes
     270             :     queue: int
     271             :     /
     272             : 
     273             : Discard queued data on file descriptor fd.
     274             : 
     275             : The queue selector specifies which queue: termios.TCIFLUSH for the input
     276             : queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for
     277             : both queues.
     278             : [clinic start generated code]*/
     279             : 
     280             : static PyObject *
     281           0 : termios_tcflush_impl(PyObject *module, int fd, int queue)
     282             : /*[clinic end generated code: output=2424f80312ec2f21 input=0f7d08122ddc07b5]*/
     283             : {
     284           0 :     termiosmodulestate *state = PyModule_GetState(module);
     285           0 :     if (tcflush(fd, queue) == -1) {
     286           0 :         return PyErr_SetFromErrno(state->TermiosError);
     287             :     }
     288             : 
     289           0 :     Py_RETURN_NONE;
     290             : }
     291             : 
     292             : /*[clinic input]
     293             : termios.tcflow
     294             : 
     295             :     fd: fildes
     296             :     action: int
     297             :     /
     298             : 
     299             : Suspend or resume input or output on file descriptor fd.
     300             : 
     301             : The action argument can be termios.TCOOFF to suspend output,
     302             : termios.TCOON to restart output, termios.TCIOFF to suspend input,
     303             : or termios.TCION to restart input.
     304             : [clinic start generated code]*/
     305             : 
     306             : static PyObject *
     307           0 : termios_tcflow_impl(PyObject *module, int fd, int action)
     308             : /*[clinic end generated code: output=afd10928e6ea66eb input=c6aff0640b6efd9c]*/
     309             : {
     310           0 :     termiosmodulestate *state = PyModule_GetState(module);
     311           0 :     if (tcflow(fd, action) == -1) {
     312           0 :         return PyErr_SetFromErrno(state->TermiosError);
     313             :     }
     314             : 
     315           0 :     Py_RETURN_NONE;
     316             : }
     317             : 
     318             : /*[clinic input]
     319             : termios.tcgetwinsize
     320             : 
     321             :     fd: fildes
     322             :     /
     323             : 
     324             : Get the tty winsize for file descriptor fd.
     325             : 
     326             : Returns a tuple (ws_row, ws_col).
     327             : [clinic start generated code]*/
     328             : 
     329             : static PyObject *
     330           0 : termios_tcgetwinsize_impl(PyObject *module, int fd)
     331             : /*[clinic end generated code: output=31825977d5325fb6 input=5706c379d7fd984d]*/
     332             : {
     333             : #if defined(TIOCGWINSZ)
     334           0 :     termiosmodulestate *state = PyModule_GetState(module);
     335             :     struct winsize w;
     336           0 :     if (ioctl(fd, TIOCGWINSZ, &w) == -1) {
     337           0 :         return PyErr_SetFromErrno(state->TermiosError);
     338             :     }
     339             : 
     340             :     PyObject *v;
     341           0 :     if (!(v = PyTuple_New(2))) {
     342           0 :         return NULL;
     343             :     }
     344             : 
     345           0 :     PyTuple_SetItem(v, 0, PyLong_FromLong((long)w.ws_row));
     346           0 :     PyTuple_SetItem(v, 1, PyLong_FromLong((long)w.ws_col));
     347           0 :     if (PyErr_Occurred()) {
     348           0 :         Py_DECREF(v);
     349           0 :         return NULL;
     350             :     }
     351           0 :     return v;
     352             : #elif defined(TIOCGSIZE)
     353             :     termiosmodulestate *state = PyModule_GetState(module);
     354             :     struct ttysize s;
     355             :     if (ioctl(fd, TIOCGSIZE, &s) == -1) {
     356             :         return PyErr_SetFromErrno(state->TermiosError);
     357             :     }
     358             : 
     359             :     PyObject *v;
     360             :     if (!(v = PyTuple_New(2))) {
     361             :         return NULL;
     362             :     }
     363             : 
     364             :     PyTuple_SetItem(v, 0, PyLong_FromLong((long)s.ts_lines));
     365             :     PyTuple_SetItem(v, 1, PyLong_FromLong((long)s.ts_cols));
     366             :     if (PyErr_Occurred()) {
     367             :         Py_DECREF(v);
     368             :         return NULL;
     369             :     }
     370             :     return v;
     371             : #else
     372             :     PyErr_SetString(PyExc_NotImplementedError,
     373             :                     "requires termios.TIOCGWINSZ and/or termios.TIOCGSIZE");
     374             :     return NULL;
     375             : #endif /* defined(TIOCGWINSZ) */
     376             : }
     377             : 
     378             : /*[clinic input]
     379             : termios.tcsetwinsize
     380             : 
     381             :     fd: fildes
     382             :     winsize as winsz: object
     383             :     /
     384             : 
     385             : Set the tty winsize for file descriptor fd.
     386             : 
     387             : The winsize to be set is taken from the winsize argument, which
     388             : is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize().
     389             : [clinic start generated code]*/
     390             : 
     391             : static PyObject *
     392           0 : termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz)
     393             : /*[clinic end generated code: output=2ac3c9bb6eda83e1 input=4a06424465b24aee]*/
     394             : {
     395           0 :     if (!PySequence_Check(winsz) || PySequence_Size(winsz) != 2) {
     396           0 :         PyErr_SetString(PyExc_TypeError,
     397             :                      "tcsetwinsize, arg 2: must be a two-item sequence");
     398           0 :         return NULL;
     399             :     }
     400             : 
     401             :     PyObject *tmp_item;
     402             :     long winsz_0, winsz_1;
     403           0 :     tmp_item = PySequence_GetItem(winsz, 0);
     404           0 :     winsz_0 = PyLong_AsLong(tmp_item);
     405           0 :     if (winsz_0 == -1 && PyErr_Occurred()) {
     406           0 :         Py_XDECREF(tmp_item);
     407           0 :         return NULL;
     408             :     }
     409           0 :     Py_XDECREF(tmp_item);
     410           0 :     tmp_item = PySequence_GetItem(winsz, 1);
     411           0 :     winsz_1 = PyLong_AsLong(tmp_item);
     412           0 :     if (winsz_1 == -1 && PyErr_Occurred()) {
     413           0 :         Py_XDECREF(tmp_item);
     414           0 :         return NULL;
     415             :     }
     416           0 :     Py_XDECREF(tmp_item);
     417             : 
     418           0 :     termiosmodulestate *state = PyModule_GetState(module);
     419             : 
     420             : #if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
     421             :     struct winsize w;
     422             :     /* Get the old winsize because it might have
     423             :        more fields such as xpixel, ypixel. */
     424           0 :     if (ioctl(fd, TIOCGWINSZ, &w) == -1) {
     425           0 :         return PyErr_SetFromErrno(state->TermiosError);
     426             :     }
     427             : 
     428           0 :     w.ws_row = (unsigned short) winsz_0;
     429           0 :     w.ws_col = (unsigned short) winsz_1;
     430           0 :     if ((((long)w.ws_row) != winsz_0) || (((long)w.ws_col) != winsz_1)) {
     431           0 :         PyErr_SetString(PyExc_OverflowError,
     432             :                         "winsize value(s) out of range.");
     433           0 :         return NULL;
     434             :     }
     435             : 
     436           0 :     if (ioctl(fd, TIOCSWINSZ, &w) == -1) {
     437           0 :         return PyErr_SetFromErrno(state->TermiosError);
     438             :     }
     439             : 
     440           0 :     Py_RETURN_NONE;
     441             : #elif defined(TIOCGSIZE) && defined(TIOCSSIZE)
     442             :     struct ttysize s;
     443             :     /* Get the old ttysize because it might have more fields. */
     444             :     if (ioctl(fd, TIOCGSIZE, &s) == -1) {
     445             :         return PyErr_SetFromErrno(state->TermiosError);
     446             :     }
     447             : 
     448             :     s.ts_lines = (int) winsz_0;
     449             :     s.ts_cols = (int) winsz_1;
     450             :     if ((((long)s.ts_lines) != winsz_0) || (((long)s.ts_cols) != winsz_1)) {
     451             :         PyErr_SetString(PyExc_OverflowError,
     452             :                         "winsize value(s) out of range.");
     453             :         return NULL;
     454             :     }
     455             : 
     456             :     if (ioctl(fd, TIOCSSIZE, &s) == -1) {
     457             :         return PyErr_SetFromErrno(state->TermiosError);
     458             :     }
     459             : 
     460             :     Py_RETURN_NONE;
     461             : #else
     462             :     PyErr_SetString(PyExc_NotImplementedError,
     463             :                     "requires termios.TIOCGWINSZ, termios.TIOCSWINSZ and/or termios.TIOCGSIZE, termios.TIOCSSIZE");
     464             :     return NULL;
     465             : #endif /* defined(TIOCGWINSZ) && defined(TIOCSWINSZ) */
     466             : }
     467             : 
     468             : static PyMethodDef termios_methods[] =
     469             : {
     470             :     TERMIOS_TCGETATTR_METHODDEF
     471             :     TERMIOS_TCSETATTR_METHODDEF
     472             :     TERMIOS_TCSENDBREAK_METHODDEF
     473             :     TERMIOS_TCDRAIN_METHODDEF
     474             :     TERMIOS_TCFLUSH_METHODDEF
     475             :     TERMIOS_TCFLOW_METHODDEF
     476             :     TERMIOS_TCGETWINSIZE_METHODDEF
     477             :     TERMIOS_TCSETWINSIZE_METHODDEF
     478             :     {NULL, NULL}
     479             : };
     480             : 
     481             : 
     482             : #if defined(VSWTCH) && !defined(VSWTC)
     483             : #define VSWTC VSWTCH
     484             : #endif
     485             : 
     486             : #if defined(VSWTC) && !defined(VSWTCH)
     487             : #define VSWTCH VSWTC
     488             : #endif
     489             : 
     490             : static struct constant {
     491             :     char *name;
     492             :     long value;
     493             : } termios_constants[] = {
     494             :     /* cfgetospeed(), cfsetospeed() constants */
     495             :     {"B0", B0},
     496             :     {"B50", B50},
     497             :     {"B75", B75},
     498             :     {"B110", B110},
     499             :     {"B134", B134},
     500             :     {"B150", B150},
     501             :     {"B200", B200},
     502             :     {"B300", B300},
     503             :     {"B600", B600},
     504             :     {"B1200", B1200},
     505             :     {"B1800", B1800},
     506             :     {"B2400", B2400},
     507             :     {"B4800", B4800},
     508             :     {"B9600", B9600},
     509             :     {"B19200", B19200},
     510             :     {"B38400", B38400},
     511             : #ifdef B57600
     512             :     {"B57600", B57600},
     513             : #endif
     514             : #ifdef B115200
     515             :     {"B115200", B115200},
     516             : #endif
     517             : #ifdef B230400
     518             :     {"B230400", B230400},
     519             : #endif
     520             : #ifdef B460800
     521             :     {"B460800", B460800},
     522             : #endif
     523             : #ifdef B500000
     524             :     {"B500000", B500000},
     525             : #endif
     526             : #ifdef B576000
     527             :     {"B576000", B576000},
     528             : #endif
     529             : #ifdef B921600
     530             :     {"B921600", B921600},
     531             : #endif
     532             : #ifdef B1000000
     533             :     {"B1000000", B1000000},
     534             : #endif
     535             : #ifdef B1152000
     536             :     {"B1152000", B1152000},
     537             : #endif
     538             : #ifdef B1500000
     539             :     {"B1500000", B1500000},
     540             : #endif
     541             : #ifdef B2000000
     542             :     {"B2000000", B2000000},
     543             : #endif
     544             : #ifdef B2500000
     545             :     {"B2500000", B2500000},
     546             : #endif
     547             : #ifdef B3000000
     548             :     {"B3000000", B3000000},
     549             : #endif
     550             : #ifdef B3500000
     551             :     {"B3500000", B3500000},
     552             : #endif
     553             : #ifdef B4000000
     554             :     {"B4000000", B4000000},
     555             : #endif
     556             : 
     557             : #ifdef CBAUDEX
     558             :     {"CBAUDEX", CBAUDEX},
     559             : #endif
     560             : 
     561             :     /* tcsetattr() constants */
     562             :     {"TCSANOW", TCSANOW},
     563             :     {"TCSADRAIN", TCSADRAIN},
     564             :     {"TCSAFLUSH", TCSAFLUSH},
     565             : #ifdef TCSASOFT
     566             :     {"TCSASOFT", TCSASOFT},
     567             : #endif
     568             : 
     569             :     /* tcflush() constants */
     570             :     {"TCIFLUSH", TCIFLUSH},
     571             :     {"TCOFLUSH", TCOFLUSH},
     572             :     {"TCIOFLUSH", TCIOFLUSH},
     573             : 
     574             :     /* tcflow() constants */
     575             :     {"TCOOFF", TCOOFF},
     576             :     {"TCOON", TCOON},
     577             :     {"TCIOFF", TCIOFF},
     578             :     {"TCION", TCION},
     579             : 
     580             :     /* struct termios.c_iflag constants */
     581             :     {"IGNBRK", IGNBRK},
     582             :     {"BRKINT", BRKINT},
     583             :     {"IGNPAR", IGNPAR},
     584             :     {"PARMRK", PARMRK},
     585             :     {"INPCK", INPCK},
     586             :     {"ISTRIP", ISTRIP},
     587             :     {"INLCR", INLCR},
     588             :     {"IGNCR", IGNCR},
     589             :     {"ICRNL", ICRNL},
     590             : #ifdef IUCLC
     591             :     {"IUCLC", IUCLC},
     592             : #endif
     593             :     {"IXON", IXON},
     594             :     {"IXANY", IXANY},
     595             :     {"IXOFF", IXOFF},
     596             : #ifdef IMAXBEL
     597             :     {"IMAXBEL", IMAXBEL},
     598             : #endif
     599             : 
     600             :     /* struct termios.c_oflag constants */
     601             :     {"OPOST", OPOST},
     602             : #ifdef OLCUC
     603             :     {"OLCUC", OLCUC},
     604             : #endif
     605             : #ifdef ONLCR
     606             :     {"ONLCR", ONLCR},
     607             : #endif
     608             : #ifdef OCRNL
     609             :     {"OCRNL", OCRNL},
     610             : #endif
     611             : #ifdef ONOCR
     612             :     {"ONOCR", ONOCR},
     613             : #endif
     614             : #ifdef ONLRET
     615             :     {"ONLRET", ONLRET},
     616             : #endif
     617             : #ifdef OFILL
     618             :     {"OFILL", OFILL},
     619             : #endif
     620             : #ifdef OFDEL
     621             :     {"OFDEL", OFDEL},
     622             : #endif
     623             : #ifdef NLDLY
     624             :     {"NLDLY", NLDLY},
     625             : #endif
     626             : #ifdef CRDLY
     627             :     {"CRDLY", CRDLY},
     628             : #endif
     629             : #ifdef TABDLY
     630             :     {"TABDLY", TABDLY},
     631             : #endif
     632             : #ifdef BSDLY
     633             :     {"BSDLY", BSDLY},
     634             : #endif
     635             : #ifdef VTDLY
     636             :     {"VTDLY", VTDLY},
     637             : #endif
     638             : #ifdef FFDLY
     639             :     {"FFDLY", FFDLY},
     640             : #endif
     641             : 
     642             :     /* struct termios.c_oflag-related values (delay mask) */
     643             : #ifdef NL0
     644             :     {"NL0", NL0},
     645             : #endif
     646             : #ifdef NL1
     647             :     {"NL1", NL1},
     648             : #endif
     649             : #ifdef CR0
     650             :     {"CR0", CR0},
     651             : #endif
     652             : #ifdef CR1
     653             :     {"CR1", CR1},
     654             : #endif
     655             : #ifdef CR2
     656             :     {"CR2", CR2},
     657             : #endif
     658             : #ifdef CR3
     659             :     {"CR3", CR3},
     660             : #endif
     661             : #ifdef TAB0
     662             :     {"TAB0", TAB0},
     663             : #endif
     664             : #ifdef TAB1
     665             :     {"TAB1", TAB1},
     666             : #endif
     667             : #ifdef TAB2
     668             :     {"TAB2", TAB2},
     669             : #endif
     670             : #ifdef TAB3
     671             :     {"TAB3", TAB3},
     672             : #endif
     673             : #ifdef XTABS
     674             :     {"XTABS", XTABS},
     675             : #endif
     676             : #ifdef BS0
     677             :     {"BS0", BS0},
     678             : #endif
     679             : #ifdef BS1
     680             :     {"BS1", BS1},
     681             : #endif
     682             : #ifdef VT0
     683             :     {"VT0", VT0},
     684             : #endif
     685             : #ifdef VT1
     686             :     {"VT1", VT1},
     687             : #endif
     688             : #ifdef FF0
     689             :     {"FF0", FF0},
     690             : #endif
     691             : #ifdef FF1
     692             :     {"FF1", FF1},
     693             : #endif
     694             : 
     695             :     /* struct termios.c_cflag constants */
     696             :     {"CSIZE", CSIZE},
     697             :     {"CSTOPB", CSTOPB},
     698             :     {"CREAD", CREAD},
     699             :     {"PARENB", PARENB},
     700             :     {"PARODD", PARODD},
     701             :     {"HUPCL", HUPCL},
     702             :     {"CLOCAL", CLOCAL},
     703             : #ifdef CIBAUD
     704             :     {"CIBAUD", CIBAUD},
     705             : #endif
     706             : #ifdef CRTSCTS
     707             :     {"CRTSCTS", (long)CRTSCTS},
     708             : #endif
     709             : 
     710             :     /* struct termios.c_cflag-related values (character size) */
     711             :     {"CS5", CS5},
     712             :     {"CS6", CS6},
     713             :     {"CS7", CS7},
     714             :     {"CS8", CS8},
     715             : 
     716             :     /* struct termios.c_lflag constants */
     717             :     {"ISIG", ISIG},
     718             :     {"ICANON", ICANON},
     719             : #ifdef XCASE
     720             :     {"XCASE", XCASE},
     721             : #endif
     722             :     {"ECHO", ECHO},
     723             :     {"ECHOE", ECHOE},
     724             :     {"ECHOK", ECHOK},
     725             :     {"ECHONL", ECHONL},
     726             : #ifdef ECHOCTL
     727             :     {"ECHOCTL", ECHOCTL},
     728             : #endif
     729             : #ifdef ECHOPRT
     730             :     {"ECHOPRT", ECHOPRT},
     731             : #endif
     732             : #ifdef ECHOKE
     733             :     {"ECHOKE", ECHOKE},
     734             : #endif
     735             : #ifdef FLUSHO
     736             :     {"FLUSHO", FLUSHO},
     737             : #endif
     738             :     {"NOFLSH", NOFLSH},
     739             :     {"TOSTOP", TOSTOP},
     740             : #ifdef PENDIN
     741             :     {"PENDIN", PENDIN},
     742             : #endif
     743             :     {"IEXTEN", IEXTEN},
     744             : 
     745             :     /* indexes into the control chars array returned by tcgetattr() */
     746             :     {"VINTR", VINTR},
     747             :     {"VQUIT", VQUIT},
     748             :     {"VERASE", VERASE},
     749             :     {"VKILL", VKILL},
     750             :     {"VEOF", VEOF},
     751             :     {"VTIME", VTIME},
     752             :     {"VMIN", VMIN},
     753             : #ifdef VSWTC
     754             :     /* The #defines above ensure that if either is defined, both are,
     755             :      * but both may be omitted by the system headers.  ;-(  */
     756             :     {"VSWTC", VSWTC},
     757             :     {"VSWTCH", VSWTCH},
     758             : #endif
     759             :     {"VSTART", VSTART},
     760             :     {"VSTOP", VSTOP},
     761             :     {"VSUSP", VSUSP},
     762             :     {"VEOL", VEOL},
     763             : #ifdef VREPRINT
     764             :     {"VREPRINT", VREPRINT},
     765             : #endif
     766             : #ifdef VDISCARD
     767             :     {"VDISCARD", VDISCARD},
     768             : #endif
     769             : #ifdef VWERASE
     770             :     {"VWERASE", VWERASE},
     771             : #endif
     772             : #ifdef VLNEXT
     773             :     {"VLNEXT", VLNEXT},
     774             : #endif
     775             : #ifdef VEOL2
     776             :     {"VEOL2", VEOL2},
     777             : #endif
     778             : 
     779             : 
     780             : #ifdef B460800
     781             :     {"B460800", B460800},
     782             : #endif
     783             : #ifdef B500000
     784             :     {"B500000", B500000},
     785             : #endif
     786             : #ifdef B576000
     787             :     { "B576000", B576000},
     788             : #endif
     789             : #ifdef B921600
     790             :     { "B921600", B921600},
     791             : #endif
     792             : #ifdef B1000000
     793             :     { "B1000000", B1000000},
     794             : #endif
     795             : #ifdef B1152000
     796             :     { "B1152000", B1152000},
     797             : #endif
     798             : #ifdef B1500000
     799             :     { "B1500000", B1500000},
     800             : #endif
     801             : #ifdef B2000000
     802             :     { "B2000000", B2000000},
     803             : #endif
     804             : #ifdef B2500000
     805             :     { "B2500000", B2500000},
     806             : #endif
     807             : #ifdef B3000000
     808             :     { "B3000000", B3000000},
     809             : #endif
     810             : #ifdef B3500000
     811             :     { "B3500000", B3500000},
     812             : #endif
     813             : #ifdef B4000000
     814             :     { "B4000000", B4000000},
     815             : #endif
     816             : #ifdef CBAUD
     817             :     {"CBAUD", CBAUD},
     818             : #endif
     819             : #ifdef CDEL
     820             :     {"CDEL", CDEL},
     821             : #endif
     822             : #ifdef CDSUSP
     823             :     {"CDSUSP", CDSUSP},
     824             : #endif
     825             : #ifdef CEOF
     826             :     {"CEOF", CEOF},
     827             : #endif
     828             : #ifdef CEOL
     829             :     {"CEOL", CEOL},
     830             : #endif
     831             : #ifdef CEOL2
     832             :     {"CEOL2", CEOL2},
     833             : #endif
     834             : #ifdef CEOT
     835             :     {"CEOT", CEOT},
     836             : #endif
     837             : #ifdef CERASE
     838             :     {"CERASE", CERASE},
     839             : #endif
     840             : #ifdef CESC
     841             :     {"CESC", CESC},
     842             : #endif
     843             : #ifdef CFLUSH
     844             :     {"CFLUSH", CFLUSH},
     845             : #endif
     846             : #ifdef CINTR
     847             :     {"CINTR", CINTR},
     848             : #endif
     849             : #ifdef CKILL
     850             :     {"CKILL", CKILL},
     851             : #endif
     852             : #ifdef CLNEXT
     853             :     {"CLNEXT", CLNEXT},
     854             : #endif
     855             : #ifdef CNUL
     856             :     {"CNUL", CNUL},
     857             : #endif
     858             : #ifdef COMMON
     859             :     {"COMMON", COMMON},
     860             : #endif
     861             : #ifdef CQUIT
     862             :     {"CQUIT", CQUIT},
     863             : #endif
     864             : #ifdef CRPRNT
     865             :     {"CRPRNT", CRPRNT},
     866             : #endif
     867             : #ifdef CSTART
     868             :     {"CSTART", CSTART},
     869             : #endif
     870             : #ifdef CSTOP
     871             :     {"CSTOP", CSTOP},
     872             : #endif
     873             : #ifdef CSUSP
     874             :     {"CSUSP", CSUSP},
     875             : #endif
     876             : #ifdef CSWTCH
     877             :     {"CSWTCH", CSWTCH},
     878             : #endif
     879             : #ifdef CWERASE
     880             :     {"CWERASE", CWERASE},
     881             : #endif
     882             : #ifdef EXTA
     883             :     {"EXTA", EXTA},
     884             : #endif
     885             : #ifdef EXTB
     886             :     {"EXTB", EXTB},
     887             : #endif
     888             : #ifdef FIOASYNC
     889             :     {"FIOASYNC", FIOASYNC},
     890             : #endif
     891             : #ifdef FIOCLEX
     892             :     {"FIOCLEX", FIOCLEX},
     893             : #endif
     894             : #ifdef FIONBIO
     895             :     {"FIONBIO", FIONBIO},
     896             : #endif
     897             : #ifdef FIONCLEX
     898             :     {"FIONCLEX", FIONCLEX},
     899             : #endif
     900             : #ifdef FIONREAD
     901             :     {"FIONREAD", FIONREAD},
     902             : #endif
     903             : #ifdef IBSHIFT
     904             :     {"IBSHIFT", IBSHIFT},
     905             : #endif
     906             : #ifdef INIT_C_CC
     907             :     {"INIT_C_CC", INIT_C_CC},
     908             : #endif
     909             : #ifdef IOCSIZE_MASK
     910             :     {"IOCSIZE_MASK", IOCSIZE_MASK},
     911             : #endif
     912             : #ifdef IOCSIZE_SHIFT
     913             :     {"IOCSIZE_SHIFT", IOCSIZE_SHIFT},
     914             : #endif
     915             : #ifdef NCC
     916             :     {"NCC", NCC},
     917             : #endif
     918             : #ifdef NCCS
     919             :     {"NCCS", NCCS},
     920             : #endif
     921             : #ifdef NSWTCH
     922             :     {"NSWTCH", NSWTCH},
     923             : #endif
     924             : #ifdef N_MOUSE
     925             :     {"N_MOUSE", N_MOUSE},
     926             : #endif
     927             : #ifdef N_PPP
     928             :     {"N_PPP", N_PPP},
     929             : #endif
     930             : #ifdef N_SLIP
     931             :     {"N_SLIP", N_SLIP},
     932             : #endif
     933             : #ifdef N_STRIP
     934             :     {"N_STRIP", N_STRIP},
     935             : #endif
     936             : #ifdef N_TTY
     937             :     {"N_TTY", N_TTY},
     938             : #endif
     939             : #ifdef TCFLSH
     940             :     {"TCFLSH", TCFLSH},
     941             : #endif
     942             : #ifdef TCGETA
     943             :     {"TCGETA", TCGETA},
     944             : #endif
     945             : #ifdef TCGETS
     946             :     {"TCGETS", TCGETS},
     947             : #endif
     948             : #ifdef TCSBRK
     949             :     {"TCSBRK", TCSBRK},
     950             : #endif
     951             : #ifdef TCSBRKP
     952             :     {"TCSBRKP", TCSBRKP},
     953             : #endif
     954             : #ifdef TCSETA
     955             :     {"TCSETA", TCSETA},
     956             : #endif
     957             : #ifdef TCSETAF
     958             :     {"TCSETAF", TCSETAF},
     959             : #endif
     960             : #ifdef TCSETAW
     961             :     {"TCSETAW", TCSETAW},
     962             : #endif
     963             : #ifdef TCSETS
     964             :     {"TCSETS", TCSETS},
     965             : #endif
     966             : #ifdef TCSETSF
     967             :     {"TCSETSF", TCSETSF},
     968             : #endif
     969             : #ifdef TCSETSW
     970             :     {"TCSETSW", TCSETSW},
     971             : #endif
     972             : #ifdef TCXONC
     973             :     {"TCXONC", TCXONC},
     974             : #endif
     975             : #ifdef TIOCCONS
     976             :     {"TIOCCONS", TIOCCONS},
     977             : #endif
     978             : #ifdef TIOCEXCL
     979             :     {"TIOCEXCL", TIOCEXCL},
     980             : #endif
     981             : #ifdef TIOCGETD
     982             :     {"TIOCGETD", TIOCGETD},
     983             : #endif
     984             : #ifdef TIOCGICOUNT
     985             :     {"TIOCGICOUNT", TIOCGICOUNT},
     986             : #endif
     987             : #ifdef TIOCGLCKTRMIOS
     988             :     {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS},
     989             : #endif
     990             : #ifdef TIOCGPGRP
     991             :     {"TIOCGPGRP", TIOCGPGRP},
     992             : #endif
     993             : #ifdef TIOCGSERIAL
     994             :     {"TIOCGSERIAL", TIOCGSERIAL},
     995             : #endif
     996             : #ifdef TIOCGSIZE
     997             :     {"TIOCGSIZE", TIOCGSIZE},
     998             : #endif
     999             : #ifdef TIOCGSOFTCAR
    1000             :     {"TIOCGSOFTCAR", TIOCGSOFTCAR},
    1001             : #endif
    1002             : #ifdef TIOCGWINSZ
    1003             :     {"TIOCGWINSZ", TIOCGWINSZ},
    1004             : #endif
    1005             : #ifdef TIOCINQ
    1006             :     {"TIOCINQ", TIOCINQ},
    1007             : #endif
    1008             : #ifdef TIOCLINUX
    1009             :     {"TIOCLINUX", TIOCLINUX},
    1010             : #endif
    1011             : #ifdef TIOCMBIC
    1012             :     {"TIOCMBIC", TIOCMBIC},
    1013             : #endif
    1014             : #ifdef TIOCMBIS
    1015             :     {"TIOCMBIS", TIOCMBIS},
    1016             : #endif
    1017             : #ifdef TIOCMGET
    1018             :     {"TIOCMGET", TIOCMGET},
    1019             : #endif
    1020             : #ifdef TIOCMIWAIT
    1021             :     {"TIOCMIWAIT", TIOCMIWAIT},
    1022             : #endif
    1023             : #ifdef TIOCMSET
    1024             :     {"TIOCMSET", TIOCMSET},
    1025             : #endif
    1026             : #ifdef TIOCM_CAR
    1027             :     {"TIOCM_CAR", TIOCM_CAR},
    1028             : #endif
    1029             : #ifdef TIOCM_CD
    1030             :     {"TIOCM_CD", TIOCM_CD},
    1031             : #endif
    1032             : #ifdef TIOCM_CTS
    1033             :     {"TIOCM_CTS", TIOCM_CTS},
    1034             : #endif
    1035             : #ifdef TIOCM_DSR
    1036             :     {"TIOCM_DSR", TIOCM_DSR},
    1037             : #endif
    1038             : #ifdef TIOCM_DTR
    1039             :     {"TIOCM_DTR", TIOCM_DTR},
    1040             : #endif
    1041             : #ifdef TIOCM_LE
    1042             :     {"TIOCM_LE", TIOCM_LE},
    1043             : #endif
    1044             : #ifdef TIOCM_RI
    1045             :     {"TIOCM_RI", TIOCM_RI},
    1046             : #endif
    1047             : #ifdef TIOCM_RNG
    1048             :     {"TIOCM_RNG", TIOCM_RNG},
    1049             : #endif
    1050             : #ifdef TIOCM_RTS
    1051             :     {"TIOCM_RTS", TIOCM_RTS},
    1052             : #endif
    1053             : #ifdef TIOCM_SR
    1054             :     {"TIOCM_SR", TIOCM_SR},
    1055             : #endif
    1056             : #ifdef TIOCM_ST
    1057             :     {"TIOCM_ST", TIOCM_ST},
    1058             : #endif
    1059             : #ifdef TIOCNOTTY
    1060             :     {"TIOCNOTTY", TIOCNOTTY},
    1061             : #endif
    1062             : #ifdef TIOCNXCL
    1063             :     {"TIOCNXCL", TIOCNXCL},
    1064             : #endif
    1065             : #ifdef TIOCOUTQ
    1066             :     {"TIOCOUTQ", TIOCOUTQ},
    1067             : #endif
    1068             : #ifdef TIOCPKT
    1069             :     {"TIOCPKT", TIOCPKT},
    1070             : #endif
    1071             : #ifdef TIOCPKT_DATA
    1072             :     {"TIOCPKT_DATA", TIOCPKT_DATA},
    1073             : #endif
    1074             : #ifdef TIOCPKT_DOSTOP
    1075             :     {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP},
    1076             : #endif
    1077             : #ifdef TIOCPKT_FLUSHREAD
    1078             :     {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD},
    1079             : #endif
    1080             : #ifdef TIOCPKT_FLUSHWRITE
    1081             :     {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE},
    1082             : #endif
    1083             : #ifdef TIOCPKT_NOSTOP
    1084             :     {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP},
    1085             : #endif
    1086             : #ifdef TIOCPKT_START
    1087             :     {"TIOCPKT_START", TIOCPKT_START},
    1088             : #endif
    1089             : #ifdef TIOCPKT_STOP
    1090             :     {"TIOCPKT_STOP", TIOCPKT_STOP},
    1091             : #endif
    1092             : #ifdef TIOCSCTTY
    1093             :     {"TIOCSCTTY", TIOCSCTTY},
    1094             : #endif
    1095             : #ifdef TIOCSERCONFIG
    1096             :     {"TIOCSERCONFIG", TIOCSERCONFIG},
    1097             : #endif
    1098             : #ifdef TIOCSERGETLSR
    1099             :     {"TIOCSERGETLSR", TIOCSERGETLSR},
    1100             : #endif
    1101             : #ifdef TIOCSERGETMULTI
    1102             :     {"TIOCSERGETMULTI", TIOCSERGETMULTI},
    1103             : #endif
    1104             : #ifdef TIOCSERGSTRUCT
    1105             :     {"TIOCSERGSTRUCT", TIOCSERGSTRUCT},
    1106             : #endif
    1107             : #ifdef TIOCSERGWILD
    1108             :     {"TIOCSERGWILD", TIOCSERGWILD},
    1109             : #endif
    1110             : #ifdef TIOCSERSETMULTI
    1111             :     {"TIOCSERSETMULTI", TIOCSERSETMULTI},
    1112             : #endif
    1113             : #ifdef TIOCSERSWILD
    1114             :     {"TIOCSERSWILD", TIOCSERSWILD},
    1115             : #endif
    1116             : #ifdef TIOCSER_TEMT
    1117             :     {"TIOCSER_TEMT", TIOCSER_TEMT},
    1118             : #endif
    1119             : #ifdef TIOCSETD
    1120             :     {"TIOCSETD", TIOCSETD},
    1121             : #endif
    1122             : #ifdef TIOCSLCKTRMIOS
    1123             :     {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS},
    1124             : #endif
    1125             : #ifdef TIOCSPGRP
    1126             :     {"TIOCSPGRP", TIOCSPGRP},
    1127             : #endif
    1128             : #ifdef TIOCSSERIAL
    1129             :     {"TIOCSSERIAL", TIOCSSERIAL},
    1130             : #endif
    1131             : #ifdef TIOCSSIZE
    1132             :     {"TIOCSSIZE", TIOCSSIZE},
    1133             : #endif
    1134             : #ifdef TIOCSSOFTCAR
    1135             :     {"TIOCSSOFTCAR", TIOCSSOFTCAR},
    1136             : #endif
    1137             : #ifdef TIOCSTI
    1138             :     {"TIOCSTI", TIOCSTI},
    1139             : #endif
    1140             : #ifdef TIOCSWINSZ
    1141             :     {"TIOCSWINSZ", TIOCSWINSZ},
    1142             : #endif
    1143             : #ifdef TIOCTTYGSTRUCT
    1144             :     {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT},
    1145             : #endif
    1146             : 
    1147             :     /* sentinel */
    1148             :     {NULL, 0}
    1149             : };
    1150             : 
    1151       41095 : static int termiosmodule_traverse(PyObject *m, visitproc visit, void *arg) {
    1152       41095 :     Py_VISIT(get_termios_state(m)->TermiosError);
    1153       41095 :     return 0;
    1154             : }
    1155             : 
    1156        1766 : static int termiosmodule_clear(PyObject *m) {
    1157        1766 :     Py_CLEAR(get_termios_state(m)->TermiosError);
    1158        1766 :     return 0;
    1159             : }
    1160             : 
    1161        1163 : static void termiosmodule_free(void *m) {
    1162        1163 :     termiosmodule_clear((PyObject *)m);
    1163        1163 : }
    1164             : 
    1165             : static int
    1166        1165 : termios_exec(PyObject *mod)
    1167             : {
    1168        1165 :     struct constant *constant = termios_constants;
    1169        1165 :     termiosmodulestate *state = get_termios_state(mod);
    1170        1165 :     state->TermiosError = PyErr_NewException("termios.error", NULL, NULL);
    1171        1165 :     if (state->TermiosError == NULL) {
    1172           0 :         return -1;
    1173             :     }
    1174        1165 :     Py_INCREF(state->TermiosError);
    1175        1165 :     if (PyModule_AddObject(mod, "error", state->TermiosError) < 0) {
    1176           0 :         Py_DECREF(state->TermiosError);
    1177           0 :         return -1;
    1178             :     }
    1179             : 
    1180      284260 :     while (constant->name != NULL) {
    1181      283095 :         if (PyModule_AddIntConstant(
    1182      283095 :             mod, constant->name, constant->value) < 0) {
    1183           0 :             return -1;
    1184             :         }
    1185      283095 :         ++constant;
    1186             :     }
    1187        1165 :     return 0;
    1188             : }
    1189             : 
    1190             : static PyModuleDef_Slot termios_slots[] = {
    1191             :     {Py_mod_exec, termios_exec},
    1192             :     {0, NULL}
    1193             : };
    1194             : 
    1195             : static struct PyModuleDef termiosmodule = {
    1196             :     PyModuleDef_HEAD_INIT,
    1197             :     .m_name = "termios",
    1198             :     .m_doc = termios__doc__,
    1199             :     .m_size = sizeof(termiosmodulestate),
    1200             :     .m_methods = termios_methods,
    1201             :     .m_slots = termios_slots,
    1202             :     .m_traverse = termiosmodule_traverse,
    1203             :     .m_clear = termiosmodule_clear,
    1204             :     .m_free = termiosmodule_free,
    1205             : };
    1206             : 
    1207        1165 : PyMODINIT_FUNC PyInit_termios(void)
    1208             : {
    1209        1165 :     return PyModuleDef_Init(&termiosmodule);
    1210             : }

Generated by: LCOV version 1.14