termios.c 28 KB

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