diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2015-07-02 00:51:03 -0700 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2015-07-02 00:51:03 -0700 |
commit | 6892d7189f5ed4d497d400ce865ea8d87b6008d8 (patch) | |
tree | 2f63d645e0db3f0968ee98630d18f762db278dd2 | |
parent | 6f94a2567b687854b18c5f73f6577d10136ef3d1 (diff) | |
parent | 6ed5dd74278a7a6be534f8900eb284ea97ca9f24 (diff) | |
download | spack-6892d7189f5ed4d497d400ce865ea8d87b6008d8.tar.gz spack-6892d7189f5ed4d497d400ce865ea8d87b6008d8.tar.bz2 spack-6892d7189f5ed4d497d400ce865ea8d87b6008d8.tar.xz spack-6892d7189f5ed4d497d400ce865ea8d87b6008d8.zip |
Merge branch 'features/toggle-build-output' into develop
-rw-r--r-- | lib/spack/llnl/util/tty/log.py | 93 |
1 files changed, 78 insertions, 15 deletions
diff --git a/lib/spack/llnl/util/tty/log.py b/lib/spack/llnl/util/tty/log.py index 6ccd0e66d9..5a52d45bc7 100644 --- a/lib/spack/llnl/util/tty/log.py +++ b/lib/spack/llnl/util/tty/log.py @@ -29,6 +29,7 @@ import os import re import select import inspect + import llnl.util.tty as tty import llnl.util.tty.color as color @@ -45,6 +46,59 @@ class _SkipWithBlock(): pass +class keyboard_input(object): + """Disable canonical input and echo on a stream within a with block. + + Use this with sys.stdin for keyboard input, e.g.: + + with keyboard_input(sys.stdin): + r, w, x = select.select([sys.stdin], [], []) + # ... do something with keypresses ... + + When the with block completes, this will restore settings before + canonical and echo were disabled. + """ + def __init__(self, stream): + self.stream = stream + + + def __enter__(self): + self.old_cfg = None + + # Ignore all this if the input stream is not a tty. + if not self.stream.isatty(): + return + + try: + # import and mark whether it worked. + import termios + + # save old termios settings + fd = self.stream.fileno() + self.old_cfg = termios.tcgetattr(fd) + + # create new settings with canonical input and echo + # disabled, so keypresses are immediate & don't echo. + self.new_cfg = termios.tcgetattr(fd) + self.new_cfg[3] &= ~termios.ICANON + self.new_cfg[3] &= ~termios.ECHO + + # Apply new settings for terminal + termios.tcsetattr(fd, termios.TCSADRAIN, self.new_cfg) + + except Exception, e: + pass # Some OS's do not support termios, so ignore. + + + def __exit__(self, exc_type, exception, traceback): + # If termios was avaialble, restore old settings after the + # with block + if self.old_cfg: + import termios + termios.tcsetattr( + self.stream.fileno(), termios.TCSADRAIN, self.old_cfg) + + class log_output(object): """Redirects output and error of enclosed block to a file. @@ -94,21 +148,30 @@ class log_output(object): read_file = os.fdopen(read, 'r', 0) with self.stream as log_file: - while True: - rlist, w, x = select.select([read_file], [], []) - if not rlist: - break - - line = read_file.readline() - if not line: - break - - # Echo to stdout if requested. - if self.echo: - sys.stdout.write(line) - - # Stripped output to log file. - log_file.write(_strip(line)) + with keyboard_input(sys.stdin): + while True: + rlist, w, x = select.select([read_file, sys.stdin], [], []) + if not rlist: + break + + # Allow user to toggle echo with 'v' key. + # Currently ignores other chars. + if sys.stdin in rlist: + if sys.stdin.read(1) == 'v': + self.echo = not self.echo + + # handle output from the with block process. + if read_file in rlist: + line = read_file.readline() + if not line: + break + + # Echo to stdout if requested. + if self.echo: + sys.stdout.write(line) + + # Stripped output to log file. + log_file.write(_strip(line)) read_file.flush() read_file.close() |