home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / palmos / pippy-0.6beta-src.tar.gz / pippy-0.6beta-src.tar / pippy-0.6beta-src / src / Lib / pty.py < prev    next >
Text File  |  2000-12-21  |  3KB  |  109 lines

  1. """Pseudo terminal utilities."""
  2.  
  3. # Bugs: No signal handling.  Doesn't set slave termios and window size.
  4. #    Only tested on Linux.
  5. # See:  W. Richard Stevens. 1992.  Advanced Programming in the 
  6. #    UNIX Environment.  Chapter 19.
  7. # Author: Steen Lumholt -- with additions by Guido.
  8.  
  9. from select import select
  10. import os, FCNTL
  11. import tty
  12.  
  13. STDIN_FILENO = 0
  14. STDOUT_FILENO = 1
  15. STDERR_FILENO = 2
  16.  
  17. CHILD = 0
  18.  
  19. def master_open():
  20.     """Open pty master and return (master_fd, tty_name).
  21.     SGI and Linux/BSD version."""
  22.     try:
  23.         import sgi
  24.     except ImportError:
  25.         pass
  26.     else:
  27.         try:
  28.             tty_name, master_fd = sgi._getpty(FCNTL.O_RDWR, 0666, 0)
  29.         except IOError, msg:
  30.             raise os.error, msg
  31.         return master_fd, tty_name
  32.     for x in 'pqrstuvwxyzPQRST':
  33.         for y in '0123456789abcdef':
  34.             pty_name = '/dev/pty' + x + y
  35.             try:
  36.                 fd = os.open(pty_name, FCNTL.O_RDWR)
  37.             except os.error:
  38.                 continue
  39.             return (fd, '/dev/tty' + x + y)
  40.     raise os.error, 'out of pty devices'
  41.  
  42. def slave_open(tty_name):
  43.     """Open the pty slave and acquire the controlling terminal.
  44.     Return the file descriptor.  Linux version."""
  45.     # (Should be universal? --Guido)
  46.     return os.open(tty_name, FCNTL.O_RDWR)
  47.  
  48. def fork():
  49.     """Fork and make the child a session leader with a controlling terminal.
  50.     Return (pid, master_fd)."""
  51.     master_fd, tty_name = master_open() 
  52.     pid = os.fork()
  53.     if pid == CHILD:
  54.         # Establish a new session.
  55.         os.setsid()
  56.  
  57.         # Acquire controlling terminal.
  58.         slave_fd = slave_open(tty_name)
  59.         os.close(master_fd)
  60.  
  61.         # Slave becomes stdin/stdout/stderr of child.
  62.         os.dup2(slave_fd, STDIN_FILENO)
  63.         os.dup2(slave_fd, STDOUT_FILENO)
  64.         os.dup2(slave_fd, STDERR_FILENO)
  65.         if (slave_fd > STDERR_FILENO):
  66.             os.close (slave_fd)
  67.  
  68.     # Parent and child process.
  69.     return pid, master_fd
  70.  
  71. def writen(fd, data):
  72.     """Write all the data to a descriptor."""
  73.     while data != '':
  74.         n = os.write(fd, data)
  75.         data = data[n:]
  76.  
  77. def read(fd):
  78.     """Default read function."""
  79.     return os.read(fd, 1024)
  80.  
  81. def copy(master_fd, master_read=read, stdin_read=read):
  82.     """Parent copy loop.
  83.     Copies  
  84.           pty master -> standard output    (master_read)
  85.           standard input -> pty master    (stdin_read)"""
  86.     while 1:
  87.         rfds, wfds, xfds = select(
  88.             [master_fd, STDIN_FILENO], [], [])
  89.         if master_fd in rfds:
  90.             data = master_read(master_fd)
  91.             os.write(STDOUT_FILENO, data)
  92.         if STDIN_FILENO in rfds:
  93.             data = stdin_read(STDIN_FILENO)
  94.             writen(master_fd, data)
  95.  
  96. def spawn(argv, master_read=read, stdin_read=read):
  97.     """Create a spawned process."""
  98.     if type(argv) == type(''):
  99.         argv = (argv,)
  100.     pid, master_fd = fork()
  101.     if pid == CHILD:
  102.         apply(os.execlp, (argv[0],) + argv)
  103.     mode = tty.tcgetattr(STDIN_FILENO)
  104.     tty.setraw(STDIN_FILENO)
  105.     try:
  106.         copy(master_fd, master_read, stdin_read)
  107.     except:
  108.         tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)
  109.