blob: 247d04478c41f5d022ccc524281ba6556384a4e5 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001inherit terminal
2
3DEVSHELL = "${SHELL}"
4
Patrick Williams03907ee2022-05-01 06:28:52 -05005PATH:prepend:task-devshell = "${COREBASE}/scripts/git-intercept:"
6
Patrick Williamsc124f4f2015-09-15 14:41:29 -05007python do_devshell () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -05008 if d.getVarFlag("do_devshell", "manualfakeroot"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -05009 d.prependVar("DEVSHELL", "pseudo ")
Brad Bishop6e60e8b2018-02-01 10:27:11 -050010 fakeenv = d.getVar("FAKEROOTENV").split()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011 for f in fakeenv:
12 k = f.split("=")
Brad Bishopd7bf8c12018-02-25 22:55:05 -050013 d.setVar(k[0], k[1])
Patrick Williamsc124f4f2015-09-15 14:41:29 -050014 d.appendVar("OE_TERMINAL_EXPORTS", " " + k[0])
15 d.delVarFlag("do_devshell", "fakeroot")
16
Brad Bishop6e60e8b2018-02-01 10:27:11 -050017 oe_terminal(d.getVar('DEVSHELL'), 'OpenEmbedded Developer Shell', d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050018}
19
Brad Bishopd7bf8c12018-02-25 22:55:05 -050020addtask devshell after do_patch do_prepare_recipe_sysroot
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021
22# The directory that the terminal starts in
23DEVSHELL_STARTDIR ?= "${S}"
24do_devshell[dirs] = "${DEVSHELL_STARTDIR}"
25do_devshell[nostamp] = "1"
Patrick Williams03907ee2022-05-01 06:28:52 -050026do_devshell[network] = "1"
Patrick Williamsc124f4f2015-09-15 14:41:29 -050027
28# devshell and fakeroot/pseudo need careful handling since only the final
29# command should run under fakeroot emulation, any X connection should
30# be done as the normal user. We therfore carefully construct the envionment
31# manually
32python () {
Brad Bishop6e60e8b2018-02-01 10:27:11 -050033 if d.getVarFlag("do_devshell", "fakeroot"):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050034 # We need to signal our code that we want fakeroot however we
35 # can't manipulate the environment and variables here yet (see YOCTO #4795)
36 d.setVarFlag("do_devshell", "manualfakeroot", "1")
37 d.delVarFlag("do_devshell", "fakeroot")
38}
39
Andrew Geisslereff27472021-10-29 15:35:00 -050040def pydevshell(d):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050041
42 import code
43 import select
44 import signal
45 import termios
46
47 m, s = os.openpty()
48 sname = os.ttyname(s)
49
50 def noechoicanon(fd):
51 old = termios.tcgetattr(fd)
52 old[3] = old[3] &~ termios.ECHO &~ termios.ICANON
53 # &~ termios.ISIG
54 termios.tcsetattr(fd, termios.TCSADRAIN, old)
Brad Bishopd7bf8c12018-02-25 22:55:05 -050055
Patrick Williamsc124f4f2015-09-15 14:41:29 -050056 # No echo or buffering over the pty
57 noechoicanon(s)
58
59 pid = os.fork()
60 if pid:
61 os.close(m)
62 oe_terminal("oepydevshell-internal.py %s %d" % (sname, pid), 'OpenEmbedded Developer PyShell', d)
63 os._exit(0)
64 else:
65 os.close(s)
66
67 os.dup2(m, sys.stdin.fileno())
68 os.dup2(m, sys.stdout.fileno())
69 os.dup2(m, sys.stderr.fileno())
70
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071 bb.utils.nonblockingfd(sys.stdout)
72 bb.utils.nonblockingfd(sys.stderr)
73 bb.utils.nonblockingfd(sys.stdin)
74
75 _context = {
76 "os": os,
77 "bb": bb,
78 "time": time,
79 "d": d,
80 }
81
82 ps1 = "pydevshell> "
83 ps2 = "... "
84 buf = []
85 more = False
86
87 i = code.InteractiveInterpreter(locals=_context)
Brad Bishop6e60e8b2018-02-01 10:27:11 -050088 print("OE PyShell (PN = %s)\n" % d.getVar("PN"))
Patrick Williamsc124f4f2015-09-15 14:41:29 -050089
90 def prompt(more):
91 if more:
92 prompt = ps2
93 else:
94 prompt = ps1
95 sys.stdout.write(prompt)
Patrick Williamsc0f7c042017-02-23 20:41:17 -060096 sys.stdout.flush()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097
98 # Restore Ctrl+C since bitbake masks this
99 def signal_handler(signal, frame):
100 raise KeyboardInterrupt
101 signal.signal(signal.SIGINT, signal_handler)
102
103 child = None
104
105 prompt(more)
106 while True:
107 try:
108 try:
109 (r, _, _) = select.select([sys.stdin], [], [], 1)
110 if not r:
111 continue
112 line = sys.stdin.readline().strip()
113 if not line:
114 prompt(more)
115 continue
116 except EOFError as e:
117 sys.stdout.write("\n")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600118 sys.stdout.flush()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500119 except (OSError, IOError) as e:
120 if e.errno == 11:
121 continue
122 if e.errno == 5:
123 return
124 raise
125 else:
126 if not child:
127 child = int(line)
128 continue
129 buf.append(line)
130 source = "\n".join(buf)
131 more = i.runsource(source, "<pyshell>")
132 if not more:
133 buf = []
Andrew Geissler95ac1b82021-03-31 14:34:31 -0500134 sys.stderr.flush()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500135 prompt(more)
136 except KeyboardInterrupt:
137 i.write("\nKeyboardInterrupt\n")
138 buf = []
139 more = False
140 prompt(more)
141 except SystemExit:
142 # Easiest way to ensure everything exits
143 os.kill(child, signal.SIGTERM)
144 break
145
Andrew Geisslereff27472021-10-29 15:35:00 -0500146python do_pydevshell() {
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500147 import signal
148
149 try:
Andrew Geisslereff27472021-10-29 15:35:00 -0500150 pydevshell(d)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 except SystemExit:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500152 # Stop the SIGTERM above causing an error exit code
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500153 return
154 finally:
155 return
156}
Andrew Geisslereff27472021-10-29 15:35:00 -0500157addtask pydevshell after do_patch
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500158
Andrew Geisslereff27472021-10-29 15:35:00 -0500159do_pydevshell[nostamp] = "1"
Patrick Williams03907ee2022-05-01 06:28:52 -0500160do_pydevshell[network] = "1"