diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/clinic/termios.c.h | 66 | ||||
-rw-r--r-- | Modules/termios.c | 158 |
2 files changed, 223 insertions, 1 deletions
diff --git a/Modules/clinic/termios.c.h b/Modules/clinic/termios.c.h index a45c1f6..b4d179a 100644 --- a/Modules/clinic/termios.c.h +++ b/Modules/clinic/termios.c.h @@ -222,4 +222,68 @@ termios_tcflow(PyObject *module, PyObject *const *args, Py_ssize_t nargs) exit: return return_value; } -/*[clinic end generated code: output=a129179f1e2545cc input=a9049054013a1b77]*/ + +PyDoc_STRVAR(termios_tcgetwinsize__doc__, +"tcgetwinsize($module, fd, /)\n" +"--\n" +"\n" +"Get the tty winsize for file descriptor fd.\n" +"\n" +"Returns a tuple (ws_row, ws_col)."); + +#define TERMIOS_TCGETWINSIZE_METHODDEF \ + {"tcgetwinsize", (PyCFunction)termios_tcgetwinsize, METH_O, termios_tcgetwinsize__doc__}, + +static PyObject * +termios_tcgetwinsize_impl(PyObject *module, int fd); + +static PyObject * +termios_tcgetwinsize(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + int fd; + + if (!_PyLong_FileDescriptor_Converter(arg, &fd)) { + goto exit; + } + return_value = termios_tcgetwinsize_impl(module, fd); + +exit: + return return_value; +} + +PyDoc_STRVAR(termios_tcsetwinsize__doc__, +"tcsetwinsize($module, fd, winsize, /)\n" +"--\n" +"\n" +"Set the tty winsize for file descriptor fd.\n" +"\n" +"The winsize to be set is taken from the winsize argument, which\n" +"is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize()."); + +#define TERMIOS_TCSETWINSIZE_METHODDEF \ + {"tcsetwinsize", (PyCFunction)(void(*)(void))termios_tcsetwinsize, METH_FASTCALL, termios_tcsetwinsize__doc__}, + +static PyObject * +termios_tcsetwinsize_impl(PyObject *module, int fd, PyObject *winsz); + +static PyObject * +termios_tcsetwinsize(PyObject *module, PyObject *const *args, Py_ssize_t nargs) +{ + PyObject *return_value = NULL; + int fd; + PyObject *winsz; + + if (!_PyArg_CheckPositional("tcsetwinsize", nargs, 2, 2)) { + goto exit; + } + if (!_PyLong_FileDescriptor_Converter(args[0], &fd)) { + goto exit; + } + winsz = args[1]; + return_value = termios_tcsetwinsize_impl(module, fd, winsz); + +exit: + return return_value; +} +/*[clinic end generated code: output=db808d31296f6643 input=a9049054013a1b77]*/ 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 |