summaryrefslogtreecommitdiff
path: root/pexpect
diff options
context:
space:
mode:
authornoah <noah@656d521f-e311-0410-88e0-e7920216d269>2006-02-17 23:49:54 +0000
committernoah <noah@656d521f-e311-0410-88e0-e7920216d269>2006-02-17 23:49:54 +0000
commit2b2ee76492ab2f4629fb691d5aeed22cf320736b (patch)
treee2d50ed2471db678cbcca6ce1b170cc04f715f59 /pexpect
parent060aca73f30303e9f5dcd8a76086f231e3732dca (diff)
downloadpexpect-2b2ee76492ab2f4629fb691d5aeed22cf320736b.tar.gz
Added some changes suggested by Nicolas Cesar.
Diffstat (limited to 'pexpect')
-rw-r--r--pexpect/fdpexpect.py23
-rw-r--r--pexpect/pexpect.py15
-rw-r--r--pexpect/pxssh.py56
3 files changed, 69 insertions, 25 deletions
diff --git a/pexpect/fdpexpect.py b/pexpect/fdpexpect.py
index 6dbaa26..b124836 100644
--- a/pexpect/fdpexpect.py
+++ b/pexpect/fdpexpect.py
@@ -3,25 +3,36 @@ already open file descriptor. For example, you could use it to
read through a file looking for patterns, or to control a modem or
serial device.
+TODO: This is BETA.
"""
-import pexpect
+from pexpect import *
-class fdspawn (pexpect.spawn):
+class fdspawn (spawn):
def __init__ (self, fd, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None):
"""This takes a file descriptor (an int) or an object that support the fileno() method
(returning an int). All Python file-like objects support fileno().
"""
### TODO: Add better handling of trying to use fdspawn in place of spawn
### TODO: (overload to allow fdspawn to also handle commands as spawn does.
- if type(fd) == type(''):
- return
- if type(fd)!=type(1) and hasattr(fd, 'fileno'):
+ if type(fd) != type(0) and hasattr(fd, 'fileno'):
fd = fd.fileno()
- pexpect.spawn.__init__(self, None, args, timeout, maxread, searchwindowsize, logfile)
+
+ if type(fd) != type(0):
+ raise ExceptionPexpect ('The fd argument is not an int. If this is a command string then maybe you want to use pexpect.spawn.')
+
+ try: # make sure fd is a valid file descriptor
+ os.fstat(command)
+ except OSError:
+ raise ExceptionPexpect, 'The fd argument is not a valid file descriptor.'
+
+ self.args = None
+ self.command = None
+ spawn.__init__(self, None, args, timeout, maxread, searchwindowsize, logfile)
self.child_fd = fd
self.own_fd = False
self.closed = False
+ self.name = '<file descriptor %d>' % fd
def __del__ (self):
return
diff --git a/pexpect/pexpect.py b/pexpect/pexpect.py
index ec3f1bc..d7c85fd 100644
--- a/pexpect/pexpect.py
+++ b/pexpect/pexpect.py
@@ -350,14 +350,19 @@ class spawn (object):
self.closed = True # File-like object.
self.__irix_hack = sys.platform.lower().find('irix') >= 0 # This flags if we are running on irix
- # allow dummy instances for subclasses that might not use command or args.
+ # allow dummy instances for subclasses that may not use command or args.
if command is None:
self.command = None
self.args = None
+ self.name = '<pexpect factory incomplete>'
return
-
+
+ # If command is an int type then it may represent a file descriptor.
+ if type(command) == type(0):
+ raise ExceptionPexpect ('Command is an int type. If this is a file descriptor then maybe you want to use fdpexpect.fdspawn which takes an existing file descriptor instead of a command string.')
+
if type (args) != type([]):
- raise TypeError ('The second argument, args, must be a list.')
+ raise TypeError ('The argument, args, must be a list.')
if args == []:
self.args = split_command_line(command)
@@ -1045,7 +1050,7 @@ class spawn (object):
raise
def getwinsize(self):
- """This returns the window size of the child tty.
+ """This returns the terminal window size of the child tty.
The return value is a tuple of (rows, cols).
"""
if 'TIOCGWINSZ' in dir(termios):
@@ -1057,7 +1062,7 @@ class spawn (object):
return struct.unpack('HHHH', x)[0:2]
def setwinsize(self, r, c):
- """This sets the window size of the child tty.
+ """This sets the terminal window size of the child tty.
This will cause a SIGWINCH signal to be sent to the child.
This does not change the physical window size.
It changes the size reported to TTY-aware applications like
diff --git a/pexpect/pxssh.py b/pexpect/pxssh.py
index 33e2e17..c30a596 100644
--- a/pexpect/pxssh.py
+++ b/pexpect/pxssh.py
@@ -11,6 +11,7 @@ TODO:
"""
from pexpect import *
import os, sys, getopt, shutil
+import signal, struct, fcntl, termios
from time import sleep
@@ -25,28 +26,41 @@ PROMPT = "\[PEXPECT\]\$ "
# backslash in front of $. The $ doesn't need to be escaped, but it doesn't
# hurt and serves to make the set command different than the regex.
+def handle_sigwinch(sig, data):
+ ### TODO:sospecho que entra en conflicto con newt
+ ### TODO:I suspect that it enters conflict with newt
+ # Check for buggy platforms (see pexpect.setwinsize()).
+ if 'TIOCGWINSZ' in dir(termios):
+ TIOCGWINSZ = termios.TIOCGWINSZ
+ else:
+ TIOCGWINSZ = 1074295912 # assume
+ s = struct.pack ("HHHH", 0, 0, 0, 0)
+ a = struct.unpack ('hhhh', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ , s))
+ setwinsize_all (a[0],a[1])
+ return True
+
+signal.signal(signal.SIGWINCH, handle_sigwinch)
+
+def setwinsize_all(a,b):
+ """This sets the terminal window size of all instances of pxssh.
+ """
+ for p in pxssh.instances:
+ p.setwinsize(a,b)
+
class pxssh (spawn):
"""This extends the spawn class to specialize for running 'ssh' command-line client.
This adds methods to login, logout, and expect_prompt.
"""
- def __init__(self):
+ instances = []
+ def __init__ (self):
self.PROMPT = "\[PEXPECT\]\$ "
- pass
- def logout(self):
- """This sends exit. If there are stopped jobs then this sends exit twice.
- """
- self.sendline("exit")
- index = self.expect([EOF, "(?i)there are stopped jobs"])
- if index==1:
- self.sendline("exit")
- self.expect(EOF)
# I need to draw a better flow chart for this.
- # This is getting messy and I'm pretty sure this isn't perfect.
- def login(self,server,username,password,terminal_type='ansi'):
+ ### TODO: This is getting messy and I'm pretty sure this isn't perfect.
+ def login (self,server,username,password,terminal_type='ansi'):
original_prompts = r"][#$]|~[#$]|bash.*?[#$]"
cmd = "ssh -l %s %s" % (username, server)
- self = spawn(cmd, timeout=300)
+ spawn.__init__(self, cmd, timeout=300)
#, "(?i)no route to host"])
i = self.expect(["(?i)are you sure you want to continue connecting", original_prompts, "(?i)password", "(?i)permission denied", "(?i)terminal type", TIMEOUT])
if i==0: # New certificate -- always accept it. This is what you if SSH does not have the remote host's public key stored in the cache.
@@ -64,7 +78,7 @@ class pxssh (spawn):
self.close()
return False
elif i==1: # can occur if you have a public key pair set to authenticate.
- ### May NOT be OK if expect false matched a prompt.
+ ### TODO: May NOT be OK if expect false matched a prompt.
pass
elif i==2: # password prompt again
# Some ssh servers will ask again for password, others print permission denied right away.
@@ -89,8 +103,22 @@ class pxssh (spawn):
if not self.set_unique_prompt():
self.close()
return False
+ pxssh.instances.append(self)
return True
+ def logout (self):
+ """This sends exit. If there are stopped jobs then this sends exit twice.
+ """
+ self.sendline("exit")
+ index = self.expect([EOF, "(?i)there are stopped jobs"])
+ if index==1:
+ self.sendline("exit")
+ self.expect(EOF)
+
+ def close (self):
+ pxssh.instances.remove(self)
+ return spawn.close(self)
+
def prompt (self):
"""This expects the prompt.
"""