diff options
| author | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2006-02-17 23:49:54 +0000 |
|---|---|---|
| committer | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2006-02-17 23:49:54 +0000 |
| commit | 2b2ee76492ab2f4629fb691d5aeed22cf320736b (patch) | |
| tree | e2d50ed2471db678cbcca6ce1b170cc04f715f59 /pexpect | |
| parent | 060aca73f30303e9f5dcd8a76086f231e3732dca (diff) | |
| download | pexpect-2b2ee76492ab2f4629fb691d5aeed22cf320736b.tar.gz | |
Added some changes suggested by Nicolas Cesar.
Diffstat (limited to 'pexpect')
| -rw-r--r-- | pexpect/fdpexpect.py | 23 | ||||
| -rw-r--r-- | pexpect/pexpect.py | 15 | ||||
| -rw-r--r-- | pexpect/pxssh.py | 56 |
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. """ |
