1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
import os, fcntl, termios
import time
def my_forkpty():
(master_fd, slave_fd) = os.openpty()
if (master_fd < 0 or slave_fd < 0):
raise ExceptionPexpect("Forkpty failed")
# slave_name = ptsname(master_fd);
pid = os.fork();
if pid == -1:
raise ExceptionPexpect("Forkpty failed")
elif pid == 0: # Child
if hasattr(termios, 'TIOCNOTTY'):
# Some platforms require an explicit detach of the
# current controlling tty before closing stdin, stdout, stderr.
# OpenBSD says that this is obsolete, but doesn't hurt.
try:
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
except:
pass
else: #if fd >= 0:
fcntl.ioctl(fd, termios.TIOCNOTTY, 0)
os.close(fd)
# The setsid() system call will place the process into its own session
# which has the effect of disassociating it from the controlling terminal.
# This is known to be true for OpenBSD.
os.setsid()
# except: return posix_error();
# Verify that we are disconnected from the controlling tty.
try:
fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY)
os.close(fd)
raise ExceptionPexpect("Forkpty failed")
except:
pass
if 'TIOCSCTTY' in dir(termios):
# Make the pseudo terminal the controlling terminal for this process
# (the process must not currently have a controlling terminal).
if fcntl.ioctl(slave_fd, termios.TIOCSCTTY, '') < 0:
raise ExceptionPexpect("Forkpty failed")
# # Verify that we can open to the slave pty file. */
# fd = os.open(slave_name, os.O_RDWR);
# if fd < 0:
# raise ExceptionPexpect("Forkpty failed")
# else:
# os.close(fd);
# Verify that we now have a controlling tty.
fd = os.open("/dev/tty", os.O_WRONLY)
if fd < 0:
raise ExceptionPexpect("This process could not get a controlling tty.")
else:
os.close(fd)
os.close(master_fd)
os.dup2(slave_fd, 0)
os.dup2(slave_fd, 1)
os.dup2(slave_fd, 2)
if slave_fd > 2:
os.close(slave_fd)
pid = 0
else:
# PARENT
os.close(slave_fd);
if pid == -1:
raise ExceptionPexpect("This process could not get a controlling tty.")
# if (pid == 0)
# PyOS_AfterFork();
return (pid, master_fd)
pid, fd = my_forkpty ()
if pid == 0: # child
print 'I am not a robot!'
else:
print '(pid, fd) = (%d, %d)' % (pid, fd)
time.sleep(1) # Give the child a chance to print.
print 'Robots always say:', os.read(fd,100)
os.close(fd)
|