|  | inherit terminal | 
|  |  | 
|  | DEVSHELL = "${SHELL}" | 
|  |  | 
|  | python do_devshell () { | 
|  | if d.getVarFlag("do_devshell", "manualfakeroot", True): | 
|  | d.prependVar("DEVSHELL", "pseudo ") | 
|  | fakeenv = d.getVar("FAKEROOTENV", True).split() | 
|  | for f in fakeenv: | 
|  | k = f.split("=") | 
|  | d.setVar(k[0], k[1]) | 
|  | d.appendVar("OE_TERMINAL_EXPORTS", " " + k[0]) | 
|  | d.delVarFlag("do_devshell", "fakeroot") | 
|  |  | 
|  | oe_terminal(d.getVar('DEVSHELL', True), 'OpenEmbedded Developer Shell', d) | 
|  | } | 
|  |  | 
|  | addtask devshell after do_patch | 
|  |  | 
|  | # The directory that the terminal starts in | 
|  | DEVSHELL_STARTDIR ?= "${S}" | 
|  | do_devshell[dirs] = "${DEVSHELL_STARTDIR}" | 
|  | do_devshell[nostamp] = "1" | 
|  |  | 
|  | # devshell and fakeroot/pseudo need careful handling since only the final | 
|  | # command should run under fakeroot emulation, any X connection should | 
|  | # be done as the normal user. We therfore carefully construct the envionment | 
|  | # manually | 
|  | python () { | 
|  | if d.getVarFlag("do_devshell", "fakeroot", True): | 
|  | # We need to signal our code that we want fakeroot however we | 
|  | # can't manipulate the environment and variables here yet (see YOCTO #4795) | 
|  | 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" |