summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/clinic/termios.c.h66
-rw-r--r--Modules/termios.c158
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