linuxterminalwidthsunos

Difference between structures ttysize and winsize?


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?


Solution

  • 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: