diff options
Diffstat (limited to 'meta/classes/devshell.bbclass')
-rw-r--r-- | meta/classes/devshell.bbclass | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/meta/classes/devshell.bbclass b/meta/classes/devshell.bbclass index 92edb9ef25..41164a3f33 100644 --- a/meta/classes/devshell.bbclass +++ b/meta/classes/devshell.bbclass @@ -31,3 +31,124 @@ python () { d.setVarFlag("do_devshell", "manualfakeroot", "1") d.delVarFlag("do_devshell", "fakeroot") } + +def devpyshell(d): + + import code + import select + import signal + import termios + + m, s = os.openpty() + sname = os.ttyname(s) + + def noechoicanon(fd): + old = termios.tcgetattr(fd) + old[3] = old[3] &~ termios.ECHO &~ termios.ICANON + # &~ termios.ISIG + termios.tcsetattr(fd, termios.TCSADRAIN, old) + + # No echo or buffering over the pty + noechoicanon(s) + + pid = os.fork() + if pid: + os.close(m) + oe_terminal("oepydevshell-internal.py %s %d" % (sname, pid), 'OpenEmbedded Developer PyShell', d) + os._exit(0) + else: + os.close(s) + + os.dup2(m, sys.stdin.fileno()) + os.dup2(m, sys.stdout.fileno()) + os.dup2(m, sys.stderr.fileno()) + + sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) + sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0) + + bb.utils.nonblockingfd(sys.stdout) + bb.utils.nonblockingfd(sys.stderr) + bb.utils.nonblockingfd(sys.stdin) + + _context = { + "os": os, + "bb": bb, + "time": time, + "d": d, + } + + ps1 = "pydevshell> " + ps2 = "... " + buf = [] + more = False + + i = code.InteractiveInterpreter(locals=_context) + print("OE PyShell (PN = %s)\n" % d.getVar("PN", True)) + + def prompt(more): + if more: + prompt = ps2 + else: + prompt = ps1 + sys.stdout.write(prompt) + + # Restore Ctrl+C since bitbake masks this + def signal_handler(signal, frame): + raise KeyboardInterrupt + signal.signal(signal.SIGINT, signal_handler) + + child = None + + prompt(more) + while True: + try: + try: + (r, _, _) = select.select([sys.stdin], [], [], 1) + if not r: + continue + line = sys.stdin.readline().strip() + if not line: + prompt(more) + continue + except EOFError as e: + sys.stdout.write("\n") + except (OSError, IOError) as e: + if e.errno == 11: + continue + if e.errno == 5: + return + raise + else: + if not child: + child = int(line) + continue + buf.append(line) + source = "\n".join(buf) + more = i.runsource(source, "<pyshell>") + if not more: + buf = [] + prompt(more) + except KeyboardInterrupt: + i.write("\nKeyboardInterrupt\n") + buf = [] + more = False + prompt(more) + except SystemExit: + # Easiest way to ensure everything exits + os.kill(child, signal.SIGTERM) + break + +python do_devpyshell() { + import signal + + try: + devpyshell(d) + except SystemExit: + # Stop the SIGTERM above causing an error exit code + return + finally: + return +} +addtask devpyshell after do_patch + +do_devpyshell[nostamp] = "1" |