diff options
author | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2003-05-05 02:41:41 +0000 |
---|---|---|
committer | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2003-05-05 02:41:41 +0000 |
commit | f3b04f3717b9cf542aa9f865b913654c37e316d0 (patch) | |
tree | 51e838c6c1c2d793d4b21cb26fcfb45c24d7f6e7 | |
parent | e4990e5b075107a8a7d05abcbb198439235d5e27 (diff) | |
download | pexpect-f3b04f3717b9cf542aa9f865b913654c37e316d0.tar.gz |
This is an experimental replacement for pty.fork (which is stupid).
git-svn-id: http://pexpect.svn.sourceforge.net/svnroot/pexpect/trunk@189 656d521f-e311-0410-88e0-e7920216d269
-rw-r--r-- | pexpect/my_forkpty.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/pexpect/my_forkpty.py b/pexpect/my_forkpty.py new file mode 100644 index 0000000..a1c6b37 --- /dev/null +++ b/pexpect/my_forkpty.py @@ -0,0 +1,89 @@ +import os, fcntl, termios, struct +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 'TIOCNOTTY' in dir(termios): + # /* 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. */ + fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) + if fd >= 0: + s = struct.pack("H", 0) + fcntl.ioctl(fd, termios.TIOCNOTTY, s); + 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). + s = struct.pack("H", 0) + if fcntl.ioctl(slave_fd, termios.TIOCSCTTY, s) < 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) + |