@@ -9,11 +9,16 @@ Version 2.45
Major new features:
- [Add new features here]
+* The functions tcgetwinsize and tcsetwinsize from POSIX.1-2024 have been
+ added to query and change the window size of a terminal. The struct
+ winsize type they operate on is now also defined by <termios.h>.
Deprecated and removed features, and other changes affecting compatibility:
- [Add deprecations, removals and changes affecting compatibility here]
+* <termios.h> now defines struct winsize and declares tcgetwinsize and
+ tcsetwinsize when _DEFAULT_SOURCE or _GNU_SOURCE is in effect, as the
+ BSDs and musl do. Programs which include <termios.h> without
+ <sys/ioctl.h> and define their own struct winsize need to be adjusted.
Changes to build and runtime requirements:
@@ -67,15 +67,7 @@ struct sgttyb
#if defined TIOCGWINSZ || defined TIOCSWINSZ
/* Type of ARG for TIOCGWINSZ and TIOCSWINSZ requests. */
-struct winsize
-{
- unsigned short int ws_row; /* Rows, in characters. */
- unsigned short int ws_col; /* Columns, in characters. */
-
- /* These are not actually used. */
- unsigned short int ws_xpixel; /* Horizontal pixels. */
- unsigned short int ws_ypixel; /* Vertical pixels. */
-};
+# include <bits/types/struct_winsize.h>
# define _IOT_winsize /* Hurd ioctl type field. */ \
_IOT (_IOTS (unsigned short int), 4, 0, 0, 0, 0)
@@ -9,6 +9,13 @@ type {struct termios}
type pid_t
#endif
+#if defined XOPEN2K24 || defined POSIX2024
+type {struct winsize}
+
+element {struct winsize} {unsigned short int} ws_row
+element {struct winsize} {unsigned short int} ws_col
+#endif
+
element {struct termios} tcflag_t c_iflag
element {struct termios} tcflag_t c_oflag
element {struct termios} tcflag_t c_cflag
@@ -147,6 +154,10 @@ function int tcgetattr (int, struct termios*)
#if !defined POSIX && !defined XPG4
function pid_t tcgetsid (int)
#endif
+#if defined XOPEN2K24 || defined POSIX2024
+function int tcgetwinsize (int, struct winsize*)
+function int tcsetwinsize (int, const struct winsize*)
+#endif
function int tcsendbreak (int, int)
function int tcsetattr (int, int, const struct termios*)
new file mode 100644
@@ -0,0 +1 @@
+#include <termios/bits/types/struct_winsize.h>
@@ -24,6 +24,8 @@ descriptor is and how to open a file descriptor for a terminal device.
* BSD Terminal Modes:: BSD compatible terminal mode setting
* Line Control:: Sending break sequences, clearing
terminal buffers @dots{}
+* Window Size:: Querying and setting the size of a
+ terminal window.
* Noncanon Example:: How to read single characters without echo.
* getpass:: Prompting the user for a passphrase.
* Pseudo-Terminals:: How to open a pseudo-terminal.
@@ -2134,6 +2136,78 @@ A bad value was supplied as the @var{action} argument.
@end table
@end deftypefun
+@node Window Size
+@section Window Size
+@cindex terminal window size
+@cindex window size of a terminal
+
+These functions query and change the size of the window associated with a
+terminal device. They are declared in the header file @file{termios.h}.
+@pindex termios.h
+
+@deftp {Data Type} {struct winsize}
+@standards{POSIX.1-2024, termios.h}
+This structure describes the size of a terminal window. It contains at
+least the following members:
+
+@table @code
+@item unsigned short int ws_row
+The number of rows, in characters.
+
+@item unsigned short int ws_col
+The number of columns, in characters.
+
+@item unsigned short int ws_xpixel
+The width of the window, in pixels. Many terminals report this as
+@math{0}.
+
+@item unsigned short int ws_ypixel
+The height of the window, in pixels. Many terminals report this as
+@math{0}.
+@end table
+@end deftp
+
+@deftypefun int tcgetwinsize (int @var{filedes}, struct winsize *@var{winsize-p})
+@standards{POSIX.1-2024, termios.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+This function stores the current window size of the terminal device with
+file descriptor @var{filedes} in the structure that @var{winsize-p}
+points to.
+
+If successful, @code{tcgetwinsize} returns @math{0}. A return value of
+@math{-1} indicates an error. The following @code{errno} error
+conditions are defined for this function:
+
+@table @code
+@item EBADF
+The @var{filedes} argument is not a valid file descriptor.
+
+@item ENOTTY
+The @var{filedes} is not associated with a terminal.
+@end table
+@end deftypefun
+
+@deftypefun int tcsetwinsize (int @var{filedes}, const struct winsize *@var{winsize-p})
+@standards{POSIX.1-2024, termios.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+This function sets the window size of the terminal device with file
+descriptor @var{filedes} from the structure that @var{winsize-p} points
+to. If the size changes, the foreground process group of the terminal
+is sent a @code{SIGWINCH} signal. @xref{Miscellaneous Signals}.
+
+If successful, @code{tcsetwinsize} returns @math{0}. A return value of
+@math{-1} indicates an error. The following @code{errno} error
+conditions are defined for this function:
+
+@table @code
+@item EBADF
+The @var{filedes} argument is not a valid file descriptor.
+
+@item ENOTTY
+The @var{filedes} is not associated with a terminal.
+@end table
+@end deftypefun
+
@node Noncanon Example
@section Noncanonical Mode Example
@@ -1 +1,3 @@
GLIBC_2.36 pidfd_getfd F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2835,6 +2835,8 @@ GLIBC_2.44 timer_delete F
GLIBC_2.44 timer_getoverrun F
GLIBC_2.44 timer_gettime F
GLIBC_2.44 timer_settime F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2511,6 +2511,8 @@ GLIBC_2.44 timer_delete F
GLIBC_2.44 timer_getoverrun F
GLIBC_2.44 timer_gettime F
GLIBC_2.44 timer_settime F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
HURD_CTHREADS_0.3 __mutex_init F
HURD_CTHREADS_0.3 __mutex_lock F
HURD_CTHREADS_0.3 __mutex_trylock F
@@ -2775,3 +2775,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -3122,6 +3122,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2536,3 +2536,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2828,6 +2828,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2825,6 +2825,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -24,13 +24,7 @@
#include <asm/ioctls.h>
-struct winsize
- {
- unsigned short int ws_row;
- unsigned short int ws_col;
- unsigned short int ws_xpixel;
- unsigned short int ws_ypixel;
- };
+#include <bits/types/struct_winsize.h>
/* modem lines */
#define TIOCM_LE 0x001
@@ -2812,3 +2812,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2849,6 +2849,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -3032,6 +3032,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2287,3 +2287,5 @@ GLIBC_2.44 wprintf F
GLIBC_2.44 write F
GLIBC_2.44 writev F
GLIBC_2.44 wscanf F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2296,3 +2296,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2808,6 +2808,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2975,6 +2975,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2861,3 +2861,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2858,3 +2858,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -23,13 +23,7 @@
/* Get definition of constants for use with `ioctl'. */
#include <asm/ioctls.h>
-struct winsize
- {
- unsigned short int ws_row;
- unsigned short int ws_col;
- unsigned short int ws_xpixel;
- unsigned short int ws_ypixel;
- };
+#include <bits/types/struct_winsize.h>
/* modem lines */
#define TIOCM_LE 0x001 /* line enable */
@@ -2938,6 +2938,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2936,6 +2936,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2944,6 +2944,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2846,6 +2846,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2286,3 +2286,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -24,13 +24,7 @@
#include <asm/ioctls.h>
-struct winsize
- {
- unsigned short int ws_row;
- unsigned short int ws_col;
- unsigned short int ws_xpixel;
- unsigned short int ws_ypixel;
- };
+#include <bits/types/struct_winsize.h>
/* modem lines */
#define TIOCM_LE 0x001
@@ -3165,6 +3165,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -3210,6 +3210,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2919,6 +2919,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2995,3 +2995,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2539,3 +2539,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2739,3 +2739,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
@@ -2956,6 +2956,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2855,6 +2855,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2852,6 +2852,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -3186,6 +3186,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2822,6 +2822,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2771,6 +2771,8 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.5 inet6_opt_find F
@@ -2790,3 +2790,5 @@ GLIBC_2.43 memset_explicit F
GLIBC_2.43 mseal F
GLIBC_2.43 openat2 F
GLIBC_2.43 umaxabs F
+GLIBC_2.45 tcgetwinsize F
+GLIBC_2.45 tcsetwinsize F
new file mode 100644
@@ -0,0 +1,27 @@
+/* Get the size of a terminal window. Unix version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/ioctl.h>
+#include <termios.h>
+
+/* Store the window size of the terminal FD in *WINP. */
+int
+tcgetwinsize (int fd, struct winsize *winp)
+{
+ return __ioctl (fd, TIOCGWINSZ, winp);
+}
new file mode 100644
@@ -0,0 +1,27 @@
+/* Set the size of a terminal window. Unix version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <sys/ioctl.h>
+#include <termios.h>
+
+/* Set the window size of the terminal FD from *WINP. */
+int
+tcsetwinsize (int fd, const struct winsize *winp)
+{
+ return __ioctl (fd, TIOCSWINSZ, winp);
+}
@@ -25,6 +25,7 @@ include ../Makeconfig
headers := \
bits/termios-baud.h \
bits/termios.h \
+ bits/types/struct_winsize.h \
sys/termios.h \
sys/ttychars.h \
sys/ttydefaults.h \
@@ -45,11 +46,21 @@ routines := \
tcgetattr \
tcgetpgrp \
tcgetsid \
+ tcgetwinsize \
tcsendbrk \
tcsetattr \
tcsetpgrp \
+ tcsetwinsize \
# routines
+tests := \
+ tst-tcwinsize \
+ tst-winsize \
+ tst-winsize-ioctl \
+ tst-winsize-posix2024 \
+ tst-winsize-xopen2024 \
+ # tests
+
include ../Rules
CFLAGS-tcdrain.c += -fexceptions -fasynchronous-unwind-tables
@@ -18,4 +18,8 @@ libc {
# cf*baud
cfgetibaud; cfgetobaud; cfsetibaud; cfsetobaud; cfsetbaud;
}
+ GLIBC_2.45 {
+ # t*
+ tcgetwinsize; tcsetwinsize;
+ }
}
new file mode 100644
@@ -0,0 +1,31 @@
+/* Define struct winsize.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef __winsize_defined
+#define __winsize_defined 1
+
+/* Size of a terminal window. */
+struct winsize
+ {
+ unsigned short int ws_row; /* Rows, in characters. */
+ unsigned short int ws_col; /* Columns, in characters. */
+ unsigned short int ws_xpixel; /* Horizontal pixels. */
+ unsigned short int ws_ypixel; /* Vertical pixels. */
+ };
+
+#endif
new file mode 100644
@@ -0,0 +1,35 @@
+/* Get the size of a terminal window. Generic version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <termios.h>
+
+/* Store the window size of the terminal FD in *WINP. */
+int
+tcgetwinsize (int fd, struct winsize *winp)
+{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
+ __set_errno (ENOSYS);
+ return -1;
+}
+stub_warning (tcgetwinsize)
new file mode 100644
@@ -0,0 +1,35 @@
+/* Set the size of a terminal window. Generic version.
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <termios.h>
+
+/* Set the window size of the terminal FD from *WINP. */
+int
+tcsetwinsize (int fd, const struct winsize *winp)
+{
+ if (fd < 0)
+ {
+ __set_errno (EBADF);
+ return -1;
+ }
+
+ __set_errno (ENOSYS);
+ return -1;
+}
+stub_warning (tcsetwinsize)
@@ -38,6 +38,11 @@ __BEGIN_DECLS
`cc_t', `speed_t', and all the macros specifying the flag bits. */
#include <bits/termios.h>
+#if defined __USE_MISC || defined __USE_XOPEN2K24
+/* Get the definition of `struct winsize'. */
+# include <bits/types/struct_winsize.h>
+#endif
+
#ifdef __USE_MISC
/* Compare a character C to a value VAL from the `c_cc' array in a
`struct termios'. If VAL is _POSIX_VDISABLE, no character can match it. */
@@ -119,6 +124,14 @@ extern int tcflow (int __fd, int __action) __THROW;
extern __pid_t tcgetsid (int __fd) __THROW;
#endif
+#if defined __USE_MISC || defined __USE_XOPEN2K24
+/* Store the window size of the terminal FD in *WINP. */
+extern int tcgetwinsize (int __fd, struct winsize *__winp) __THROW;
+
+/* Set the window size of the terminal FD from *WINP. */
+extern int tcsetwinsize (int __fd, const struct winsize *__winp) __THROW;
+#endif
+
#ifdef __USE_MISC
# include <sys/ttydefaults.h>
new file mode 100644
@@ -0,0 +1,86 @@
+/* Check tcgetwinsize and tcsetwinsize on a pseudo-terminal (bug 32074).
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+/* <termios.h> comes first so that this test also covers including
+ <sys/ioctl.h> after it; tst-winsize-ioctl.c covers the other order. */
+#include <termios.h>
+#include <sys/ioctl.h>
+
+#include <errno.h>
+#include <string.h>
+#include <support/check.h>
+#include <support/tty.h>
+#include <support/xunistd.h>
+
+static int
+do_test (void)
+{
+ struct winsize initial = { .ws_row = 24, .ws_col = 80 };
+ int outer, inner;
+ support_openpty (&outer, &inner, NULL, NULL, &initial);
+
+ struct winsize ws;
+ memset (&ws, 0xff, sizeof ws);
+ TEST_COMPARE (tcgetwinsize (inner, &ws), 0);
+ TEST_COMPARE (ws.ws_row, 24);
+ TEST_COMPARE (ws.ws_col, 80);
+
+ struct winsize updated
+ = { .ws_row = 50, .ws_col = 132, .ws_xpixel = 640, .ws_ypixel = 480 };
+ TEST_COMPARE (tcsetwinsize (inner, &updated), 0);
+
+ /* The new size must be visible through the ioctl interface and
+ through the other end of the pseudo-terminal. */
+ memset (&ws, 0, sizeof ws);
+ TEST_COMPARE (ioctl (inner, TIOCGWINSZ, &ws), 0);
+ TEST_COMPARE (ws.ws_row, 50);
+ TEST_COMPARE (ws.ws_col, 132);
+ TEST_COMPARE (ws.ws_xpixel, 640);
+ TEST_COMPARE (ws.ws_ypixel, 480);
+
+ memset (&ws, 0, sizeof ws);
+ TEST_COMPARE (tcgetwinsize (outer, &ws), 0);
+ TEST_COMPARE (ws.ws_row, 50);
+ TEST_COMPARE (ws.ws_col, 132);
+
+ /* A descriptor which is not a terminal. */
+ int fds[2];
+ xpipe (fds);
+ errno = 0;
+ TEST_COMPARE (tcgetwinsize (fds[0], &ws), -1);
+ TEST_COMPARE (errno, ENOTTY);
+ errno = 0;
+ TEST_COMPARE (tcsetwinsize (fds[0], &updated), -1);
+ TEST_COMPARE (errno, ENOTTY);
+
+ /* An invalid descriptor. */
+ errno = 0;
+ TEST_COMPARE (tcgetwinsize (-1, &ws), -1);
+ TEST_COMPARE (errno, EBADF);
+ errno = 0;
+ TEST_COMPARE (tcsetwinsize (-1, &updated), -1);
+ TEST_COMPARE (errno, EBADF);
+
+ xclose (fds[0]);
+ xclose (fds[1]);
+ xclose (inner);
+ xclose (outer);
+ return 0;
+}
+
+#include <support/test-driver.c>
new file mode 100644
@@ -0,0 +1,6 @@
+/* Process tst-winsize-main.c in the default mode, with <sys/ioctl.h>
+ included first to check that both headers can be combined in this
+ order; tst-tcwinsize.c covers the other order. */
+#include <sys/ioctl.h>
+
+#include "tst-winsize-main.c"
new file mode 100644
@@ -0,0 +1,34 @@
+/* Check that <termios.h> defines struct winsize (bug 32074).
+ Copyright (C) 2026 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <termios.h>
+
+/* This fails to compile if <termios.h> leaves struct winsize
+ incomplete. */
+static struct winsize ws;
+
+static int
+do_test (void)
+{
+ ws.ws_row = 24;
+ ws.ws_col = 80;
+
+ return ws.ws_row != 24 || ws.ws_col != 80;
+}
+
+#include <support/test-driver.c>
new file mode 100644
@@ -0,0 +1,5 @@
+/* Process tst-winsize-main.c in POSIX.1-2024 mode. */
+#undef _GNU_SOURCE
+#define _POSIX_C_SOURCE 202405L
+
+#include "tst-winsize-main.c"
new file mode 100644
@@ -0,0 +1,5 @@
+/* Process tst-winsize-main.c in X/Open Issue 8 mode. */
+#undef _GNU_SOURCE
+#define _XOPEN_SOURCE 800
+
+#include "tst-winsize-main.c"
new file mode 100644
@@ -0,0 +1,3 @@
+/* Process tst-winsize-main.c in the default mode with <termios.h>
+ alone. */
+#include "tst-winsize-main.c"