diff options
author | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2007-12-19 03:00:33 +0000 |
---|---|---|
committer | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2007-12-19 03:00:33 +0000 |
commit | c0a3518dd5f0b7278972ac050f881e52415ba103 (patch) | |
tree | a1bb32ceb3d2241cd36f199812301127dae08bfe | |
parent | de5c6b824f3c1a4bcca3ee36db0fd16bfc7be77d (diff) | |
download | pexpect-c0a3518dd5f0b7278972ac050f881e52415ba103.tar.gz |
Adding waitnoecho and test functions.
git-svn-id: http://pexpect.svn.sourceforge.net/svnroot/pexpect/trunk@501 656d521f-e311-0410-88e0-e7920216d269
-rw-r--r-- | pexpect/README | 3 | ||||
-rw-r--r-- | pexpect/pexpect.py | 41 | ||||
-rwxr-xr-x | pexpect/tests/echo_wait.py | 19 | ||||
-rwxr-xr-x | pexpect/tests/test_expect.py | 13 |
4 files changed, 72 insertions, 4 deletions
diff --git a/pexpect/README b/pexpect/README index 98cd631..3101dc8 100644 --- a/pexpect/README +++ b/pexpect/README @@ -16,6 +16,9 @@ Python, Pexpect does not require TCL or Expect nor does it require C extensions to be compiled. It should work on any platform that supports the standard Python pty module. The Pexpect interface was designed to be easy to use. +If you want to work with the development version of the source code then please +read the DEVELOPERS document in the root of the source code tree. + Free, open source, and all that good stuff. Pexpect Copyright (c) 2008 Noah Spurrier diff --git a/pexpect/pexpect.py b/pexpect/pexpect.py index fbac205..cb4dd20 100644 --- a/pexpect/pexpect.py +++ b/pexpect/pexpect.py @@ -670,6 +670,40 @@ class spawn (object): return os.isatty(self.child_fd) + def waitnoecho (self, timeout=-1): + + """This waits until the terminal ECHO flag is set False. This returns + True if the echo mode is off. This returns False if the ECHO flag was + not set False before the timeout. This can be used to detect when the + child is waiting for a password. Usually a child application will turn + off echo mode when it is waiting for the user to enter a password. It + timeout is None then this method to block forever until ECHO flag is + False.""" + + if timeout == -1: + timeout = self.timeout + if timeout is not None: + end_time = time.time() + timeout + while True: + if not self.getecho(): + return True + if timeout < 0 and timeout is not None: + return False + if timeout is not None: + timeout = end_time - time.time() + time.sleep(0.1) + + def getecho (self): + + """This returns the terminal echo mode. This returns True if echo is + on or False if echo is off. Child applications that are expecting you + to enter a password often set ECHO False. See waitnoecho(). """ + + attr = termios.tcgetattr(self.child_fd) + if attr[3] & termios.ECHO: + return True + return False + def setecho (self, state): """This sets the terminal echo mode on or off. Note that anything the @@ -702,11 +736,11 @@ class spawn (object): """ self.child_fd - new = termios.tcgetattr(self.child_fd) + attr = termios.tcgetattr(self.child_fd) if state: - new[3] = new[3] | termios.ECHO + attr[3] = attr[3] | termios.ECHO else: - new[3] = new[3] & ~termios.ECHO + attr[3] = attr[3] & ~termios.ECHO # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent # and blocked on some platforms. TCSADRAIN is probably ideal if it worked. termios.tcsetattr(self.child_fd, termios.TCSANOW, new) @@ -1778,4 +1812,3 @@ def split_command_line(command_line): return arg_list # vi:ts=4:sw=4:expandtab:ft=python: - diff --git a/pexpect/tests/echo_wait.py b/pexpect/tests/echo_wait.py new file mode 100755 index 0000000..2d27991 --- /dev/null +++ b/pexpect/tests/echo_wait.py @@ -0,0 +1,19 @@ +import signal, time, struct, fcntl, termios, os, sys + +# a dumb PAM will print the password prompt first then set ECHO +# False. What it should do it set ECHO False first then print the +# prompt. Otherwise, if we see the password prompt and type out +# password real fast before it turns off ECHO then some or all of +# our password might be visibly echod back to us. Sounds unlikely? +# It happens. + +print "fake password:" +sys.stdout.flush() +attr = termios.tcgetattr(sys.stdout) +attr[3] = attr[3] & ~termios.ECHO +termios.tcsetattr(sys.stdout, termios.TCSANOW, new) +time.sleep(3) +attr[3] = attr[3] | termios.ECHO +termios.tcsetattr(sys.stdout, termios.TCSANOW, new) + +time.sleep(20) diff --git a/pexpect/tests/test_expect.py b/pexpect/tests/test_expect.py index 3afef87..3929192 100755 --- a/pexpect/tests/test_expect.py +++ b/pexpect/tests/test_expect.py @@ -109,6 +109,19 @@ class ExpectTestCase (PexpectTestCase.PexpectTestCase): index = p.expect ([pexpect.EOF,'abcd','wxyz','7890']) assert index == 3, "index="+str(index) + def test_waitnoecho (self): + + """ This tests that we can wait on a child process to set echo mode. + For example, this tests that we could wait for SSH to set ECHO False + when asking of a password. This makes use of an external script + echo_wait.py. """ + + p1 = pexpect.spawn('%s echo_wait.py' % self.PYTHONBIN) + start = time.time() + p1.waitnoecho(timeout=10) + end_time = time.time() - start + assert end_time < 10 and end_time > 2, "waitnoecho did not set ECHO off in the expected time window" + def test_expect_echo (self): """This tests that echo can be turned on and off. """ |