| 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) |
| |