Best way of finding terminal width/height?
Grant Edwards
grante at visi.com
Tue Feb 7 13:06:43 EST 2006
On 2006-02-07, Joel Hedlund <joel.hedlund at gmail.com> wrote:
>> You just call the failed read() or write() again. Unless
>> there's some way that the read/write partially succeeded and
>> you don't have any way to know how many bytes were
>> read/written, If that's the case then Python's "file" object
>> read and write would appear to be broken by design.
>
> Wow... I tried to set up an example that would fail, and it
> didn't. It seems the test only fails if I use the keyboard to
> cram stuff into stdin, and not if stdin is a regular pipe.
That's what I'd expect. Resizing the terminal should have no
effect on read() calls that are pending on other things.
> Could this perhaps be some kind of misbehavior on behalf of my
> terminal emulator (GNOME Terminal 2.12.0 in Ubuntulinux 5.10)?
Nope. Resign the terminal will abort pending I/O operations on
that terminal. It won't terminal I/O operations pending on
other devices/files.
> Then run the prog and pipe a large chunk of text into stdin, and redirect stdout to a file:
>
> $ cat /a/large/text/file | python winch.py > copy.of.the.large.file
>
> Now, what happens for me is exactly what I wanted. I can
> resize the window as much as I like, and a diff
Sure.
> $ diff /a/large/text/file copy.of.the.large.file
>
> comes up empty. A perfectly good copy.
>
> However, if I do this instead (try to use keyboard to push stuff into stdin):
>
> $ python winch.py > copy.of.the.large.file
>
> I expect python not to return until I press Ctrl-D on my
> keyboard,
sys.stdin.read() will return when there's an EOF or when the
underyling read() call is aborted by a signal.
> but it does return as soon as I enter more than one
> line of text and then resize the window (one unterminated line
> is ok).
>
> Example text to type in:
> moo moo
> cow cow
>
> As soon as I have typed in something that includes a newline
> charater through the keyboard and try to resize the terminal,
> sys.stdin.read() will return whatever I put in no far and no
> exception raised.
Yup. That does indeed appear to be the way it works. :)
> Weird. Could it in fact my terminal that's screwing things up
> for me?
No.
Try this out:
----------------------------------------------------------------------
#!/usr/bin/python
import signal, os, sys
_bTerminalSizeChanged = False
def report_terminal_size_change(signum, frame):
global _bTerminalSizeChanged
_bTerminalSizeChanged = True
signal.signal(signal.SIGWINCH, report_terminal_size_change)
while True:
try:
s = sys.stdin.read()
if not s:
break
sys.stdout.write(s)
except IOError:
sys.stderr.write("IOError\n")
if _bTerminalSizeChanged:
sys.stderr.write("SIGWINCH recevied\n")
_bTerminalSizeChanged = False
----------------------------------------------------------------------
In that example, I handle IOError on write with the same
exception handler as the one for read. That may not be exactly
what you want to do, but it does demonstrate what
window-resizing does.
When the window is resized, the SIGWINCH handler will be
called. A pending read() may abort with an IOError, or it may
just return some buffered data.
--
Grant Edwards grante Yow! Send your questions
at to "ASK ZIPPY", Box 40474,
visi.com San Francisco, CA 94140,
USA
More information about the Python-list
mailing list