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