Use pseudoterminal to run tools when bkpt enabled
Using our usual subprocess scheme seems to break terminal echo for some
tools when run interactively through SC. Using a pseudo-terminal to run
them instead seems to solve the problem.
@@ -33,6 +33,7 @@ import getpass
import distro
import netifaces
import webbrowser
+import pty
from jinja2 import Environment, FileSystemLoader
from pathlib import Path
from timeit import default_timer as timer
@@ -3448,6 +3449,22 @@ class Chip:
self.logger.info('%s', cmdstr)
timeout = self.get('flowgraph', flow, step, index, 'timeout')
logfile = step + '.log'
+ if sys.platform in ('darwin', 'linux') and step in self.get('bkpt'):
+ # When we break on a step, the tool often drops into a shell.
+ # However, our usual subprocess scheme seems to break terminal
+ # echo for some tools. On POSIX-compatible systems, we can use
+ # pty to connect the tool to our terminal instead. This code
+ # doesn't handle quiet/timeout logic, since we don't want either
+ # of these features for an interactive session. Logic for
+ # forwarding to file based on
+ # https://docs.python.org/3/library/pty.html#example.
+ with open(logfile, 'wb') as log_writer:
+ def read(fd):
+ data = os.read(fd, 1024)
+ log_writer.write(data)
+ return data
+ retcode = pty.spawn(cmdlist, read)
+ else:
with open(logfile, 'w') as log_writer, open(logfile, 'r') as log_reader:
# Use separate reader/writer file objects as hack to display
# live output in non-blocking way, so we can monitor the
@@ -3469,9 +3486,10 @@ class Chip:
# Read the remaining
if not quiet:
sys.stdout.write(log_reader.read())
+ retcode = proc.returncode
- if proc.returncode != 0:
- self.logger.warning('Command failed. See log file %s', os.path.abspath(logfile))
+ if retcode != 0:
+ self.logger.warning('Command failed with code %d. See log file %s', retcode, os.path.abspath(logfile))
if not self.get('eda', tool, 'continue'):
self._haltstep(step, index, active)
