summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2012-08-15 16:00:40 (GMT)
committerRichard Purdie <richard.purdie@linuxfoundation.org>2012-08-16 10:19:03 (GMT)
commitc49a2529bffc38b4a1f40ccaccc578022b1517b1 (patch)
tree69aa2193eebf3929f5bcf762e110384a57e2736d /bitbake
parent2718537b4b04eb3d80ab4d74171b58e7b8dd68b8 (diff)
downloadpoky-c49a2529bffc38b4a1f40ccaccc578022b1517b1.tar.gz
bitbake: knotty2: Handle long lines of text and terminal window size changes
Long lines of text which wrapped on the terminal corrupted the output shown by knotty2. This patch catches such errors by becomming aware of the terminal size. It also catches terminal window size change events and adapting to those changes using a signal handler. Based on a patch from Jason Wessel with several tweaks and enhancements such as use of chained signal handlers and covering all output messages. (Bitbake rev: 9afc9e4d14abec5ac326851d4bb689c1e8d45a43) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/ui/knotty2.py52
1 files changed, 46 insertions, 6 deletions
diff --git a/bitbake/lib/bb/ui/knotty2.py b/bitbake/lib/bb/ui/knotty2.py
index 65e941b..57ad67f 100644
--- a/bitbake/lib/bb/ui/knotty2.py
+++ b/bitbake/lib/bb/ui/knotty2.py
@@ -21,6 +21,10 @@
21from bb.ui import knotty 21from bb.ui import knotty
22import logging 22import logging
23import sys 23import sys
24import os
25import fcntl
26import struct
27import copy
24logger = logging.getLogger("BitBake") 28logger = logging.getLogger("BitBake")
25 29
26class InteractConsoleLogFilter(logging.Filter): 30class InteractConsoleLogFilter(logging.Filter):
@@ -35,6 +39,35 @@ class InteractConsoleLogFilter(logging.Filter):
35 return True 39 return True
36 40
37class TerminalFilter2(object): 41class TerminalFilter2(object):
42 columns = 80
43
44 def sigwinch_handle(self, signum, frame):
45 self.columns = self.getTerminalColumns()
46 if self._sigwinch_default:
47 self._sigwinch_default(signum, frame)
48
49 def getTerminalColumns(self):
50 def ioctl_GWINSZ(fd):
51 try:
52 cr = struct.unpack('hh', fcntl.ioctl(fd, self.termios.TIOCGWINSZ, '1234'))
53 except:
54 return None
55 return cr
56 cr = ioctl_GWINSZ(sys.stdout.fileno())
57 if not cr:
58 try:
59 fd = os.open(os.ctermid(), os.O_RDONLY)
60 cr = ioctl_GWINSZ(fd)
61 os.close(fd)
62 except:
63 pass
64 if not cr:
65 try:
66 cr = (env['LINES'], env['COLUMNS'])
67 except:
68 cr = (25, 80)
69 return cr[1]
70
38 def __init__(self, main, helper, console, format): 71 def __init__(self, main, helper, console, format):
39 self.main = main 72 self.main = main
40 self.helper = helper 73 self.helper = helper
@@ -49,7 +82,6 @@ class TerminalFilter2(object):
49 82
50 import curses 83 import curses
51 import termios 84 import termios
52 import copy
53 self.curses = curses 85 self.curses = curses
54 self.termios = termios 86 self.termios = termios
55 try: 87 try:
@@ -62,6 +94,12 @@ class TerminalFilter2(object):
62 self.ed = curses.tigetstr("ed") 94 self.ed = curses.tigetstr("ed")
63 if self.ed: 95 if self.ed:
64 self.cuu = curses.tigetstr("cuu") 96 self.cuu = curses.tigetstr("cuu")
97 try:
98 self._sigwinch_default = signal.getsignal(signal.SIGWINCH)
99 signal.signal(signal.SIGWINCH, self.sigwinch_handle)
100 except:
101 pass
102 self.columns = self.getTerminalColumns()
65 except: 103 except:
66 self.cuu = None 104 self.cuu = None
67 console.addFilter(InteractConsoleLogFilter(self, format)) 105 console.addFilter(InteractConsoleLogFilter(self, format))
@@ -85,18 +123,20 @@ class TerminalFilter2(object):
85 self.clearFooter() 123 self.clearFooter()
86 if not activetasks: 124 if not activetasks:
87 return 125 return
88 lines = 1
89 tasks = [] 126 tasks = []
90 for t in runningpids: 127 for t in runningpids:
91 tasks.append("%s (pid %s)" % (activetasks[t]["title"], t)) 128 tasks.append("%s (pid %s)" % (activetasks[t]["title"], t))
92 129
93 if self.main.shutdown: 130 if self.main.shutdown:
94 print("Waiting for %s running tasks to finish:" % len(activetasks)) 131 content = "Waiting for %s running tasks to finish:" % len(activetasks)
95 else: 132 else:
96 print("Currently %s running tasks (%s of %s):" % (len(activetasks), self.helper.tasknumber_current, self.helper.tasknumber_total)) 133 content = "Currently %s running tasks (%s of %s):" % (len(activetasks), self.helper.tasknumber_current, self.helper.tasknumber_total)
134 print content
135 lines = 1 + int(len(content) / (self.columns + 1))
97 for tasknum, task in enumerate(tasks): 136 for tasknum, task in enumerate(tasks):
98 print("%s: %s" % (tasknum, task)) 137 content = "%s: %s" % (tasknum, task)
99 lines = lines + 1 138 print content
139 lines = lines + 1 + int(len(content) / (self.columns + 1))
100 self.footer_present = lines 140 self.footer_present = lines
101 self.lastpids = runningpids[:] 141 self.lastpids = runningpids[:]
102 142