1 /* termiosmodule.c -- POSIX terminal I/O module implementation. */
5 #define PyInit_termios inittermios
9 #define BAD "bad termios argument"
11 static PyObject
*TermiosError
;
13 /* termios = tcgetattr(fd)
15 [iflag, oflag, cflag, lflag, ispeed, ospeed, [cc[0], ..., cc[NCCS]]]
17 Return the attributes of the terminal device. */
20 termios_tcgetattr(self
, args
)
27 speed_t ispeed
, ospeed
;
32 if (!PyArg_Parse(args
, "i", &fd
))
35 if (tcgetattr(fd
, &mode
) == -1)
36 PyErr_SetFromErrno(TermiosError
);
38 ispeed
= cfgetispeed(&mode
);
39 ospeed
= cfgetospeed(&mode
);
41 cc
= PyList_New(NCCS
);
44 for (i
= 0; i
< NCCS
; i
++) {
45 ch
= (char)mode
.c_cc
[i
];
46 v
= PyString_FromStringAndSize(&ch
, 1);
49 PyList_SetItem(cc
, i
, v
);
52 /* Convert the MIN and TIME slots to integer. On some systems, the
53 MIN and TIME slots are the same as the EOF and EOL slots. So we
54 only do this in noncanonical input mode. */
55 if (mode
.c_lflag
& ICANON
== 0) {
56 v
= PyInt_FromLong((long)mode
.c_cc
[VMIN
]);
59 PyList_SetItem(cc
, VMIN
, v
);
60 v
= PyInt_FromLong((long)mode
.c_cc
[VTIME
]);
63 PyList_SetItem(cc
, VTIME
, v
);
67 PyList_SetItem(v
, 0, PyInt_FromLong((long)mode
.c_iflag
));
68 PyList_SetItem(v
, 1, PyInt_FromLong((long)mode
.c_oflag
));
69 PyList_SetItem(v
, 2, PyInt_FromLong((long)mode
.c_cflag
));
70 PyList_SetItem(v
, 3, PyInt_FromLong((long)mode
.c_lflag
));
71 PyList_SetItem(v
, 4, PyInt_FromLong((long)ispeed
));
72 PyList_SetItem(v
, 5, PyInt_FromLong((long)ospeed
));
73 PyList_SetItem(v
, 6, cc
);
78 /* tcsetattr(fd, when, termios)
79 Set the attributes of the terminal device. */
82 termios_tcsetattr(self
, args
)
88 speed_t ispeed
, ospeed
;
89 PyObject
*term
, *cc
, *v
;
92 if (!PyArg_Parse(args
, "(iiO)", &fd
, &when
, &term
))
94 if (!PyList_Check(term
) || PyList_Size(term
) != 7) {
95 PyErr_SetString(PyExc_TypeError
, BAD
);
98 for (i
= 0; i
< 6; i
++)
99 if (!PyInt_Check(PyList_GetItem(term
, i
))) {
100 PyErr_SetString(PyExc_TypeError
, BAD
);
104 mode
.c_iflag
= (tcflag_t
) PyInt_AsLong(PyList_GetItem(term
, 0));
105 mode
.c_oflag
= (tcflag_t
) PyInt_AsLong(PyList_GetItem(term
, 1));
106 mode
.c_cflag
= (tcflag_t
) PyInt_AsLong(PyList_GetItem(term
, 2));
107 mode
.c_lflag
= (tcflag_t
) PyInt_AsLong(PyList_GetItem(term
, 3));
108 ispeed
= (speed_t
) PyInt_AsLong(PyList_GetItem(term
, 4));
109 ospeed
= (speed_t
) PyInt_AsLong(PyList_GetItem(term
, 5));
110 cc
= PyList_GetItem(term
, 6);
112 if (!PyList_Check(cc
) || PyList_Size(cc
) != NCCS
) {
113 PyErr_SetString(PyExc_TypeError
, BAD
);
117 for (i
= 0; i
< NCCS
; i
++) {
118 v
= PyList_GetItem(cc
, i
);
119 if (PyString_Check(v
) && PyString_Size(v
) == 1)
120 mode
.c_cc
[i
] = (cc_t
) * PyString_AsString(v
);
121 else if (PyInt_Check(v
))
122 mode
.c_cc
[i
] = (cc_t
) PyInt_AsLong(v
);
124 PyErr_SetString(PyExc_TypeError
, BAD
);
129 if (cfsetispeed(&mode
, (speed_t
) ispeed
) == -1)
130 PyErr_SetFromErrno(TermiosError
);
131 if (cfsetospeed(&mode
, (speed_t
) ospeed
) == -1)
132 PyErr_SetFromErrno(TermiosError
);
133 if (tcsetattr(fd
, when
, &mode
) == -1)
134 PyErr_SetFromErrno(TermiosError
);
140 /* tcsendbreak(fd, duration)
141 Generate a break condition. */
144 termios_tcsendbreak(self
, args
)
150 if (!PyArg_Parse(args
, "(ii)", &fd
, &duration
))
152 if (tcsendbreak(fd
, duration
) == -1)
153 PyErr_SetFromErrno(TermiosError
);
160 Wait until all queued output to the terminal has been
164 termios_tcdrain(self
, args
)
170 if (!PyArg_Parse(args
, "i", &fd
))
172 if (tcdrain(fd
) == -1)
173 PyErr_SetFromErrno(TermiosError
);
179 /* tcflush(fd, queue)
180 Clear the input and/or output queues associated with
184 termios_tcflush(self
, args
)
190 if (!PyArg_Parse(args
, "(ii)", &fd
, &queue
))
192 if (tcflush(fd
, queue
) == -1)
193 PyErr_SetFromErrno(TermiosError
);
199 /* tcflow(fd, action)
200 Perform operations relating to XON/XOFF flow control on
204 termios_tcflow(self
, args
)
210 if (!PyArg_Parse(args
, "(ii)", &fd
, &action
))
212 if (tcflow(fd
, action
) == -1)
213 PyErr_SetFromErrno(TermiosError
);
219 static PyMethodDef termios_methods
[] =
221 {"tcgetattr", termios_tcgetattr
},
222 {"tcsetattr", termios_tcsetattr
},
223 {"tcsendbreak", termios_tcsendbreak
},
224 {"tcdrain", termios_tcdrain
},
225 {"tcflush", termios_tcflush
},
226 {"tcflow", termios_tcflow
},
235 m
= Py_InitModule("termios", termios_methods
);
237 d
= PyModule_GetDict(m
);
238 TermiosError
= Py_BuildValue("s", "termios.error");
239 PyDict_SetItemString(d
, "error", TermiosError
);
241 if (PyErr_Occurred())
242 Py_FatalError("can't initialize module termios");