[comp.unix.questions] using ioctl

brad@SSD.CSD.HARRIS.COM (Brad Appleton) (10/02/90)

I have a program that wants to get the current window size of the terminal
(the number of rows and columns).  I would like to do this using ioctl().
I know that POSIX compliant systems (and some POSIX conforming hopefuls)
have a TIOCGWINSZ mask for ioctl(). 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? ...)?

working source fragments would be great!

advTHANXance
______________________ "And miles to go before I sleep." ______________________
 Brad Appleton        brad@travis.ssd.csd.harris.com   Harris Computer Systems
                          ...!uunet!hcx1!brad          Fort Lauderdale, FL USA
~~~~~~~~~~~~~~~~~~~~ Disclaimer: I said it, not my company! ~~~~~~~~~~~~~~~~~~~

guy@auspex.auspex.com (Guy Harris) (10/03/90)

>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);
			}
		}
	}

decot@hpisod2.HP.COM (Dave Decot) (10/03/90)

> I have a program that wants to get the current window size of the terminal
> (the number of rows and columns).  I would like to do this using ioctl().
> I know that POSIX compliant systems (and some POSIX conforming hopefuls)
> have a TIOCGWINSZ mask for ioctl(). This works just fine and dandy. Is

POSIX compliant systems need not even have a function called ioctl(),
much less any TIOCGWINSZ functionality available through it.

> 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? ...)?

For those systems that have this capability, that's about the most common
way to do it.  It appears to be mostly on systems derived from SunOS
(such as System VR3).

Dave Decot

gwyn@smoke.BRL.MIL (Doug Gwyn) (10/04/90)

In article <10650105@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes:
>> 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? ...)?
>For those systems that have this capability, that's about the most common
>way to do it.  It appears to be mostly on systems derived from SunOS
>(such as System VR3).

Actually, TIOCGWINSZ first appeared under that name on some intermediate
release of 4.2BSD.  SunOS had introduced a very similar ioctl with a slightly
different name, and Berkeley did their usual reengineering act on it.  AT&T
around 1984 had come up with a similar JWINSIZE ioctl to support "layers"
(xt protocol, as used in Blit, 5620, 630, etc. terminals).  AT&T's was
different in one significant way: the size originally could not be set
from user mode; the xt pseudo-device driver took care of setting the size.
(This has since changed somewhat.)

Notice the historical lack of communication among UNIX developers all
working on similar facilities.  Shame, shame.