~ubuntu-branches/ubuntu/natty/computer-janitor/natty

« back to all changes in this revision

Viewing changes to computerjanitorapp/terminalsize.py

  • Committer: Bazaar Package Importer
  • Author(s): Lars Wirzenius
  • Date: 2009-02-19 09:37:52 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090219093752-4e3rkcoatpr4x2u8
Tags: 1.12-0ubuntu1
* New upstream release.
* Upstream source has partially been moved to update-manager. This
  has resulted in some packaging changes.
* debian/control: Add dependency on update-manager-core for 
  computer-janitor, on the version of update-manager-core that includes
  the computer-janitor core code (plugin management, plugins).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# terminalsize.py - find size of terminal
 
2
# Copyright (C) 2008  Canonical, Ltd.
 
3
#
 
4
# This program is free software: you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation, version 3 of the License.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 
 
16
# Inspired by code by Chuck Blake, at
 
17
# http://pdos.csail.mit.edu/~cblake/cls/cls.py, but rewritten in an
 
18
# attempt to clarify things. This code is slightly tricky, so I thought
 
19
# the extra clarity would be worth it.
 
20
 
 
21
import fcntl
 
22
import os
 
23
import struct
 
24
import termios
 
25
 
 
26
 
 
27
def get_terminal_size(fd=1):
 
28
    """Return size of terminal attached to the standard output.
 
29
    
 
30
    Use ioctl(2) to query a terminal for its size, given a file
 
31
    descriptor attached to the terminal. Return (None, None) if this
 
32
    fails, otherwise a tuple (columns, rows).
 
33
    
 
34
    (The optional 'fd' argument can be set to whatever file
 
35
    descriptor you want to use. This is useful for unit tests.)
 
36
    
 
37
    """
 
38
 
 
39
    try:
 
40
        # Do the ioctl call. termios.TIOCGWINSZ is the code to query
 
41
        # terminal size (see tty_ioctl(4), at least on Linux). We need
 
42
        # to give it a string of suitable size to use as the input
 
43
        # buffer for ioctl. Ioctl modifies the buffer and returns the
 
44
        # modified buffer as its return value.
 
45
        #
 
46
        # The manual page specifies a struct winsize to be used, which
 
47
        # consists of four unsigned shorts. We use struct.calcsize to
 
48
        # compute the size of that.
 
49
        # 
 
50
        # Note that Blake's original code assumes only the first two 
 
51
        # shorts in the struct are used, and that two shorts fit into
 
52
        # four bytes, which is probably true for all the relevant
 
53
        # platforms, but is cramped enough that it makes me feel icky.
 
54
        # Thus, I assume less. This will still break if the contents
 
55
        # of the struct change, but since that would change the system
 
56
        # call API, that's unlikely.
 
57
        
 
58
        buflen = struct.calcsize('hhhh')
 
59
        buf = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * buflen)
 
60
        
 
61
        # ioctl returns a binary buffer that represents the struct
 
62
        # at the C level. We unpack it with struct.unpack.
 
63
        
 
64
        tuple = struct.unpack('hhhh', buf)
 
65
    except:
 
66
        # If anything went wrong, we give up and claim we don't know.
 
67
        return None, None
 
68
 
 
69
    return tuple[0], tuple[1]