diff options
| author | Noah Spurrier <noah@squaretrade.com> | 2012-10-26 11:19:10 -0700 |
|---|---|---|
| committer | Noah Spurrier <noah@squaretrade.com> | 2012-10-26 11:19:10 -0700 |
| commit | 7999ca657997e78febfb3fb89cfcc066d50bf788 (patch) | |
| tree | 7ff33465bb4f8f79b92add505d11d4b731dfe6a7 /notes | |
| parent | 6b65a76c26d72caf0a5b11725750861bf89f2b75 (diff) | |
| download | pexpect-7999ca657997e78febfb3fb89cfcc066d50bf788.tar.gz | |
Moved everything up one directory level.
Diffstat (limited to 'notes')
| -rw-r--r-- | notes/my_forkpty.py | 89 | ||||
| -rw-r--r-- | notes/notes.txt | 50 | ||||
| -rw-r--r-- | notes/posixmodule.c.diff | 233 |
3 files changed, 372 insertions, 0 deletions
diff --git a/notes/my_forkpty.py b/notes/my_forkpty.py new file mode 100644 index 0000000..f2bef23 --- /dev/null +++ b/notes/my_forkpty.py @@ -0,0 +1,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) + diff --git a/notes/notes.txt b/notes/notes.txt new file mode 100644 index 0000000..a793587 --- /dev/null +++ b/notes/notes.txt @@ -0,0 +1,50 @@ + +#################### +# +# NOTES +# +#################### + +## def send_human(self, text, delay_min = 0, delay_max = 1): +## pass +## def spawn2(self, command, args): +## """return pid, fd_stdio, fd_stderr +## """ +## pass + + +# Reason for double fork: +# http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC15 +# Reason for ptys: +# http://www.erlenstar.demon.co.uk/unix/faq_4.html#SEC52 + +# Nonblocking on Win32? +# Reasearch this as a way to maybe make pipe work for Win32. +# http://groups.google.com/groups?q=setraw+tty&hl=en&selm=uvgpvisvk.fsf%40roundpoint.com&rnum=7 +# +# if istty: +# if os.name=='posix': +# import tty +# tty.setraw(sys.stdin.fileno()) +# elif os.name=='nt': +# import win32file, win32con +# hstdin = win32file._get_osfhandle(sys.stdin.fileno()) +# modes = (win32file.GetConsoleMode(hstdin) +# & ~(win32con.ENABLE_LINE_INPUT +# |win32con.ENABLE_ECHO_INPUT)) +# win32file.SetConsoleMode(hstdin, modes) + +# Basic documentation: +# Explain use of lists of patterns and return index. +# Explain exceptions for non-handled special cases like EOF + +# Test bad fork +# Test ENOENT. In other words, no more TTY devices. + +#GLOBAL_SIGCHLD_RECEIVED = 0 +#def childdied (signum, frame): +# print 'Signal handler called with signal', signum +# frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED = 1 +# print str(frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED) +# GLOBAL_SIGCHLD_RECEIVED = 1 + diff --git a/notes/posixmodule.c.diff b/notes/posixmodule.c.diff new file mode 100644 index 0000000..3bea1f9 --- /dev/null +++ b/notes/posixmodule.c.diff @@ -0,0 +1,233 @@ +*** Python-2.2.1.orig/Modules/posixmodule.c Tue Mar 12 16:38:31 2002 +--- Python-2.2.1/Modules/posixmodule.c Tue May 21 01:16:29 2002 +*************** +*** 1904,1910 **** + } + #endif + +! #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) + #ifdef HAVE_PTY_H + #include <pty.h> + #else +--- 1904,1913 ---- + } + #endif + +! #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(sun) +! #ifdef sun +! #include <sys/stropts.h> +! #endif + #ifdef HAVE_PTY_H + #include <pty.h> + #else +*************** +*** 1914,1920 **** + #endif /* HAVE_PTY_H */ + #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ + +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) + static char posix_openpty__doc__[] = + "openpty() -> (master_fd, slave_fd)\n\ + Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; +--- 1917,1923 ---- + #endif /* HAVE_PTY_H */ + #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ + +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(sun) + static char posix_openpty__doc__[] = + "openpty() -> (master_fd, slave_fd)\n\ + Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; +*************** +*** 1925,1932 **** + int master_fd, slave_fd; + #ifndef HAVE_OPENPTY + char * slave_name; + #endif +! + if (!PyArg_ParseTuple(args, ":openpty")) + return NULL; + +--- 1928,1941 ---- + int master_fd, slave_fd; + #ifndef HAVE_OPENPTY + char * slave_name; ++ #ifdef sun ++ void *sig_saved; + #endif +! #endif +! #if !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) && defined(sun) +! extern char *ptsname(); +! #endif +! + if (!PyArg_ParseTuple(args, ":openpty")) + return NULL; + +*************** +*** 1933,1939 **** + #ifdef HAVE_OPENPTY + if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) + return posix_error(); +! #else + slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); + if (slave_name == NULL) + return posix_error(); +--- 1942,1948 ---- + #ifdef HAVE_OPENPTY + if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) + return posix_error(); +! #elif HAVE__GETPTY + slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); + if (slave_name == NULL) + return posix_error(); +*************** +*** 1941,1946 **** +--- 1950,1966 ---- + slave_fd = open(slave_name, O_RDWR); + if (slave_fd < 0) + return posix_error(); ++ #else ++ master_fd = open("/dev/ptmx", O_RDWR|O_NOCTTY); /* open master */ ++ sig_saved = signal(SIGCHLD, SIG_DFL); ++ grantpt(master_fd); /* change permission of slave */ ++ unlockpt(master_fd); /* unlock slave */ ++ signal(SIGCHLD,sig_saved); ++ slave_name = ptsname(master_fd); /* get name of slave */ ++ slave_fd = open(slave_name, O_RDWR); /* open slave */ ++ ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ ++ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm*/ ++ ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat*/ + #endif /* HAVE_OPENPTY */ + + return Py_BuildValue("(ii)", master_fd, slave_fd); +*************** +*** 1948,1954 **** + } + #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ + +! #ifdef HAVE_FORKPTY + static char posix_forkpty__doc__[] = + "forkpty() -> (pid, master_fd)\n\ + Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ +--- 1968,1974 ---- + } + #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ + +! #if defined(HAVE_FORKPTY) || defined(sun) + static char posix_forkpty__doc__[] = + "forkpty() -> (pid, master_fd)\n\ + Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ +*************** +*** 1959,1968 **** +--- 1979,2067 ---- + posix_forkpty(PyObject *self, PyObject *args) + { + int master_fd, pid; ++ #if defined(sun) ++ int slave; ++ char * slave_name; ++ void *sig_saved; ++ int fd; ++ #endif + + if (!PyArg_ParseTuple(args, ":forkpty")) + return NULL; ++ #if defined(sun) ++ master_fd = open("/dev/ptmx", O_RDWR|O_NOCTTY); /* open master */ ++ sig_saved = signal(SIGCHLD, SIG_DFL); ++ grantpt(master_fd); /* change permission of slave */ ++ unlockpt(master_fd); /* unlock slave */ ++ signal(SIGCHLD,sig_saved); ++ slave_name = ptsname(master_fd); /* get name of slave */ ++ slave = open(slave_name, O_RDWR); /* open slave */ ++ ioctl(slave, I_PUSH, "ptem"); /* push ptem */ ++ ioctl(slave, I_PUSH, "ldterm"); /* push ldterm*/ ++ ioctl(slave, I_PUSH, "ttcompat"); /* push ttcompat*/ ++ if (master_fd < 0 || slave < 0) ++ { ++ return posix_error(); ++ } ++ switch (pid = fork()) { ++ case -1: ++ return posix_error(); ++ case 0: ++ /* First disconnect from the old controlling tty. */ ++ #ifdef TIOCNOTTY ++ fd = open("/dev/tty", O_RDWR | O_NOCTTY); ++ if (fd >= 0) { ++ (void) ioctl(fd, TIOCNOTTY, NULL); ++ close(fd); ++ } ++ #endif /* TIOCNOTTY */ ++ if (setsid() < 0) ++ return posix_error(); ++ ++ /* ++ * Verify that we are successfully disconnected from the controlling ++ * tty. ++ */ ++ fd = open("/dev/tty", O_RDWR | O_NOCTTY); ++ if (fd >= 0) { ++ return posix_error(); ++ close(fd); ++ } ++ /* Make it our controlling tty. */ ++ #ifdef TIOCSCTTY ++ if (ioctl(slave, TIOCSCTTY, NULL) < 0) ++ return posix_error(); ++ #endif /* TIOCSCTTY */ ++ fd = open(slave_name, O_RDWR); ++ if (fd < 0) { ++ return posix_error(); ++ } else { ++ close(fd); ++ } ++ /* Verify that we now have a controlling tty. */ ++ fd = open("/dev/tty", O_WRONLY); ++ if (fd < 0) ++ return posix_error(); ++ else { ++ close(fd); ++ } ++ (void) close(master_fd); ++ (void) dup2(slave, 0); ++ (void) dup2(slave, 1); ++ (void) dup2(slave, 2); ++ if (slave > 2) ++ (void) close(slave); ++ pid = 0; ++ break; ++ defautlt: ++ /* ++ * parent ++ */ ++ (void) close(slave); ++ } ++ #else + pid = forkpty(&master_fd, NULL, NULL, NULL); ++ #endif + if (pid == -1) + return posix_error(); + if (pid == 0) +*************** +*** 5607,5616 **** + #ifdef HAVE_FORK + {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, + #endif /* HAVE_FORK */ +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) + {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, + #endif /* HAVE_OPENPTY || HAVE__GETPTY */ +! #ifdef HAVE_FORKPTY + {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, + #endif /* HAVE_FORKPTY */ + #ifdef HAVE_GETEGID +--- 5706,5715 ---- + #ifdef HAVE_FORK + {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, + #endif /* HAVE_FORK */ +! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(sun) + {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, + #endif /* HAVE_OPENPTY || HAVE__GETPTY */ +! #if defined(HAVE_FORKPTY) || defined(sun) + {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, + #endif /* HAVE_FORKPTY */ + #ifdef HAVE_GETEGID |
