[net.unix-wizards] Mysterious transformation of tset

earle@smeagol.UUCP (Greg_Earle) (10/10/85)

I have a question for the Sun gurus.  When inside the window system,
executing "tset -QS" directly from the shell gives output that
'knows' about the size (lines, columns) of the current window: 
e.g.

 % tset -QS; echo
sun Mu|sun:li#50:co#76:cl=^L:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:am:bs:km:mi:ms:
(etc.)
rs=\E[s: % 

(line broken up for readability).  Note the entries for li and co.
But lo and behold; if you should try to do anything with this output, like
put it between `` for use with eval, or even through a pipe or a redirected
output, the output suddenly mysteriously changes back to a 'normal' sun
termcap entry:

 % tset -QS | cat
sun Mu|sun:li#34:co#80:cl=^L:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:am:bs:km:mi:ms:
( etc.)
rs=\E[s: %

Or:

 % tset -QS > /tmp/foo
 % cat /tmp/foo
sun Mu|sun:li#34:co#80:cl=^L:cm=\E[%i%d;%dH:nd=\E[C:up=\E[A:am:bs:km:mi:ms:
( etc. )
rs=\E[s : % 

How/Why is this happening?  more(1) seems to know about the length of the tty
subwindow; you get everything from the top of the window down to the last 
line before more stops.  Does it get it directly from the window subsystem?
One reason I ask is that it seems like it could be a wonderful feature; 
you could put a series of statements in your .cshrc file (like the 
example given in the man page for tset with option -S) so each program 
that used $TERMCAP would know about the window limits if it wanted 
(I was thinking of modifying vnews(1) to do this, instead of the fixed 
# of lines you get).

For a minute, I thought the old "can't set your parent's env from yerself"
but that can't be it; you can muck all your other environment variables to
your hearts content inside the (non-login) shell windows.

Thanks in advance.

				Greg Earle

 ...!{{decvax,ucbvax}!sdcsvax,hplabs,allegra,trwrb}!sdcrdcf!smeagol!lorien!earle

 ...!{ihnp4,decvax,ucbvax}!sun!tsunami!smeagol!lorien!earle

chris@umcp-cs.UUCP (Chris Torek) (10/13/85)

The answer no doubt lies in the fact that the window size is obtained
via an ioctl:  `TIOCGSIZE'.  Presumably Sun's tset is performing
this on its standard output, and inside backquotes this is tied to
a pipe rather than the terminal.  If you have source, you may be
able to fix tset by making the ioctl happen on 0 or 2 (stdin or
stderr).

Sun changed their termcap routines to know about the `li#' and
`co#' entries, and to return the appropriate values based on the
window size, if available.  Thus programs like `more' work without
modification.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

shannon@sun.uucp (Bill Shannon) (10/14/85)

Within the termcap library, whenever you do a tgetent, it tries to find
out the size of the current window.  It does this by doing an ioctl on
stdout.  Almost always, when using termcap, stdout is the tty/window
you're going to do termcap things to.  If the ioctl succeeds, tgetent
modifies the normal termcap entry to insert new "li" and "co" entries
at the front (where they'll be found before the attributes in the
normal termcap entry).  This explains why it fails when you pipe the
output through cat but succeeds in almost all real cases.

					Bill Shannon


P.S.  Not mentioned above is the fact that if the window size changes
after doing the tgetent, the program must've set itself up to notice
the change (catch the SIGWINCH signal) and do the ioctl itself to get
the new window size.

peter@graffiti.UUCP (Peter da Silva) (10/15/85)

> I have a question for the Sun gurus.  When inside the window system,
> executing "tset -QS" directly from the shell gives output that
> 'knows' about the size (lines, columns) of the current window: 
> But lo and behold; if you should try to do anything with this output, like
> put it between `` for use with eval, or even through a pipe or a redirected
> output, the output suddenly mysteriously changes back to a 'normal' sun
> termcap entry:

Sounds like tset is using stdout for the ioctl that reads the real screen
size. OOPS (as tgoto(3) said after I did something similar).