diff options
Diffstat (limited to 'Modules/termios.c')
-rw-r--r-- | Modules/termios.c | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/Modules/termios.c b/Modules/termios.c index fdfe589..38573e2 100644 --- a/Modules/termios.c +++ b/Modules/termios.c @@ -315,6 +315,156 @@ termios_tcflow_impl(PyObject *module, int fd, int action) Py_RETURN_NONE; } +/*[clinic input] +termios.tcgetwinsize + + fd: fildes + / + +Get the tty winsize for file descriptor fd. + +Returns a tuple (ws_row, ws_col). +[clinic start generated code]*/ + +static PyObject * +termios_tcgetwinsize_impl(PyObject *module, int fd) +/*[clinic end generated code: output=31825977d5325fb6 input=5706c379d7fd984d]*/ +{ +#if defined(TIOCGWINSZ) + termiosmodulestate *state = PyModule_GetState(module); + struct winsize w; + if (ioctl(fd, TIOCGWINSZ, &w) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } + + PyObject *v; + if (!(v = PyTuple_New(2))) { + return NULL; + } + + PyTuple_SetItem(v, 0, PyLong_FromLong((long)w.ws_row)); + PyTuple_SetItem(v, 1, PyLong_FromLong((long)w.ws_col)); + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + return v; +#elif defined(TIOCGSIZE) + termiosmodulestate *state = PyModule_GetState(module); + struct ttysize s; + if (ioctl(fd, TIOCGSIZE, &s) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } + + PyObject *v; + if (!(v = PyTuple_New(2))) { + return NULL; + } + + PyTuple_SetItem(v, 0, PyLong_FromLong((long)s.ts_lines)); + PyTuple_SetItem(v, 1, PyLong_FromLong((long)s.ts_cols)); + if (PyErr_Occurred()) { + Py_DECREF(v); + return NULL; + } + return v; +#else + PyErr_SetString(PyExc_NotImplementedError, + "requires termios.TIOCGWINSZ and/or termios.TIOCGSIZE"); + return NULL; +#endif /* defined(TIOCGWINSZ) */ +} + +/*[clinic input] +termios.tcsetwinsize + + fd: fildes + winsize as winsz: object + / + +Set the tty winsize for file descriptor fd. + +The winsize to be set is taken from the winsize argument, which +is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize(). +[clinic start generated code]*/ + +static PyObject * +termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz) +/*[clinic end generated code: output=2ac3c9bb6eda83e1 input=4a06424465b24aee]*/ +{ + if (!PySequence_Check(winsz) || PySequence_Size(winsz) != 2) { + PyErr_SetString(PyExc_TypeError, + "tcsetwinsize, arg 2: must be a two-item sequence"); + return NULL; + } + + PyObject *tmp_item; + long winsz_0, winsz_1; + tmp_item = PySequence_GetItem(winsz, 0); + winsz_0 = PyLong_AsLong(tmp_item); + if (winsz_0 == -1 && PyErr_Occurred()) { + Py_XDECREF(tmp_item); + return NULL; + } + Py_XDECREF(tmp_item); + tmp_item = PySequence_GetItem(winsz, 1); + winsz_1 = PyLong_AsLong(tmp_item); + if (winsz_1 == -1 && PyErr_Occurred()) { + Py_XDECREF(tmp_item); + return NULL; + } + Py_XDECREF(tmp_item); + + termiosmodulestate *state = PyModule_GetState(module); + +#if defined(TIOCGWINSZ) && defined(TIOCSWINSZ) + struct winsize w; + /* Get the old winsize because it might have + more fields such as xpixel, ypixel. */ + if (ioctl(fd, TIOCGWINSZ, &w) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } + + w.ws_row = (unsigned short) winsz_0; + w.ws_col = (unsigned short) winsz_1; + if ((((long)w.ws_row) != winsz_0) || (((long)w.ws_col) != winsz_1)) { + PyErr_SetString(PyExc_OverflowError, + "winsize value(s) out of range."); + return NULL; + } + + if (ioctl(fd, TIOCSWINSZ, &w) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } + + Py_RETURN_NONE; +#elif defined(TIOCGSIZE) && defined(TIOCSSIZE) + struct ttysize s; + /* Get the old ttysize because it might have more fields. */ + if (ioctl(fd, TIOCGSIZE, &s) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } + + s.ts_lines = (int) winsz_0; + s.ts_cols = (int) winsz_1; + if ((((long)s.ts_lines) != winsz_0) || (((long)s.ts_cols) != winsz_1)) { + PyErr_SetString(PyExc_OverflowError, + "winsize value(s) out of range."); + return NULL; + } + + if (ioctl(fd, TIOCSSIZE, &s) == -1) { + return PyErr_SetFromErrno(state->TermiosError); + } + + Py_RETURN_NONE; +#else + PyErr_SetString(PyExc_NotImplementedError, + "requires termios.TIOCGWINSZ, termios.TIOCSWINSZ and/or termios.TIOCGSIZE, termios.TIOCSSIZE"); + return NULL; +#endif /* defined(TIOCGWINSZ) && defined(TIOCSWINSZ) */ +} + static PyMethodDef termios_methods[] = { TERMIOS_TCGETATTR_METHODDEF @@ -323,6 +473,8 @@ static PyMethodDef termios_methods[] = TERMIOS_TCDRAIN_METHODDEF TERMIOS_TCFLUSH_METHODDEF TERMIOS_TCFLOW_METHODDEF + TERMIOS_TCGETWINSIZE_METHODDEF + TERMIOS_TCSETWINSIZE_METHODDEF {NULL, NULL} }; @@ -841,6 +993,9 @@ static struct constant { #ifdef TIOCGSERIAL {"TIOCGSERIAL", TIOCGSERIAL}, #endif +#ifdef TIOCGSIZE + {"TIOCGSIZE", TIOCGSIZE}, +#endif #ifdef TIOCGSOFTCAR {"TIOCGSOFTCAR", TIOCGSOFTCAR}, #endif @@ -973,6 +1128,9 @@ static struct constant { #ifdef TIOCSSERIAL {"TIOCSSERIAL", TIOCSSERIAL}, #endif +#ifdef TIOCSSIZE + {"TIOCSSIZE", TIOCSSIZE}, +#endif #ifdef TIOCSSOFTCAR {"TIOCSSOFTCAR", TIOCSSOFTCAR}, #endif |