blob: 2f7d5d433e876839799761955bb042babe0f31a0 [file] [log] [blame]
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001#!/usr/bin/env python3
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002
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
Brad Bishop6e60e8b2018-02-01 10:27:11 -050025if len(sys.argv) != 3 or sys.argv[1] in ('-h', '--help'):
26 print('oepydevshell-internal.py: error: the following arguments are required: pty, pid\n'
27 'Usage: oepydevshell-internal.py pty pid\n\n'
28 'OpenEmbedded oepydevshell-internal.py - internal script called from meta/classes/devshell.bbclass\n\n'
29 'arguments:\n'
30 ' pty pty device name\n'
31 ' pid parent process id\n\n'
32 'options:\n'
33 ' -h, --help show this help message and exit\n')
34 sys.exit(2)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050035
36pty = open(sys.argv[1], "w+b", 0)
37parent = int(sys.argv[2])
38
Patrick Williamsc124f4f2015-09-15 14:41:29 -050039nonblockingfd(pty)
40nonblockingfd(sys.stdin)
41
42
43histfile = os.path.expanduser("~/.oedevpyshell-history")
44readline.parse_and_bind("tab: complete")
45try:
46 readline.read_history_file(histfile)
47except IOError:
Brad Bishop6e60e8b2018-02-01 10:27:11 -050048 pass
Patrick Williamsc124f4f2015-09-15 14:41:29 -050049
50try:
51
52 i = ""
53 o = ""
54 # Need cbreak/noecho whilst in select so we trigger on any keypress
55 cbreaknoecho(sys.stdin.fileno())
56 # Send our PID to the other end so they can kill us.
Patrick Williamsc0f7c042017-02-23 20:41:17 -060057 pty.write(str(os.getpid()).encode('utf-8') + b"\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058 while True:
59 try:
60 writers = []
61 if i:
62 writers.append(sys.stdout)
63 (ready, _, _) = select.select([pty, sys.stdin], writers , [], 0)
64 try:
65 if pty in ready:
Brad Bishop19323692019-04-05 15:28:33 -040066 readdata = pty.read()
67 if readdata:
68 i = i + readdata.decode('utf-8')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069 if i:
70 # Write a page at a time to avoid overflowing output
71 # d.keys() is a good way to do that
72 sys.stdout.write(i[:4096])
Patrick Williamsc0f7c042017-02-23 20:41:17 -060073 sys.stdout.flush()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050074 i = i[4096:]
75 if sys.stdin in ready:
76 echonocbreak(sys.stdin.fileno())
Patrick Williamsc0f7c042017-02-23 20:41:17 -060077 o = input().encode('utf-8')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050078 cbreaknoecho(sys.stdin.fileno())
Patrick Williamsc0f7c042017-02-23 20:41:17 -060079 pty.write(o + b"\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050080 except (IOError, OSError) as e:
81 if e.errno == 11:
82 continue
83 if e.errno == 5:
84 sys.exit(0)
85 raise
86 except EOFError:
87 sys.exit(0)
88 except KeyboardInterrupt:
89 os.kill(parent, signal.SIGINT)
90
91except SystemExit:
92 pass
93except Exception as e:
94 import traceback
95 print("Exception in oepydehshell-internal: " + str(e))
96 traceback.print_exc()
97 time.sleep(5)
98finally:
99 readline.write_history_file(histfile)