@@ -315,6 +315,156 @@ termios_tcflow_impl(PyObject *module, int fd, int action)
315315 Py_RETURN_NONE ;
316316}
317317
318+ /*[clinic input]
319+ termios.tcgetwinsize
320+
321+ fd: fildes
322+ /
323+
324+ Get the tty winsize for file descriptor fd.
325+
326+ Returns a tuple (ws_row, ws_col).
327+ [clinic start generated code]*/
328+
329+ static PyObject *
330+ termios_tcgetwinsize_impl (PyObject * module , int fd )
331+ /*[clinic end generated code: output=31825977d5325fb6 input=5706c379d7fd984d]*/
332+ {
333+ #if defined(TIOCGWINSZ )
334+ termiosmodulestate * state = PyModule_GetState (module );
335+ struct winsize w ;
336+ if (ioctl (fd , TIOCGWINSZ , & w ) == -1 ) {
337+ return PyErr_SetFromErrno (state -> TermiosError );
338+ }
339+
340+ PyObject * v ;
341+ if (!(v = PyTuple_New (2 ))) {
342+ return NULL ;
343+ }
344+
345+ PyTuple_SetItem (v , 0 , PyLong_FromLong ((long )w .ws_row ));
346+ PyTuple_SetItem (v , 1 , PyLong_FromLong ((long )w .ws_col ));
347+ if (PyErr_Occurred ()) {
348+ Py_DECREF (v );
349+ return NULL ;
350+ }
351+ return v ;
352+ #elif defined(TIOCGSIZE )
353+ termiosmodulestate * state = PyModule_GetState (module );
354+ struct ttysize s ;
355+ if (ioctl (fd , TIOCGSIZE , & s ) == -1 ) {
356+ return PyErr_SetFromErrno (state -> TermiosError );
357+ }
358+
359+ PyObject * v ;
360+ if (!(v = PyTuple_New (2 ))) {
361+ return NULL ;
362+ }
363+
364+ PyTuple_SetItem (v , 0 , PyLong_FromLong ((long )s .ts_lines ));
365+ PyTuple_SetItem (v , 1 , PyLong_FromLong ((long )s .ts_cols ));
366+ if (PyErr_Occurred ()) {
367+ Py_DECREF (v );
368+ return NULL ;
369+ }
370+ return v ;
371+ #else
372+ PyErr_SetString (PyExc_NotImplementedError ,
373+ "requires termios.TIOCGWINSZ and/or termios.TIOCGSIZE" );
374+ return NULL ;
375+ #endif /* defined(TIOCGWINSZ) */
376+ }
377+
378+ /*[clinic input]
379+ termios.tcsetwinsize
380+
381+ fd: fildes
382+ winsize as winsz: object
383+ /
384+
385+ Set the tty winsize for file descriptor fd.
386+
387+ The winsize to be set is taken from the winsize argument, which
388+ is a two-item tuple (ws_row, ws_col) like the one returned by tcgetwinsize().
389+ [clinic start generated code]*/
390+
391+ static PyObject *
392+ termios_tcsetwinsize_impl (PyObject * module , int fd , PyObject * winsz )
393+ /*[clinic end generated code: output=2ac3c9bb6eda83e1 input=4a06424465b24aee]*/
394+ {
395+ if (!PySequence_Check (winsz ) || PySequence_Size (winsz ) != 2 ) {
396+ PyErr_SetString (PyExc_TypeError ,
397+ "tcsetwinsize, arg 2: must be a two-item sequence" );
398+ return NULL ;
399+ }
400+
401+ PyObject * tmp_item ;
402+ long winsz_0 , winsz_1 ;
403+ tmp_item = PySequence_GetItem (winsz , 0 );
404+ winsz_0 = PyLong_AsLong (tmp_item );
405+ if (winsz_0 == -1 && PyErr_Occurred ()) {
406+ Py_XDECREF (tmp_item );
407+ return NULL ;
408+ }
409+ Py_XDECREF (tmp_item );
410+ tmp_item = PySequence_GetItem (winsz , 1 );
411+ winsz_1 = PyLong_AsLong (tmp_item );
412+ if (winsz_1 == -1 && PyErr_Occurred ()) {
413+ Py_XDECREF (tmp_item );
414+ return NULL ;
415+ }
416+ Py_XDECREF (tmp_item );
417+
418+ termiosmodulestate * state = PyModule_GetState (module );
419+
420+ #if defined(TIOCGWINSZ ) && defined(TIOCSWINSZ )
421+ struct winsize w ;
422+ /* Get the old winsize because it might have
423+ more fields such as xpixel, ypixel. */
424+ if (ioctl (fd , TIOCGWINSZ , & w ) == -1 ) {
425+ return PyErr_SetFromErrno (state -> TermiosError );
426+ }
427+
428+ w .ws_row = (unsigned short ) winsz_0 ;
429+ w .ws_col = (unsigned short ) winsz_1 ;
430+ if ((((long )w .ws_row ) != winsz_0 ) || (((long )w .ws_col ) != winsz_1 )) {
431+ PyErr_SetString (PyExc_OverflowError ,
432+ "winsize value(s) out of range." );
433+ return NULL ;
434+ }
435+
436+ if (ioctl (fd , TIOCSWINSZ , & w ) == -1 ) {
437+ return PyErr_SetFromErrno (state -> TermiosError );
438+ }
439+
440+ Py_RETURN_NONE ;
441+ #elif defined(TIOCGSIZE ) && defined(TIOCSSIZE )
442+ struct ttysize s ;
443+ /* Get the old ttysize because it might have more fields. */
444+ if (ioctl (fd , TIOCGSIZE , & s ) == -1 ) {
445+ return PyErr_SetFromErrno (state -> TermiosError );
446+ }
447+
448+ s .ts_lines = (int ) winsz_0 ;
449+ s .ts_cols = (int ) winsz_1 ;
450+ if ((((long )s .ts_lines ) != winsz_0 ) || (((long )s .ts_cols ) != winsz_1 )) {
451+ PyErr_SetString (PyExc_OverflowError ,
452+ "winsize value(s) out of range." );
453+ return NULL ;
454+ }
455+
456+ if (ioctl (fd , TIOCSSIZE , & s ) == -1 ) {
457+ return PyErr_SetFromErrno (state -> TermiosError );
458+ }
459+
460+ Py_RETURN_NONE ;
461+ #else
462+ PyErr_SetString (PyExc_NotImplementedError ,
463+ "requires termios.TIOCGWINSZ, termios.TIOCSWINSZ and/or termios.TIOCGSIZE, termios.TIOCSSIZE" );
464+ return NULL ;
465+ #endif /* defined(TIOCGWINSZ) && defined(TIOCSWINSZ) */
466+ }
467+
318468static PyMethodDef termios_methods [] =
319469{
320470 TERMIOS_TCGETATTR_METHODDEF
@@ -323,6 +473,8 @@ static PyMethodDef termios_methods[] =
323473 TERMIOS_TCDRAIN_METHODDEF
324474 TERMIOS_TCFLUSH_METHODDEF
325475 TERMIOS_TCFLOW_METHODDEF
476+ TERMIOS_TCGETWINSIZE_METHODDEF
477+ TERMIOS_TCSETWINSIZE_METHODDEF
326478 {NULL , NULL }
327479};
328480
@@ -841,6 +993,9 @@ static struct constant {
841993#ifdef TIOCGSERIAL
842994 {"TIOCGSERIAL" , TIOCGSERIAL },
843995#endif
996+ #ifdef TIOCGSIZE
997+ {"TIOCGSIZE" , TIOCGSIZE },
998+ #endif
844999#ifdef TIOCGSOFTCAR
8451000 {"TIOCGSOFTCAR" , TIOCGSOFTCAR },
8461001#endif
@@ -973,6 +1128,9 @@ static struct constant {
9731128#ifdef TIOCSSERIAL
9741129 {"TIOCSSERIAL" , TIOCSSERIAL },
9751130#endif
1131+ #ifdef TIOCSSIZE
1132+ {"TIOCSSIZE" , TIOCSSIZE },
1133+ #endif
9761134#ifdef TIOCSSOFTCAR
9771135 {"TIOCSSOFTCAR" , TIOCSSOFTCAR },
9781136#endif
0 commit comments