oepydevshell-internal.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #!/usr/bin/env python
  2. import os
  3. import sys
  4. import time
  5. import select
  6. import fcntl
  7. import termios
  8. import readline
  9. import signal
  10. def nonblockingfd(fd):
  11. fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
  12. def echonocbreak(fd):
  13. old = termios.tcgetattr(fd)
  14. old[3] = old[3] | termios.ECHO | termios.ICANON
  15. termios.tcsetattr(fd, termios.TCSADRAIN, old)
  16. def cbreaknoecho(fd):
  17. old = termios.tcgetattr(fd)
  18. old[3] = old[3] &~ termios.ECHO &~ termios.ICANON
  19. termios.tcsetattr(fd, termios.TCSADRAIN, old)
  20. if len(sys.argv) != 3:
  21. print("Incorrect parameters")
  22. sys.exit(1)
  23. pty = open(sys.argv[1], "w+b", 0)
  24. parent = int(sys.argv[2])
  25. # Don't buffer output by line endings
  26. sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
  27. sys.stdin = os.fdopen(sys.stdin.fileno(), 'r', 0)
  28. nonblockingfd(pty)
  29. nonblockingfd(sys.stdin)
  30. histfile = os.path.expanduser("~/.oedevpyshell-history")
  31. readline.parse_and_bind("tab: complete")
  32. try:
  33. readline.read_history_file(histfile)
  34. except IOError:
  35. pass
  36. try:
  37. i = ""
  38. o = ""
  39. # Need cbreak/noecho whilst in select so we trigger on any keypress
  40. cbreaknoecho(sys.stdin.fileno())
  41. # Send our PID to the other end so they can kill us.
  42. pty.write(str(os.getpid()) + "\n")
  43. while True:
  44. try:
  45. writers = []
  46. if i:
  47. writers.append(sys.stdout)
  48. (ready, _, _) = select.select([pty, sys.stdin], writers , [], 0)
  49. try:
  50. if pty in ready:
  51. i = i + pty.read()
  52. if i:
  53. # Write a page at a time to avoid overflowing output
  54. # d.keys() is a good way to do that
  55. sys.stdout.write(i[:4096])
  56. i = i[4096:]
  57. if sys.stdin in ready:
  58. echonocbreak(sys.stdin.fileno())
  59. o = raw_input()
  60. cbreaknoecho(sys.stdin.fileno())
  61. pty.write(o + "\n")
  62. except (IOError, OSError) as e:
  63. if e.errno == 11:
  64. continue
  65. if e.errno == 5:
  66. sys.exit(0)
  67. raise
  68. except EOFError:
  69. sys.exit(0)
  70. except KeyboardInterrupt:
  71. os.kill(parent, signal.SIGINT)
  72. except SystemExit:
  73. pass
  74. except Exception as e:
  75. import traceback
  76. print("Exception in oepydehshell-internal: " + str(e))
  77. traceback.print_exc()
  78. time.sleep(5)
  79. finally:
  80. readline.write_history_file(histfile)