/Modules/termios.c

http://unladen-swallow.googlecode.com/ · C · 926 lines · 832 code · 66 blank · 28 comment · 60 complexity · cbbb236c6a516b379d34a4d12b9cfd30 MD5 · raw file

  1. /* termiosmodule.c -- POSIX terminal I/O module implementation. */
  2. #include "Python.h"
  3. #define PyInit_termios inittermios
  4. /* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE
  5. is defined, so we define it here. */
  6. #if defined(__sgi)
  7. #define CTRL(c) ((c)&037)
  8. #endif
  9. #include <termios.h>
  10. #ifdef __osf__
  11. /* On OSF, sys/ioctl.h requires that struct termio already be defined,
  12. * so this needs to be included first on that platform. */
  13. #include <termio.h>
  14. #endif
  15. #include <sys/ioctl.h>
  16. /* HP-UX requires that this be included to pick up MDCD, MCTS, MDSR,
  17. * MDTR, MRI, and MRTS (appearantly used internally by some things
  18. * defined as macros; these are not used here directly).
  19. */
  20. #ifdef HAVE_SYS_MODEM_H
  21. #include <sys/modem.h>
  22. #endif
  23. /* HP-UX requires that this be included to pick up TIOCGPGRP and friends */
  24. #ifdef HAVE_SYS_BSDTTY_H
  25. #include <sys/bsdtty.h>
  26. #endif
  27. PyDoc_STRVAR(termios__doc__,
  28. "This module provides an interface to the Posix calls for tty I/O control.\n\
  29. For a complete description of these calls, see the Posix or Unix manual\n\
  30. pages. It is only available for those Unix versions that support Posix\n\
  31. termios style tty I/O control.\n\
  32. \n\
  33. All functions in this module take a file descriptor fd as their first\n\
  34. argument. This can be an integer file descriptor, such as returned by\n\
  35. sys.stdin.fileno(), or a file object, such as sys.stdin itself.");
  36. static PyObject *TermiosError;
  37. static int fdconv(PyObject* obj, void* p)
  38. {
  39. int fd;
  40. fd = PyObject_AsFileDescriptor(obj);
  41. if (fd >= 0) {
  42. *(int*)p = fd;
  43. return 1;
  44. }
  45. return 0;
  46. }
  47. PyDoc_STRVAR(termios_tcgetattr__doc__,
  48. "tcgetattr(fd) -> list_of_attrs\n\
  49. \n\
  50. Get the tty attributes for file descriptor fd, as follows:\n\
  51. [iflag, oflag, cflag, lflag, ispeed, ospeed, cc] where cc is a list\n\
  52. of the tty special characters (each a string of length 1, except the items\n\
  53. with indices VMIN and VTIME, which are integers when these fields are\n\
  54. defined). The interpretation of the flags and the speeds as well as the\n\
  55. indexing in the cc array must be done using the symbolic constants defined\n\
  56. in this module.");
  57. static PyObject *
  58. termios_tcgetattr(PyObject *self, PyObject *args)
  59. {
  60. int fd;
  61. struct termios mode;
  62. PyObject *cc;
  63. speed_t ispeed, ospeed;
  64. PyObject *v;
  65. int i;
  66. char ch;
  67. if (!PyArg_ParseTuple(args, "O&:tcgetattr",
  68. fdconv, (void*)&fd))
  69. return NULL;
  70. if (tcgetattr(fd, &mode) == -1)
  71. return PyErr_SetFromErrno(TermiosError);
  72. ispeed = cfgetispeed(&mode);
  73. ospeed = cfgetospeed(&mode);
  74. cc = PyList_New(NCCS);
  75. if (cc == NULL)
  76. return NULL;
  77. for (i = 0; i < NCCS; i++) {
  78. ch = (char)mode.c_cc[i];
  79. v = PyString_FromStringAndSize(&ch, 1);
  80. if (v == NULL)
  81. goto err;
  82. PyList_SetItem(cc, i, v);
  83. }
  84. /* Convert the MIN and TIME slots to integer. On some systems, the
  85. MIN and TIME slots are the same as the EOF and EOL slots. So we
  86. only do this in noncanonical input mode. */
  87. if ((mode.c_lflag & ICANON) == 0) {
  88. v = PyInt_FromLong((long)mode.c_cc[VMIN]);
  89. if (v == NULL)
  90. goto err;
  91. PyList_SetItem(cc, VMIN, v);
  92. v = PyInt_FromLong((long)mode.c_cc[VTIME]);
  93. if (v == NULL)
  94. goto err;
  95. PyList_SetItem(cc, VTIME, v);
  96. }
  97. if (!(v = PyList_New(7)))
  98. goto err;
  99. PyList_SetItem(v, 0, PyInt_FromLong((long)mode.c_iflag));
  100. PyList_SetItem(v, 1, PyInt_FromLong((long)mode.c_oflag));
  101. PyList_SetItem(v, 2, PyInt_FromLong((long)mode.c_cflag));
  102. PyList_SetItem(v, 3, PyInt_FromLong((long)mode.c_lflag));
  103. PyList_SetItem(v, 4, PyInt_FromLong((long)ispeed));
  104. PyList_SetItem(v, 5, PyInt_FromLong((long)ospeed));
  105. PyList_SetItem(v, 6, cc);
  106. if (PyErr_Occurred()){
  107. Py_DECREF(v);
  108. goto err;
  109. }
  110. return v;
  111. err:
  112. Py_DECREF(cc);
  113. return NULL;
  114. }
  115. PyDoc_STRVAR(termios_tcsetattr__doc__,
  116. "tcsetattr(fd, when, attributes) -> None\n\
  117. \n\
  118. Set the tty attributes for file descriptor fd.\n\
  119. The attributes to be set are taken from the attributes argument, which\n\
  120. is a list like the one returned by tcgetattr(). The when argument\n\
  121. determines when the attributes are changed: termios.TCSANOW to\n\
  122. change immediately, termios.TCSADRAIN to change after transmitting all\n\
  123. queued output, or termios.TCSAFLUSH to change after transmitting all\n\
  124. queued output and discarding all queued input. ");
  125. static PyObject *
  126. termios_tcsetattr(PyObject *self, PyObject *args)
  127. {
  128. int fd, when;
  129. struct termios mode;
  130. speed_t ispeed, ospeed;
  131. PyObject *term, *cc, *v;
  132. int i;
  133. if (!PyArg_ParseTuple(args, "O&iO:tcsetattr",
  134. fdconv, &fd, &when, &term))
  135. return NULL;
  136. if (!PyList_Check(term) || PyList_Size(term) != 7) {
  137. PyErr_SetString(PyExc_TypeError,
  138. "tcsetattr, arg 3: must be 7 element list");
  139. return NULL;
  140. }
  141. /* Get the old mode, in case there are any hidden fields... */
  142. if (tcgetattr(fd, &mode) == -1)
  143. return PyErr_SetFromErrno(TermiosError);
  144. mode.c_iflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 0));
  145. mode.c_oflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 1));
  146. mode.c_cflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 2));
  147. mode.c_lflag = (tcflag_t) PyInt_AsLong(PyList_GetItem(term, 3));
  148. ispeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 4));
  149. ospeed = (speed_t) PyInt_AsLong(PyList_GetItem(term, 5));
  150. cc = PyList_GetItem(term, 6);
  151. if (PyErr_Occurred())
  152. return NULL;
  153. if (!PyList_Check(cc) || PyList_Size(cc) != NCCS) {
  154. PyErr_Format(PyExc_TypeError,
  155. "tcsetattr: attributes[6] must be %d element list",
  156. NCCS);
  157. return NULL;
  158. }
  159. for (i = 0; i < NCCS; i++) {
  160. v = PyList_GetItem(cc, i);
  161. if (PyString_Check(v) && PyString_Size(v) == 1)
  162. mode.c_cc[i] = (cc_t) * PyString_AsString(v);
  163. else if (PyInt_Check(v))
  164. mode.c_cc[i] = (cc_t) PyInt_AsLong(v);
  165. else {
  166. PyErr_SetString(PyExc_TypeError,
  167. "tcsetattr: elements of attributes must be characters or integers");
  168. return NULL;
  169. }
  170. }
  171. if (cfsetispeed(&mode, (speed_t) ispeed) == -1)
  172. return PyErr_SetFromErrno(TermiosError);
  173. if (cfsetospeed(&mode, (speed_t) ospeed) == -1)
  174. return PyErr_SetFromErrno(TermiosError);
  175. if (tcsetattr(fd, when, &mode) == -1)
  176. return PyErr_SetFromErrno(TermiosError);
  177. Py_INCREF(Py_None);
  178. return Py_None;
  179. }
  180. PyDoc_STRVAR(termios_tcsendbreak__doc__,
  181. "tcsendbreak(fd, duration) -> None\n\
  182. \n\
  183. Send a break on file descriptor fd.\n\
  184. A zero duration sends a break for 0.25-0.5 seconds; a nonzero duration\n\
  185. has a system dependent meaning.");
  186. static PyObject *
  187. termios_tcsendbreak(PyObject *self, PyObject *args)
  188. {
  189. int fd, duration;
  190. if (!PyArg_ParseTuple(args, "O&i:tcsendbreak",
  191. fdconv, &fd, &duration))
  192. return NULL;
  193. if (tcsendbreak(fd, duration) == -1)
  194. return PyErr_SetFromErrno(TermiosError);
  195. Py_INCREF(Py_None);
  196. return Py_None;
  197. }
  198. PyDoc_STRVAR(termios_tcdrain__doc__,
  199. "tcdrain(fd) -> None\n\
  200. \n\
  201. Wait until all output written to file descriptor fd has been transmitted.");
  202. static PyObject *
  203. termios_tcdrain(PyObject *self, PyObject *args)
  204. {
  205. int fd;
  206. if (!PyArg_ParseTuple(args, "O&:tcdrain",
  207. fdconv, &fd))
  208. return NULL;
  209. if (tcdrain(fd) == -1)
  210. return PyErr_SetFromErrno(TermiosError);
  211. Py_INCREF(Py_None);
  212. return Py_None;
  213. }
  214. PyDoc_STRVAR(termios_tcflush__doc__,
  215. "tcflush(fd, queue) -> None\n\
  216. \n\
  217. Discard queued data on file descriptor fd.\n\
  218. The queue selector specifies which queue: termios.TCIFLUSH for the input\n\
  219. queue, termios.TCOFLUSH for the output queue, or termios.TCIOFLUSH for\n\
  220. both queues. ");
  221. static PyObject *
  222. termios_tcflush(PyObject *self, PyObject *args)
  223. {
  224. int fd, queue;
  225. if (!PyArg_ParseTuple(args, "O&i:tcflush",
  226. fdconv, &fd, &queue))
  227. return NULL;
  228. if (tcflush(fd, queue) == -1)
  229. return PyErr_SetFromErrno(TermiosError);
  230. Py_INCREF(Py_None);
  231. return Py_None;
  232. }
  233. PyDoc_STRVAR(termios_tcflow__doc__,
  234. "tcflow(fd, action) -> None\n\
  235. \n\
  236. Suspend or resume input or output on file descriptor fd.\n\
  237. The action argument can be termios.TCOOFF to suspend output,\n\
  238. termios.TCOON to restart output, termios.TCIOFF to suspend input,\n\
  239. or termios.TCION to restart input.");
  240. static PyObject *
  241. termios_tcflow(PyObject *self, PyObject *args)
  242. {
  243. int fd, action;
  244. if (!PyArg_ParseTuple(args, "O&i:tcflow",
  245. fdconv, &fd, &action))
  246. return NULL;
  247. if (tcflow(fd, action) == -1)
  248. return PyErr_SetFromErrno(TermiosError);
  249. Py_INCREF(Py_None);
  250. return Py_None;
  251. }
  252. static PyMethodDef termios_methods[] =
  253. {
  254. {"tcgetattr", termios_tcgetattr,
  255. METH_VARARGS, termios_tcgetattr__doc__},
  256. {"tcsetattr", termios_tcsetattr,
  257. METH_VARARGS, termios_tcsetattr__doc__},
  258. {"tcsendbreak", termios_tcsendbreak,
  259. METH_VARARGS, termios_tcsendbreak__doc__},
  260. {"tcdrain", termios_tcdrain,
  261. METH_VARARGS, termios_tcdrain__doc__},
  262. {"tcflush", termios_tcflush,
  263. METH_VARARGS, termios_tcflush__doc__},
  264. {"tcflow", termios_tcflow,
  265. METH_VARARGS, termios_tcflow__doc__},
  266. {NULL, NULL}
  267. };
  268. #if defined(VSWTCH) && !defined(VSWTC)
  269. #define VSWTC VSWTCH
  270. #endif
  271. #if defined(VSWTC) && !defined(VSWTCH)
  272. #define VSWTCH VSWTC
  273. #endif
  274. static struct constant {
  275. char *name;
  276. long value;
  277. } termios_constants[] = {
  278. /* cfgetospeed(), cfsetospeed() constants */
  279. {"B0", B0},
  280. {"B50", B50},
  281. {"B75", B75},
  282. {"B110", B110},
  283. {"B134", B134},
  284. {"B150", B150},
  285. {"B200", B200},
  286. {"B300", B300},
  287. {"B600", B600},
  288. {"B1200", B1200},
  289. {"B1800", B1800},
  290. {"B2400", B2400},
  291. {"B4800", B4800},
  292. {"B9600", B9600},
  293. {"B19200", B19200},
  294. {"B38400", B38400},
  295. #ifdef B57600
  296. {"B57600", B57600},
  297. #endif
  298. #ifdef B115200
  299. {"B115200", B115200},
  300. #endif
  301. #ifdef B230400
  302. {"B230400", B230400},
  303. #endif
  304. #ifdef CBAUDEX
  305. {"CBAUDEX", CBAUDEX},
  306. #endif
  307. /* tcsetattr() constants */
  308. {"TCSANOW", TCSANOW},
  309. {"TCSADRAIN", TCSADRAIN},
  310. {"TCSAFLUSH", TCSAFLUSH},
  311. /* tcflush() constants */
  312. {"TCIFLUSH", TCIFLUSH},
  313. {"TCOFLUSH", TCOFLUSH},
  314. {"TCIOFLUSH", TCIOFLUSH},
  315. /* tcflow() constants */
  316. {"TCOOFF", TCOOFF},
  317. {"TCOON", TCOON},
  318. {"TCIOFF", TCIOFF},
  319. {"TCION", TCION},
  320. /* struct termios.c_iflag constants */
  321. {"IGNBRK", IGNBRK},
  322. {"BRKINT", BRKINT},
  323. {"IGNPAR", IGNPAR},
  324. {"PARMRK", PARMRK},
  325. {"INPCK", INPCK},
  326. {"ISTRIP", ISTRIP},
  327. {"INLCR", INLCR},
  328. {"IGNCR", IGNCR},
  329. {"ICRNL", ICRNL},
  330. #ifdef IUCLC
  331. {"IUCLC", IUCLC},
  332. #endif
  333. {"IXON", IXON},
  334. {"IXANY", IXANY},
  335. {"IXOFF", IXOFF},
  336. #ifdef IMAXBEL
  337. {"IMAXBEL", IMAXBEL},
  338. #endif
  339. /* struct termios.c_oflag constants */
  340. {"OPOST", OPOST},
  341. #ifdef OLCUC
  342. {"OLCUC", OLCUC},
  343. #endif
  344. #ifdef ONLCR
  345. {"ONLCR", ONLCR},
  346. #endif
  347. #ifdef OCRNL
  348. {"OCRNL", OCRNL},
  349. #endif
  350. #ifdef ONOCR
  351. {"ONOCR", ONOCR},
  352. #endif
  353. #ifdef ONLRET
  354. {"ONLRET", ONLRET},
  355. #endif
  356. #ifdef OFILL
  357. {"OFILL", OFILL},
  358. #endif
  359. #ifdef OFDEL
  360. {"OFDEL", OFDEL},
  361. #endif
  362. #ifdef NLDLY
  363. {"NLDLY", NLDLY},
  364. #endif
  365. #ifdef CRDLY
  366. {"CRDLY", CRDLY},
  367. #endif
  368. #ifdef TABDLY
  369. {"TABDLY", TABDLY},
  370. #endif
  371. #ifdef BSDLY
  372. {"BSDLY", BSDLY},
  373. #endif
  374. #ifdef VTDLY
  375. {"VTDLY", VTDLY},
  376. #endif
  377. #ifdef FFDLY
  378. {"FFDLY", FFDLY},
  379. #endif
  380. /* struct termios.c_oflag-related values (delay mask) */
  381. #ifdef NL0
  382. {"NL0", NL0},
  383. #endif
  384. #ifdef NL1
  385. {"NL1", NL1},
  386. #endif
  387. #ifdef CR0
  388. {"CR0", CR0},
  389. #endif
  390. #ifdef CR1
  391. {"CR1", CR1},
  392. #endif
  393. #ifdef CR2
  394. {"CR2", CR2},
  395. #endif
  396. #ifdef CR3
  397. {"CR3", CR3},
  398. #endif
  399. #ifdef TAB0
  400. {"TAB0", TAB0},
  401. #endif
  402. #ifdef TAB1
  403. {"TAB1", TAB1},
  404. #endif
  405. #ifdef TAB2
  406. {"TAB2", TAB2},
  407. #endif
  408. #ifdef TAB3
  409. {"TAB3", TAB3},
  410. #endif
  411. #ifdef XTABS
  412. {"XTABS", XTABS},
  413. #endif
  414. #ifdef BS0
  415. {"BS0", BS0},
  416. #endif
  417. #ifdef BS1
  418. {"BS1", BS1},
  419. #endif
  420. #ifdef VT0
  421. {"VT0", VT0},
  422. #endif
  423. #ifdef VT1
  424. {"VT1", VT1},
  425. #endif
  426. #ifdef FF0
  427. {"FF0", FF0},
  428. #endif
  429. #ifdef FF1
  430. {"FF1", FF1},
  431. #endif
  432. /* struct termios.c_cflag constants */
  433. {"CSIZE", CSIZE},
  434. {"CSTOPB", CSTOPB},
  435. {"CREAD", CREAD},
  436. {"PARENB", PARENB},
  437. {"PARODD", PARODD},
  438. {"HUPCL", HUPCL},
  439. {"CLOCAL", CLOCAL},
  440. #ifdef CIBAUD
  441. {"CIBAUD", CIBAUD},
  442. #endif
  443. #ifdef CRTSCTS
  444. {"CRTSCTS", (long)CRTSCTS},
  445. #endif
  446. /* struct termios.c_cflag-related values (character size) */
  447. {"CS5", CS5},
  448. {"CS6", CS6},
  449. {"CS7", CS7},
  450. {"CS8", CS8},
  451. /* struct termios.c_lflag constants */
  452. {"ISIG", ISIG},
  453. {"ICANON", ICANON},
  454. #ifdef XCASE
  455. {"XCASE", XCASE},
  456. #endif
  457. {"ECHO", ECHO},
  458. {"ECHOE", ECHOE},
  459. {"ECHOK", ECHOK},
  460. {"ECHONL", ECHONL},
  461. #ifdef ECHOCTL
  462. {"ECHOCTL", ECHOCTL},
  463. #endif
  464. #ifdef ECHOPRT
  465. {"ECHOPRT", ECHOPRT},
  466. #endif
  467. #ifdef ECHOKE
  468. {"ECHOKE", ECHOKE},
  469. #endif
  470. #ifdef FLUSHO
  471. {"FLUSHO", FLUSHO},
  472. #endif
  473. {"NOFLSH", NOFLSH},
  474. {"TOSTOP", TOSTOP},
  475. #ifdef PENDIN
  476. {"PENDIN", PENDIN},
  477. #endif
  478. {"IEXTEN", IEXTEN},
  479. /* indexes into the control chars array returned by tcgetattr() */
  480. {"VINTR", VINTR},
  481. {"VQUIT", VQUIT},
  482. {"VERASE", VERASE},
  483. {"VKILL", VKILL},
  484. {"VEOF", VEOF},
  485. {"VTIME", VTIME},
  486. {"VMIN", VMIN},
  487. #ifdef VSWTC
  488. /* The #defines above ensure that if either is defined, both are,
  489. * but both may be omitted by the system headers. ;-( */
  490. {"VSWTC", VSWTC},
  491. {"VSWTCH", VSWTCH},
  492. #endif
  493. {"VSTART", VSTART},
  494. {"VSTOP", VSTOP},
  495. {"VSUSP", VSUSP},
  496. {"VEOL", VEOL},
  497. #ifdef VREPRINT
  498. {"VREPRINT", VREPRINT},
  499. #endif
  500. #ifdef VDISCARD
  501. {"VDISCARD", VDISCARD},
  502. #endif
  503. #ifdef VWERASE
  504. {"VWERASE", VWERASE},
  505. #endif
  506. #ifdef VLNEXT
  507. {"VLNEXT", VLNEXT},
  508. #endif
  509. #ifdef VEOL2
  510. {"VEOL2", VEOL2},
  511. #endif
  512. #ifdef B460800
  513. {"B460800", B460800},
  514. #endif
  515. #ifdef CBAUD
  516. {"CBAUD", CBAUD},
  517. #endif
  518. #ifdef CDEL
  519. {"CDEL", CDEL},
  520. #endif
  521. #ifdef CDSUSP
  522. {"CDSUSP", CDSUSP},
  523. #endif
  524. #ifdef CEOF
  525. {"CEOF", CEOF},
  526. #endif
  527. #ifdef CEOL
  528. {"CEOL", CEOL},
  529. #endif
  530. #ifdef CEOL2
  531. {"CEOL2", CEOL2},
  532. #endif
  533. #ifdef CEOT
  534. {"CEOT", CEOT},
  535. #endif
  536. #ifdef CERASE
  537. {"CERASE", CERASE},
  538. #endif
  539. #ifdef CESC
  540. {"CESC", CESC},
  541. #endif
  542. #ifdef CFLUSH
  543. {"CFLUSH", CFLUSH},
  544. #endif
  545. #ifdef CINTR
  546. {"CINTR", CINTR},
  547. #endif
  548. #ifdef CKILL
  549. {"CKILL", CKILL},
  550. #endif
  551. #ifdef CLNEXT
  552. {"CLNEXT", CLNEXT},
  553. #endif
  554. #ifdef CNUL
  555. {"CNUL", CNUL},
  556. #endif
  557. #ifdef COMMON
  558. {"COMMON", COMMON},
  559. #endif
  560. #ifdef CQUIT
  561. {"CQUIT", CQUIT},
  562. #endif
  563. #ifdef CRPRNT
  564. {"CRPRNT", CRPRNT},
  565. #endif
  566. #ifdef CSTART
  567. {"CSTART", CSTART},
  568. #endif
  569. #ifdef CSTOP
  570. {"CSTOP", CSTOP},
  571. #endif
  572. #ifdef CSUSP
  573. {"CSUSP", CSUSP},
  574. #endif
  575. #ifdef CSWTCH
  576. {"CSWTCH", CSWTCH},
  577. #endif
  578. #ifdef CWERASE
  579. {"CWERASE", CWERASE},
  580. #endif
  581. #ifdef EXTA
  582. {"EXTA", EXTA},
  583. #endif
  584. #ifdef EXTB
  585. {"EXTB", EXTB},
  586. #endif
  587. #ifdef FIOASYNC
  588. {"FIOASYNC", FIOASYNC},
  589. #endif
  590. #ifdef FIOCLEX
  591. {"FIOCLEX", FIOCLEX},
  592. #endif
  593. #ifdef FIONBIO
  594. {"FIONBIO", FIONBIO},
  595. #endif
  596. #ifdef FIONCLEX
  597. {"FIONCLEX", FIONCLEX},
  598. #endif
  599. #ifdef FIONREAD
  600. {"FIONREAD", FIONREAD},
  601. #endif
  602. #ifdef IBSHIFT
  603. {"IBSHIFT", IBSHIFT},
  604. #endif
  605. #ifdef INIT_C_CC
  606. {"INIT_C_CC", INIT_C_CC},
  607. #endif
  608. #ifdef IOCSIZE_MASK
  609. {"IOCSIZE_MASK", IOCSIZE_MASK},
  610. #endif
  611. #ifdef IOCSIZE_SHIFT
  612. {"IOCSIZE_SHIFT", IOCSIZE_SHIFT},
  613. #endif
  614. #ifdef NCC
  615. {"NCC", NCC},
  616. #endif
  617. #ifdef NCCS
  618. {"NCCS", NCCS},
  619. #endif
  620. #ifdef NSWTCH
  621. {"NSWTCH", NSWTCH},
  622. #endif
  623. #ifdef N_MOUSE
  624. {"N_MOUSE", N_MOUSE},
  625. #endif
  626. #ifdef N_PPP
  627. {"N_PPP", N_PPP},
  628. #endif
  629. #ifdef N_SLIP
  630. {"N_SLIP", N_SLIP},
  631. #endif
  632. #ifdef N_STRIP
  633. {"N_STRIP", N_STRIP},
  634. #endif
  635. #ifdef N_TTY
  636. {"N_TTY", N_TTY},
  637. #endif
  638. #ifdef TCFLSH
  639. {"TCFLSH", TCFLSH},
  640. #endif
  641. #ifdef TCGETA
  642. {"TCGETA", TCGETA},
  643. #endif
  644. #ifdef TCGETS
  645. {"TCGETS", TCGETS},
  646. #endif
  647. #ifdef TCSBRK
  648. {"TCSBRK", TCSBRK},
  649. #endif
  650. #ifdef TCSBRKP
  651. {"TCSBRKP", TCSBRKP},
  652. #endif
  653. #ifdef TCSETA
  654. {"TCSETA", TCSETA},
  655. #endif
  656. #ifdef TCSETAF
  657. {"TCSETAF", TCSETAF},
  658. #endif
  659. #ifdef TCSETAW
  660. {"TCSETAW", TCSETAW},
  661. #endif
  662. #ifdef TCSETS
  663. {"TCSETS", TCSETS},
  664. #endif
  665. #ifdef TCSETSF
  666. {"TCSETSF", TCSETSF},
  667. #endif
  668. #ifdef TCSETSW
  669. {"TCSETSW", TCSETSW},
  670. #endif
  671. #ifdef TCXONC
  672. {"TCXONC", TCXONC},
  673. #endif
  674. #ifdef TIOCCONS
  675. {"TIOCCONS", TIOCCONS},
  676. #endif
  677. #ifdef TIOCEXCL
  678. {"TIOCEXCL", TIOCEXCL},
  679. #endif
  680. #ifdef TIOCGETD
  681. {"TIOCGETD", TIOCGETD},
  682. #endif
  683. #ifdef TIOCGICOUNT
  684. {"TIOCGICOUNT", TIOCGICOUNT},
  685. #endif
  686. #ifdef TIOCGLCKTRMIOS
  687. {"TIOCGLCKTRMIOS", TIOCGLCKTRMIOS},
  688. #endif
  689. #ifdef TIOCGPGRP
  690. {"TIOCGPGRP", TIOCGPGRP},
  691. #endif
  692. #ifdef TIOCGSERIAL
  693. {"TIOCGSERIAL", TIOCGSERIAL},
  694. #endif
  695. #ifdef TIOCGSOFTCAR
  696. {"TIOCGSOFTCAR", TIOCGSOFTCAR},
  697. #endif
  698. #ifdef TIOCGWINSZ
  699. {"TIOCGWINSZ", TIOCGWINSZ},
  700. #endif
  701. #ifdef TIOCINQ
  702. {"TIOCINQ", TIOCINQ},
  703. #endif
  704. #ifdef TIOCLINUX
  705. {"TIOCLINUX", TIOCLINUX},
  706. #endif
  707. #ifdef TIOCMBIC
  708. {"TIOCMBIC", TIOCMBIC},
  709. #endif
  710. #ifdef TIOCMBIS
  711. {"TIOCMBIS", TIOCMBIS},
  712. #endif
  713. #ifdef TIOCMGET
  714. {"TIOCMGET", TIOCMGET},
  715. #endif
  716. #ifdef TIOCMIWAIT
  717. {"TIOCMIWAIT", TIOCMIWAIT},
  718. #endif
  719. #ifdef TIOCMSET
  720. {"TIOCMSET", TIOCMSET},
  721. #endif
  722. #ifdef TIOCM_CAR
  723. {"TIOCM_CAR", TIOCM_CAR},
  724. #endif
  725. #ifdef TIOCM_CD
  726. {"TIOCM_CD", TIOCM_CD},
  727. #endif
  728. #ifdef TIOCM_CTS
  729. {"TIOCM_CTS", TIOCM_CTS},
  730. #endif
  731. #ifdef TIOCM_DSR
  732. {"TIOCM_DSR", TIOCM_DSR},
  733. #endif
  734. #ifdef TIOCM_DTR
  735. {"TIOCM_DTR", TIOCM_DTR},
  736. #endif
  737. #ifdef TIOCM_LE
  738. {"TIOCM_LE", TIOCM_LE},
  739. #endif
  740. #ifdef TIOCM_RI
  741. {"TIOCM_RI", TIOCM_RI},
  742. #endif
  743. #ifdef TIOCM_RNG
  744. {"TIOCM_RNG", TIOCM_RNG},
  745. #endif
  746. #ifdef TIOCM_RTS
  747. {"TIOCM_RTS", TIOCM_RTS},
  748. #endif
  749. #ifdef TIOCM_SR
  750. {"TIOCM_SR", TIOCM_SR},
  751. #endif
  752. #ifdef TIOCM_ST
  753. {"TIOCM_ST", TIOCM_ST},
  754. #endif
  755. #ifdef TIOCNOTTY
  756. {"TIOCNOTTY", TIOCNOTTY},
  757. #endif
  758. #ifdef TIOCNXCL
  759. {"TIOCNXCL", TIOCNXCL},
  760. #endif
  761. #ifdef TIOCOUTQ
  762. {"TIOCOUTQ", TIOCOUTQ},
  763. #endif
  764. #ifdef TIOCPKT
  765. {"TIOCPKT", TIOCPKT},
  766. #endif
  767. #ifdef TIOCPKT_DATA
  768. {"TIOCPKT_DATA", TIOCPKT_DATA},
  769. #endif
  770. #ifdef TIOCPKT_DOSTOP
  771. {"TIOCPKT_DOSTOP", TIOCPKT_DOSTOP},
  772. #endif
  773. #ifdef TIOCPKT_FLUSHREAD
  774. {"TIOCPKT_FLUSHREAD", TIOCPKT_FLUSHREAD},
  775. #endif
  776. #ifdef TIOCPKT_FLUSHWRITE
  777. {"TIOCPKT_FLUSHWRITE", TIOCPKT_FLUSHWRITE},
  778. #endif
  779. #ifdef TIOCPKT_NOSTOP
  780. {"TIOCPKT_NOSTOP", TIOCPKT_NOSTOP},
  781. #endif
  782. #ifdef TIOCPKT_START
  783. {"TIOCPKT_START", TIOCPKT_START},
  784. #endif
  785. #ifdef TIOCPKT_STOP
  786. {"TIOCPKT_STOP", TIOCPKT_STOP},
  787. #endif
  788. #ifdef TIOCSCTTY
  789. {"TIOCSCTTY", TIOCSCTTY},
  790. #endif
  791. #ifdef TIOCSERCONFIG
  792. {"TIOCSERCONFIG", TIOCSERCONFIG},
  793. #endif
  794. #ifdef TIOCSERGETLSR
  795. {"TIOCSERGETLSR", TIOCSERGETLSR},
  796. #endif
  797. #ifdef TIOCSERGETMULTI
  798. {"TIOCSERGETMULTI", TIOCSERGETMULTI},
  799. #endif
  800. #ifdef TIOCSERGSTRUCT
  801. {"TIOCSERGSTRUCT", TIOCSERGSTRUCT},
  802. #endif
  803. #ifdef TIOCSERGWILD
  804. {"TIOCSERGWILD", TIOCSERGWILD},
  805. #endif
  806. #ifdef TIOCSERSETMULTI
  807. {"TIOCSERSETMULTI", TIOCSERSETMULTI},
  808. #endif
  809. #ifdef TIOCSERSWILD
  810. {"TIOCSERSWILD", TIOCSERSWILD},
  811. #endif
  812. #ifdef TIOCSER_TEMT
  813. {"TIOCSER_TEMT", TIOCSER_TEMT},
  814. #endif
  815. #ifdef TIOCSETD
  816. {"TIOCSETD", TIOCSETD},
  817. #endif
  818. #ifdef TIOCSLCKTRMIOS
  819. {"TIOCSLCKTRMIOS", TIOCSLCKTRMIOS},
  820. #endif
  821. #ifdef TIOCSPGRP
  822. {"TIOCSPGRP", TIOCSPGRP},
  823. #endif
  824. #ifdef TIOCSSERIAL
  825. {"TIOCSSERIAL", TIOCSSERIAL},
  826. #endif
  827. #ifdef TIOCSSOFTCAR
  828. {"TIOCSSOFTCAR", TIOCSSOFTCAR},
  829. #endif
  830. #ifdef TIOCSTI
  831. {"TIOCSTI", TIOCSTI},
  832. #endif
  833. #ifdef TIOCSWINSZ
  834. {"TIOCSWINSZ", TIOCSWINSZ},
  835. #endif
  836. #ifdef TIOCTTYGSTRUCT
  837. {"TIOCTTYGSTRUCT", TIOCTTYGSTRUCT},
  838. #endif
  839. /* sentinel */
  840. {NULL, 0}
  841. };
  842. PyMODINIT_FUNC
  843. PyInit_termios(void)
  844. {
  845. PyObject *m;
  846. struct constant *constant = termios_constants;
  847. m = Py_InitModule4("termios", termios_methods, termios__doc__,
  848. (PyObject *)NULL, PYTHON_API_VERSION);
  849. if (m == NULL)
  850. return;
  851. if (TermiosError == NULL) {
  852. TermiosError = PyErr_NewException("termios.error", NULL, NULL);
  853. }
  854. Py_INCREF(TermiosError);
  855. PyModule_AddObject(m, "error", TermiosError);
  856. while (constant->name != NULL) {
  857. PyModule_AddIntConstant(m, constant->name, constant->value);
  858. ++constant;
  859. }
  860. }