summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAseda Aboagye <aaboagye@google.com>2015-12-17 16:55:01 -0800
committerchrome-bot <chrome-bot@chromium.org>2015-12-17 23:45:18 -0800
commit4bad633cb9ece35138415541a0decafda613a95f (patch)
tree15bd06ee85e188bcbd738cbd9267691dd3e82815
parent6a29ca187a22012a984808d76caaa339c85c5616 (diff)
downloadchrome-ec-4bad633cb9ece35138415541a0decafda613a95f.tar.gz
ec3po: Add graceful exit.
The console and interpreter are usually killed by KeyboardInterrupt whether or not it's run standalone or by servod. This commit tries to make the exit graceful by closing pipes, file descriptors, and exiting each process. BUG=chromium:570526 BRANCH=None TEST=Run ec3po standalone and hit Ctrl+C to kill it. Observe no traceback and no leftover processes. TEST=Repeat above test, but inside servod TEST=cros lint --debug util/ec3po/console.py TEST=cros lint --debug util/ec3po/interpreter.py TEST=python2 -b util/ec3po/console_interpreter.py TEST=python2 -b util/ec3po/console_interpreter.py Change-Id: Ia151b9ede8adf7f8dec6c07277f62d097c13e63e Signed-off-by: Aseda Aboagye <aaboagye@google.com> Reviewed-on: https://chromium-review.googlesource.com/319252 Commit-Ready: Aseda Aboagye <aaboagye@chromium.org> Tested-by: Aseda Aboagye <aaboagye@chromium.org> Reviewed-by: Wai-Hong Tam <waihong@chromium.org>
-rwxr-xr-xutil/ec3po/console.py63
-rw-r--r--util/ec3po/interpreter.py43
2 files changed, 63 insertions, 43 deletions
diff --git a/util/ec3po/console.py b/util/ec3po/console.py
index 962d042ff3..39278e343d 100755
--- a/util/ec3po/console.py
+++ b/util/ec3po/console.py
@@ -635,32 +635,42 @@ def StartLoop(console):
"""
console.logger.info('EC Console is being served on %s.', console.user_pty)
console.logger.debug(console)
- while True:
- # Check to see if pipes or the console are ready for reading.
- read_list = [console.master_pty, console.cmd_pipe, console.dbg_pipe]
- ready_for_reading = select.select(read_list, [], [])[0]
-
- for obj in ready_for_reading:
- if obj is console.master_pty:
- console.logger.debug('Input from user')
- # Convert to bytes so we can look for non-printable chars such as
- # Ctrl+A, Ctrl+E, etc.
- line = bytearray(os.read(console.master_pty, CONSOLE_MAX_READ))
- for i in line:
- # Handle each character as it arrives.
- console.HandleChar(i)
-
- elif obj is console.cmd_pipe:
- data = console.cmd_pipe.recv()
- # Write it to the user console.
- console.logger.debug('|CMD|->\'%s\'', data)
- os.write(console.master_pty, data)
-
- elif obj is console.dbg_pipe:
- data = console.dbg_pipe.recv()
- # Write it to the user console.
- console.logger.debug('|DBG|->\'%s\'', data)
- os.write(console.master_pty, data)
+ try:
+ while True:
+ # Check to see if pipes or the console are ready for reading.
+ read_list = [console.master_pty, console.cmd_pipe, console.dbg_pipe]
+ ready_for_reading = select.select(read_list, [], [])[0]
+
+ for obj in ready_for_reading:
+ if obj is console.master_pty:
+ console.logger.debug('Input from user')
+ # Convert to bytes so we can look for non-printable chars such as
+ # Ctrl+A, Ctrl+E, etc.
+ line = bytearray(os.read(console.master_pty, CONSOLE_MAX_READ))
+ for i in line:
+ # Handle each character as it arrives.
+ console.HandleChar(i)
+
+ elif obj is console.cmd_pipe:
+ data = console.cmd_pipe.recv()
+ # Write it to the user console.
+ console.logger.debug('|CMD|->\'%s\'', data)
+ os.write(console.master_pty, data)
+
+ elif obj is console.dbg_pipe:
+ data = console.dbg_pipe.recv()
+ # Write it to the user console.
+ console.logger.debug('|DBG|->\'%s\'', data)
+ os.write(console.master_pty, data)
+
+ finally:
+ # Close pipes.
+ console.dbg_pipe.close()
+ console.cmd_pipe.close()
+ # Close file descriptor.
+ os.close(console.master_pty)
+ # Exit.
+ sys.exit(0)
def main(argv):
@@ -676,7 +686,6 @@ def main(argv):
# Set up argument parser.
parser = argparse.ArgumentParser(description=('Start interactive EC console '
'and interpreter.'))
- # TODO(aaboagye): Eventually get this from servod.
parser.add_argument('ec_uart_pty',
help=('The full PTY name that the EC UART'
' is present on. eg: /dev/pts/12'))
diff --git a/util/ec3po/interpreter.py b/util/ec3po/interpreter.py
index 31079fb908..b71607f254 100644
--- a/util/ec3po/interpreter.py
+++ b/util/ec3po/interpreter.py
@@ -20,6 +20,7 @@ import logging
import os
import Queue
import select
+import sys
COMMAND_RETRIES = 3 # Number of attempts to retry a command.
@@ -312,19 +313,29 @@ def StartLoop(interp):
Args:
interp: An Interpreter object that has been properly initialised.
"""
- while True:
- readable, writeable, _ = select.select(interp.inputs, interp.outputs, [])
-
- for obj in readable:
- # Handle any debug prints from the EC.
- if obj is interp.ec_uart_pty:
- interp.HandleECData()
-
- # Handle any commands from the user.
- elif obj is interp.cmd_pipe:
- interp.HandleUserData()
-
- for obj in writeable:
- # Send a command to the EC.
- if obj is interp.ec_uart_pty:
- interp.SendCmdToEC()
+ try:
+ while True:
+ readable, writeable, _ = select.select(interp.inputs, interp.outputs, [])
+
+ for obj in readable:
+ # Handle any debug prints from the EC.
+ if obj is interp.ec_uart_pty:
+ interp.HandleECData()
+
+ # Handle any commands from the user.
+ elif obj is interp.cmd_pipe:
+ interp.HandleUserData()
+
+ for obj in writeable:
+ # Send a command to the EC.
+ if obj is interp.ec_uart_pty:
+ interp.SendCmdToEC()
+
+ finally:
+ # Close pipes.
+ interp.cmd_pipe.close()
+ interp.dbg_pipe.close()
+ # Close file descriptor.
+ interp.ec_uart_pty.close()
+ # Exit.
+ sys.exit(0)