blob: a22bec3365f6036936f17ecf0fa228156c9868c9 [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
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
Patrick Williamsc124f4f2015-09-15 14:41:29 -050032nonblockingfd(pty)
33nonblockingfd(sys.stdin)
34
35
36histfile = os.path.expanduser("~/.oedevpyshell-history")
37readline.parse_and_bind("tab: complete")
38try:
39 readline.read_history_file(histfile)
40except IOError:
41 pass
42
43try:
44
45 i = ""
46 o = ""
47 # Need cbreak/noecho whilst in select so we trigger on any keypress
48 cbreaknoecho(sys.stdin.fileno())
49 # Send our PID to the other end so they can kill us.
Patrick Williamsc0f7c042017-02-23 20:41:17 -060050 pty.write(str(os.getpid()).encode('utf-8') + b"\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050051 while True:
52 try:
53 writers = []
54 if i:
55 writers.append(sys.stdout)
56 (ready, _, _) = select.select([pty, sys.stdin], writers , [], 0)
57 try:
58 if pty in ready:
Patrick Williamsc0f7c042017-02-23 20:41:17 -060059 i = i + pty.read().decode('utf-8')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050060 if i:
61 # Write a page at a time to avoid overflowing output
62 # d.keys() is a good way to do that
63 sys.stdout.write(i[:4096])
Patrick Williamsc0f7c042017-02-23 20:41:17 -060064 sys.stdout.flush()
Patrick Williamsc124f4f2015-09-15 14:41:29 -050065 i = i[4096:]
66 if sys.stdin in ready:
67 echonocbreak(sys.stdin.fileno())
Patrick Williamsc0f7c042017-02-23 20:41:17 -060068 o = input().encode('utf-8')
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069 cbreaknoecho(sys.stdin.fileno())
Patrick Williamsc0f7c042017-02-23 20:41:17 -060070 pty.write(o + b"\n")
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071 except (IOError, OSError) as e:
72 if e.errno == 11:
73 continue
74 if e.errno == 5:
75 sys.exit(0)
76 raise
77 except EOFError:
78 sys.exit(0)
79 except KeyboardInterrupt:
80 os.kill(parent, signal.SIGINT)
81
82except SystemExit:
83 pass
84except Exception as e:
85 import traceback
86 print("Exception in oepydehshell-internal: " + str(e))
87 traceback.print_exc()
88 time.sleep(5)
89finally:
90 readline.write_history_file(histfile)