"""Pseudo terminal utilities."""

# Bugs: No signal handling.  Doesn't set slave termios and window size.
#	Only tested on Linux.
# See:  W. Richard Stevens. 1992.  Advanced Programming in the 
#	UNIX Environment.  Chapter 19.
# Author: Steen Lumholt -- with additions by Guido.

from select import select
import os, FCNTL
import tty

STDIN_FILENO = 0
STDOUT_FILENO = 1
STDERR_FILENO = 2

CHILD = 0

def openpty():
	"""openpty() -> (master_fd, slave_fd)
	Open a pty master/slave pair, using os.openpty() if possible."""

	try:
		return os.openpty()
	except (AttributeError, OSError):
		pass
	master_fd, slave_name = _open_terminal()
	slave_fd = slave_open(slave_name)
	return master_fd, slave_fd

def master_open():
	"""master_open() -> (master_fd, slave_name)
	Open a pty master and return the fd, and the filename of the slave end.
	Deprecated, use openpty() instead."""

	try:
		master_fd, slave_fd = os.openpty()
	except (AttributeError, OSError):
		pass
	else:
		slave_name = os.ttyname(slave_fd)
		os.close(slave_fd)
		return master_fd, slave_name

	return _open_terminal()

def _open_terminal():
	"""Open pty master and return (master_fd, tty_name).
	SGI and generic BSD version, for when openpty() fails."""
	try:
		import sgi
	except ImportError:
		pass
	else:
		try:
		    tty_name, master_fd = sgi._getpty(FCNTL.O_RDWR, 0666, 0)
		except IOError, msg:
			raise os.error, msg
		return master_fd, tty_name
	for x in 'pqrstuvwxyzPQRST':
		for y in '0123456789abcdef':
			pty_name = '/dev/pty' + x + y
			try:
				fd = os.open(pty_name, FCNTL.O_RDWR)
			except os.error:
				continue
			return (fd, '/dev/tty' + x + y)
	raise os.error, 'out of pty devices'

def slave_open(tty_name):
	"""slave_open(tty_name) -> slave_fd
	Open the pty slave and acquire the controlling terminal, returning
	opened filedescriptor.
	Deprecated, use openpty() instead."""

	return os.open(tty_name, FCNTL.O_RDWR)

def fork():
	"""fork() -> (pid, master_fd)
	Fork and make the child a session leader with a controlling terminal."""

	try:
		pid, fd = os.forkpty()
	except (AttributeError, OSError):
		pass
	else:
		if pid == CHILD:
			try:
				os.setsid()
			except OSError:
				# os.forkpty() already set us session leader
				pass
		return pid, fd

	master_fd, slave_fd = openpty() 
	pid = os.fork()
	if pid == CHILD:
		# Establish a new session.
		os.setsid()
		os.close(master_fd)

		# Slave becomes stdin/stdout/stderr of child.
		os.dup2(slave_fd, STDIN_FILENO)
		os.dup2(slave_fd, STDOUT_FILENO)
		os.dup2(slave_fd, STDERR_FILENO)
		if (slave_fd > STDERR_FILENO):
			os.close (slave_fd)

	# Parent and child process.
	return pid, master_fd

def _writen(fd, data):
	"""Write all the data to a descriptor."""
	while data != '':
		n = os.write(fd, data)
		data = data[n:]

def _read(fd):
	"""Default read function."""
	return os.read(fd, 1024)

def _copy(master_fd, master_read=_read, stdin_read=_read):
	"""Parent copy loop.
	Copies  
	  	pty master -> standard output	(master_read)
	  	standard input -> pty master	(stdin_read)"""
	while 1:
		rfds, wfds, xfds = select(
			[master_fd, STDIN_FILENO], [], [])
		if master_fd in rfds:
			data = master_read(master_fd)
			os.write(STDOUT_FILENO, data)
		if STDIN_FILENO in rfds:
			data = stdin_read(STDIN_FILENO)
			_writen(master_fd, data)

def spawn(argv, master_read=_read, stdin_read=_read):
	"""Create a spawned process."""
	if type(argv) == type(''):
		argv = (argv,)
	pid, master_fd = fork()
	if pid == CHILD:
		apply(os.execlp, (argv[0],) + argv)
	mode = tty.tcgetattr(STDIN_FILENO)
	tty.setraw(STDIN_FILENO)
	try:
		_copy(master_fd, master_read, stdin_read)
	except:
		tty.tcsetattr(STDIN_FILENO, tty.TCSAFLUSH, mode)
