using ioctl() to get window-size

Guy Harris guy at auspex.auspex.com
Wed Oct 3 07:00:20 AEST 1990


>I know that POSIX compliant systems (and some POSIX conforming hopefuls)
>have a TIOCGWINSZ mask for ioctl().

No, you don't.  Some POSIX-compliant systems have TIOCGWINSZ, but POSIX
doesn't require that a POSIX-compliant system have TIOCGWINSZ - or
"ioctl", for that matter.

>This works just fine and dandy. Is there some other way to get this
>info from ioctl other than via TIOCGWINSZ??  If so, how portable is
>it (AT&T only? BSD only? SunOS only? ...)?

Some systems have other "ioctl"s to do that, but it's less portable than
using TIOCGWINSZ.

TIOCGWINSZ is supported by 4.3BSD and later BSD systems, SunOS 4.0 and
later SunOS systems (I think I put it into 3.2 as well, but it's been a
while so I'm no longer certain), System V Release 4 (on pseudo-ttys
only, I think), and probably other systems.

The only other "ioctl" I know of (others may exist, I just haven't run
into them) is TIOCGSIZE in SunOS, and Sun dumped it in favor of
TIOCGWINSZ; it's still provided in 4.x for binary compatibility, but
it's not documented, and may not be supported in future releases.  I
don't know that anybody other than Sun provides it - as I said, less
portable.

According to the System V Release 4 manual page "curs_terminfo(3X)", if
the environment variables LINES and COLUMNS aren't set, and the program
is running in a window, the current window size is used; I think this
means that if the program is running in a pseudo-tty, TIOCGWINSZ is
used.  I.e., if the program calls "setupterm", the "terminfo" variables
"lines" and "columns" are set appropriately; if TIOCGWINSZ is supported,
it's used, otherwise the screen size is set from the "terminfo"
database.

Thus, programs using "curses" get the screen size from TIOCGWINSZ if
it's supported, and get it from the "terminfo" database if it's not,
automatically; programs that don't should use "setupterm" and the
"terminfo" variables "lines" and "columns", regardless of whether they
use "terminfo" for anything else or not, and as such get the size from
TIOCGWINSZ if it's supported, and from the "terminfo" database if it's
not.

>working source fragments would be great!

For System V "curses" (tested under SunOS 4.0.3 in the S5 environment,
i.e. compiled with "/usr/5bin/cc"; should work under S5R2 or later):

	#include <stdio.h>
	#include <curses.h>
	#include <term.h>

	int
	main(argc, argv)
		int argc;
		char **argv;
	{
		setupterm(0, 1, (int *)NULL);
		printf("%d lines, %d columns\n", lines, columns);
	}

For "termcap" - SunOS's "termcap" will get the "li" and "co"
capabilities from TIOCGWINSZ if it can, others may not, but if you
compile this code in the SunOS 4.0.3 S5 environment (and probably under
most but not all S5 systems with "curses"/"terminfo"), it works:

	#include <stdio.h>

	int
	main(argc, argv)
		int argc;
		char **argv;
	{
		extern char *getenv();
		char *term;
		int error;
		char ltcbuf[1024];
		int lines, columns;

		term = getenv("TERM");
		if (term == NULL)
			(void) fprintf(stderr, "TERM not set\n");
		else {
			error = tgetent(ltcbuf, term);
			if (error == -1)
				(void) fprintf(stderr,
				    "Cannot open termcap file\n");
			else if (error == 0)
				(void) fprintf(stderr,
				    "%s is an unknown terminal type\n", term);
			else {
				lines = tgetnum("li");
				columns = tgetnum("co");
				printf("%d lines, %d columns\n", lines,
				    columns);
			}
		}
	}



More information about the Comp.unix.questions mailing list