summaryrefslogtreecommitdiffstats
path: root/scripts/oepydevshell-internal.py
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2014-05-27 16:09:16 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-05-28 08:27:00 +0100
commitcd7b437d4b6800aab47ea9d9b00bbac1bb270bc5 (patch)
tree9f6590f7b0d8d7257f066f648712c9db9da0e504 /scripts/oepydevshell-internal.py
parent3bf24188b6735bc156f0e2f0acde0277b8443737 (diff)
downloadpoky-cd7b437d4b6800aab47ea9d9b00bbac1bb270bc5.tar.gz
devshell: Add interactive python shell
Being able to interact with the python context in the Bitbake task execution environment has long been desireable. This patch introduces such a mechanism. Executing "bitbake X -c devpyshell" will open a terminal connected to a python interactive interpretor in the task context so for example you can run commands like "d.getVar('WORKDIR')" This version now includes readline support for command history and various other bug fixes such as exiting cleanly compared to previous versions. (From OE-Core rev: 36734f34fe6e4b91e293234687e63c02f5b3117e) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'scripts/oepydevshell-internal.py')
-rwxr-xr-xscripts/oepydevshell-internal.py92
1 files changed, 92 insertions, 0 deletions
diff --git a/scripts/oepydevshell-internal.py b/scripts/oepydevshell-internal.py
new file mode 100755
index 0000000000..f7b2e4e0bf
--- /dev/null
+++ b/scripts/oepydevshell-internal.py
@@ -0,0 +1,92 @@
1#!/usr/bin/env python
2
3import os
4import sys
5import time
6import select
7import fcntl
8import termios
9import readline
10import signal
11
12def nonblockingfd(fd):
13 fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
14
15def echonocbreak(fd):
16 old = termios.tcgetattr(fd)
17 old[3] = old[3] | termios.ECHO | termios.ICANON
18 termios.tcsetattr(fd, termios.TCSADRAIN, old)
19
20def cbreaknoecho(fd):
21 old = termios.tcgetattr(fd)
22 old[3] = old[3] &~ termios.ECHO &~ termios.ICANON
23 termios.tcsetattr(fd, termios.TCSADRAIN, old)
24
25if len(sys.argv) != 3:
26 print("Incorrect parameters")
27 sys.exit(1)
28
29pty = open(sys.argv[1], "w+b", 0)
30parent = int(sys.argv[2])
31
32# Don't buffer output by line endings
33sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
34sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0)
35nonblockingfd(pty)
36nonblockingfd(sys.stdin)
37
38
39histfile = os.path.expanduser("~/.oedevpyshell-history")
40readline.parse_and_bind("tab: complete")
41try:
42 readline.read_history_file(histfile)
43except IOError:
44 pass
45
46try:
47
48 i = ""
49 o = ""
50 # Need cbreak/noecho whilst in select so we trigger on any keypress
51 cbreaknoecho(sys.stdin.fileno())
52 # Send our PID to the other end so they can kill us.
53 pty.write(str(os.getpid()) + "\n")
54 while True:
55 try:
56 writers = []
57 if i:
58 writers.append(sys.stdout)
59 (ready, _, _) = select.select([pty, sys.stdin], writers , [], 0)
60 try:
61 if pty in ready:
62 i = i + pty.read()
63 if i:
64 # Write a page at a time to avoid overflowing output
65 # d.keys() is a good way to do that
66 sys.stdout.write(i[:4096])
67 i = i[4096:]
68 if sys.stdin in ready:
69 echonocbreak(sys.stdin.fileno())
70 o = raw_input()
71 cbreaknoecho(sys.stdin.fileno())
72 pty.write(o + "\n")
73 except (IOError, OSError) as e:
74 if e.errno == 11:
75 continue
76 if e.errno == 5:
77 sys.exit(0)
78 raise
79 except EOFError:
80 sys.exit(0)
81 except KeyboardInterrupt:
82 os.kill(parent, signal.SIGINT)
83
84except SystemExit:
85 pass
86except Exception as e:
87 import traceback
88 print("Exception in oepydehshell-internal: " + str(e))
89 traceback.print_exc()
90 time.sleep(5)
91finally:
92 readline.write_history_file(histfile)