I have following code to get width and height of screen in Linux.
#ifdef TIOCGSIZE
struct ttysize ts;
ioctl(STDIN_FILENO, TIOCGSIZE, &ts);
cols = ts.ts_cols;
lines = ts.ts_lines;
#elif defined(TIOCGWINSZ)
struct winsize ts;
ioctl(STDIN_FILENO, TIOCGWINSZ, &ts);
cols = ts.ws_col;
lines = ts.ws_row;
#endif /* TIOCGSIZE */
What is difference between ttysize and winsize?
The ttysize
was the original implementation for SunOS 3.0 (February 1986), and soon after made obsolete by winsize
, which adds the size of the window in pixels. Here's
what the definitions look like in <sys/ttycom.h>
from SunOS 4:
/* * Window/terminal size structure. * This information is stored by the kernel * in order to provide a consistent interface, * but is not used by the kernel. * * Type must be "unsigned short" so that types.h not required. */ struct winsize { unsigned short ws_row; /* rows, in characters */ unsigned short ws_col; /* columns, in characters */ unsigned short ws_xpixel; /* horizontal size, pixels - not used */ unsigned short ws_ypixel; /* vertical size, pixels - not used */ }; #define TIOCGWINSZ _IOR(t, 104, struct winsize) /* get window size */ #define TIOCSWINSZ _IOW(t, 103, struct winsize) /* set window size */ /* * Sun version of same. */ struct ttysize { int ts_lines; /* number of lines on terminal */ int ts_cols; /* number of columns on terminal */ }; #define TIOCSSIZE _IOW(t,37,struct ttysize)/* set tty size */ #define TIOCGSIZE _IOR(t,38,struct ttysize)/* get tty size */
The data types are different (an integer would waste memory), and the fields have different names.
The ttysize
structure has long been obsolete: if either is provided by the system, winsize
is supported. That wasn't true when porting ncurses to SCO OpenServer in 1997, as noted in this chunk from lib_setup.c:
/* * SCO defines TIOCGSIZE and the corresponding struct. Other systems (SunOS, * Solaris, IRIX) define TIOCGWINSZ and struct winsize. */ #ifdef TIOCGSIZE # define IOCTL_WINSIZE TIOCGSIZE # define STRUCT_WINSIZE struct ttysize # define WINSIZE_ROWS(n) (int)n.ts_lines # define WINSIZE_COLS(n) (int)n.ts_cols #else # ifdef TIOCGWINSZ # define IOCTL_WINSIZE TIOCGWINSZ # define STRUCT_WINSIZE struct winsize # define WINSIZE_ROWS(n) (int)n.ws_row # define WINSIZE_COLS(n) (int)n.ws_col # endif #endif
You might notice that Linux is not mentioned in the comment. According to comments in asm-sparc64/ioctls.h, the ioctl for ttysize
was unsupported as of 2.6.16:
/* Note that all the ioctls that are not available in Linux have a * double underscore on the front to: a) avoid some programs to * think we support some ioctls under Linux (autoconfiguration stuff) */ ... #define TIOCCONS _IO('t', 36) #define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS Specific */ #define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS Specific */ #define TIOCGSOFTCAR _IOR('t', 100, int) #define TIOCSSOFTCAR _IOW('t', 101, int) #define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */ #define TIOCSWINSZ _IOW('t', 103, struct winsize) #define TIOCGWINSZ _IOR('t', 104, struct winsize)
A much earlier comment in 1995 added the definitions (without the double-underscore). Possibly a few programs used that with Linux, although winsize
was well established on most platforms before Linux was begun. A little more digging finds that the double-underscore was introduced in 1996 (patch-2.1.9 linux/include/asm-sparc/ioctls.h). Given that, very few programs would have used it with Linux.
Further reading: