Merge lp:~mterry/duplicity/nopexpect into lp:duplicity/0.6
- nopexpect
- Merge into 0.6-series
Proposed by
Michael Terry
Status: | Merged |
---|---|
Merged at revision: | 830 |
Proposed branch: | lp:~mterry/duplicity/nopexpect |
Merge into: | lp:duplicity/0.6 |
Diff against target: |
1849 lines (+0/-1845) 1 file modified
duplicity/pexpect.py (+0/-1845) |
To merge this branch: | bzr merge lp:~mterry/duplicity/nopexpect |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
duplicity-team | Pending | ||
Review via email: mp+91925@code.launchpad.net |
Commit message
Description of the change
Just a simple branch that drops the now-unused local copy of pexpect.py. (The ssh backend now uses paramiko) Unless you plan to use pexpect again, this should be harmless and a nice drop in lines of code.
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === removed file 'duplicity/pexpect.py' |
2 | --- duplicity/pexpect.py 2011-06-17 06:21:42 +0000 |
3 | +++ duplicity/pexpect.py 1970-01-01 00:00:00 +0000 |
4 | @@ -1,1845 +0,0 @@ |
5 | -"""Pexpect is a Python module for spawning child applications and controlling |
6 | -them automatically. Pexpect can be used for automating interactive applications |
7 | -such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup |
8 | -scripts for duplicating software package installations on different servers. It |
9 | -can be used for automated software testing. Pexpect is in the spirit of Don |
10 | -Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python |
11 | -require TCL and Expect or require C extensions to be compiled. Pexpect does not |
12 | -use C, Expect, or TCL extensions. It should work on any platform that supports |
13 | -the standard Python pty module. The Pexpect interface focuses on ease of use so |
14 | -that simple tasks are easy. |
15 | - |
16 | -There are two main interfaces to Pexpect -- the function, run() and the class, |
17 | -spawn. You can call the run() function to execute a command and return the |
18 | -output. This is a handy replacement for os.system(). |
19 | - |
20 | -For example:: |
21 | - |
22 | - pexpect.run('ls -la') |
23 | - |
24 | -The more powerful interface is the spawn class. You can use this to spawn an |
25 | -external child command and then interact with the child by sending lines and |
26 | -expecting responses. |
27 | - |
28 | -For example:: |
29 | - |
30 | - child = pexpect.spawn('scp foo myname@host.example.com:.') |
31 | - child.expect ('Password:') |
32 | - child.sendline (mypassword) |
33 | - |
34 | -This works even for commands that ask for passwords or other input outside of |
35 | -the normal stdio streams. |
36 | - |
37 | -Credits: Noah Spurrier, Richard Holden, Marco Molteni, Kimberley Burchett, |
38 | -Robert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids |
39 | -vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin, |
40 | -Geoffrey Marshall, Francisco Lourenco, Glen Mabey, Karthik Gurusamy, Fernando |
41 | -Perez, Corey Minyard, Jon Cohen, Guillaume Chazarain, Andrew Ryan, Nick |
42 | -Craig-Wood, Andrew Stone, Jorgen Grahn (Let me know if I forgot anyone.) |
43 | - |
44 | -Free, open source, and all that good stuff. |
45 | - |
46 | -Permission is hereby granted, free of charge, to any person obtaining a copy of |
47 | -this software and associated documentation files (the "Software"), to deal in |
48 | -the Software without restriction, including without limitation the rights to |
49 | -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies |
50 | -of the Software, and to permit persons to whom the Software is furnished to do |
51 | -so, subject to the following conditions: |
52 | - |
53 | -The above copyright notice and this permission notice shall be included in all |
54 | -copies or substantial portions of the Software. |
55 | - |
56 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
57 | -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
58 | -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
59 | -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
60 | -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
61 | -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
62 | -SOFTWARE. |
63 | - |
64 | -Pexpect Copyright (c) 2008 Noah Spurrier |
65 | -http://pexpect.sourceforge.net/ |
66 | - |
67 | -$Id: pexpect.py,v 1.1 2009/01/06 22:11:37 loafman Exp $ |
68 | -""" |
69 | - |
70 | -try: |
71 | - import os, sys, time |
72 | - import select |
73 | - import string |
74 | - import re |
75 | - import struct |
76 | - import resource |
77 | - import types |
78 | - import pty |
79 | - import tty |
80 | - import termios |
81 | - import fcntl |
82 | - import errno |
83 | - import traceback |
84 | - import signal |
85 | -except ImportError, e: |
86 | - raise ImportError (str(e) + """ |
87 | - |
88 | -A critical module was not found. Probably this operating system does not |
89 | -support it. Pexpect is intended for UNIX-like operating systems.""") |
90 | - |
91 | -__version__ = '2.3' |
92 | -__revision__ = '$Revision: 1.1 $' |
93 | -__all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'run', 'which', |
94 | - 'split_command_line', '__version__', '__revision__'] |
95 | - |
96 | -# Exception classes used by this module. |
97 | -class ExceptionPexpect(Exception): |
98 | - |
99 | - """Base class for all exceptions raised by this module. |
100 | - """ |
101 | - |
102 | - def __init__(self, value): |
103 | - |
104 | - self.value = value |
105 | - |
106 | - def __str__(self): |
107 | - |
108 | - return str(self.value) |
109 | - |
110 | - def get_trace(self): |
111 | - |
112 | - """This returns an abbreviated stack trace with lines that only concern |
113 | - the caller. In other words, the stack trace inside the Pexpect module |
114 | - is not included. """ |
115 | - |
116 | - tblist = traceback.extract_tb(sys.exc_info()[2]) |
117 | - #tblist = filter(self.__filter_not_pexpect, tblist) |
118 | - tblist = [item for item in tblist if self.__filter_not_pexpect(item)] |
119 | - tblist = traceback.format_list(tblist) |
120 | - return ''.join(tblist) |
121 | - |
122 | - def __filter_not_pexpect(self, trace_list_item): |
123 | - |
124 | - """This returns True if list item 0 the string 'pexpect.py' in it. """ |
125 | - |
126 | - if trace_list_item[0].find('pexpect.py') == -1: |
127 | - return True |
128 | - else: |
129 | - return False |
130 | - |
131 | -class EOF(ExceptionPexpect): |
132 | - |
133 | - """Raised when EOF is read from a child. This usually means the child has exited.""" |
134 | - |
135 | -class TIMEOUT(ExceptionPexpect): |
136 | - |
137 | - """Raised when a read time exceeds the timeout. """ |
138 | - |
139 | -##class TIMEOUT_PATTERN(TIMEOUT): |
140 | -## """Raised when the pattern match time exceeds the timeout. |
141 | -## This is different than a read TIMEOUT because the child process may |
142 | -## give output, thus never give a TIMEOUT, but the output |
143 | -## may never match a pattern. |
144 | -## """ |
145 | -##class MAXBUFFER(ExceptionPexpect): |
146 | -## """Raised when a scan buffer fills before matching an expected pattern.""" |
147 | - |
148 | -def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None): |
149 | - |
150 | - """ |
151 | - This function runs the given command; waits for it to finish; then |
152 | - returns all output as a string. STDERR is included in output. If the full |
153 | - path to the command is not given then the path is searched. |
154 | - |
155 | - Note that lines are terminated by CR/LF (\\r\\n) combination even on |
156 | - UNIX-like systems because this is the standard for pseudo ttys. If you set |
157 | - 'withexitstatus' to true, then run will return a tuple of (command_output, |
158 | - exitstatus). If 'withexitstatus' is false then this returns just |
159 | - command_output. |
160 | - |
161 | - The run() function can often be used instead of creating a spawn instance. |
162 | - For example, the following code uses spawn:: |
163 | - |
164 | - from pexpect import * #@UnusedWildImport |
165 | - child = spawn('scp foo myname@host.example.com:.') |
166 | - child.expect ('(?i)password') |
167 | - child.sendline (mypassword) |
168 | - |
169 | - The previous code can be replace with the following:: |
170 | - |
171 | - from pexpect import * #@UnusedWildImport |
172 | - run ('scp foo myname@host.example.com:.', events={'(?i)password': mypassword}) |
173 | - |
174 | - Examples |
175 | - ======== |
176 | - |
177 | - Start the apache daemon on the local machine:: |
178 | - |
179 | - from pexpect import * #@UnusedWildImport |
180 | - run ("/usr/local/apache/bin/apachectl start") |
181 | - |
182 | - Check in a file using SVN:: |
183 | - |
184 | - from pexpect import * #@UnusedWildImport |
185 | - run ("svn ci -m 'automatic commit' my_file.py") |
186 | - |
187 | - Run a command and capture exit status:: |
188 | - |
189 | - from pexpect import * #@UnusedWildImport |
190 | - (command_output, exitstatus) = run ('ls -l /bin', withexitstatus=1) |
191 | - |
192 | - Tricky Examples |
193 | - =============== |
194 | - |
195 | - The following will run SSH and execute 'ls -l' on the remote machine. The |
196 | - password 'secret' will be sent if the '(?i)password' pattern is ever seen:: |
197 | - |
198 | - run ("ssh username@machine.example.com 'ls -l'", events={'(?i)password':'secret\\n'}) |
199 | - |
200 | - This will start mencoder to rip a video from DVD. This will also display |
201 | - progress ticks every 5 seconds as it runs. For example:: |
202 | - |
203 | - from pexpect import * #@UnusedWildImport |
204 | - def print_ticks(d): |
205 | - print d['event_count'], |
206 | - run ("mencoder dvd://1 -o video.avi -oac copy -ovc copy", events={TIMEOUT:print_ticks}, timeout=5) |
207 | - |
208 | - The 'events' argument should be a dictionary of patterns and responses. |
209 | - Whenever one of the patterns is seen in the command out run() will send the |
210 | - associated response string. Note that you should put newlines in your |
211 | - string if Enter is necessary. The responses may also contain callback |
212 | - functions. Any callback is function that takes a dictionary as an argument. |
213 | - The dictionary contains all the locals from the run() function, so you can |
214 | - access the child spawn object or any other variable defined in run() |
215 | - (event_count, child, and extra_args are the most useful). A callback may |
216 | - return True to stop the current run process otherwise run() continues until |
217 | - the next event. A callback may also return a string which will be sent to |
218 | - the child. 'extra_args' is not used by directly run(). It provides a way to |
219 | - pass data to a callback function through run() through the locals |
220 | - dictionary passed to a callback. """ |
221 | - |
222 | - if timeout == -1: |
223 | - child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env) |
224 | - else: |
225 | - child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, cwd=cwd, env=env) |
226 | - if events is not None: |
227 | - patterns = events.keys() |
228 | - responses = events.values() |
229 | - else: |
230 | - patterns=None # We assume that EOF or TIMEOUT will save us. |
231 | - responses=None |
232 | - child_result_list = [] |
233 | - event_count = 0 |
234 | - while 1: |
235 | - try: |
236 | - index = child.expect (patterns) |
237 | - if type(child.after) in types.StringTypes: |
238 | - child_result_list.append(child.before + child.after) |
239 | - else: # child.after may have been a TIMEOUT or EOF, so don't cat those. |
240 | - child_result_list.append(child.before) |
241 | - if type(responses[index]) in types.StringTypes: |
242 | - child.send(responses[index]) |
243 | - elif type(responses[index]) is types.FunctionType: |
244 | - callback_result = responses[index](locals()) |
245 | - sys.stdout.flush() |
246 | - if type(callback_result) in types.StringTypes: |
247 | - child.send(callback_result) |
248 | - elif callback_result: |
249 | - break |
250 | - else: |
251 | - raise TypeError ('The callback must be a string or function type.') |
252 | - event_count = event_count + 1 |
253 | - except TIMEOUT, e: |
254 | - child_result_list.append(child.before) |
255 | - break |
256 | - except EOF, e: |
257 | - child_result_list.append(child.before) |
258 | - break |
259 | - child_result = ''.join(child_result_list) |
260 | - if withexitstatus: |
261 | - child.close() |
262 | - return (child_result, child.exitstatus) |
263 | - else: |
264 | - return child_result |
265 | - |
266 | -class spawn (object): |
267 | - |
268 | - """This is the main class interface for Pexpect. Use this class to start |
269 | - and control child applications. """ |
270 | - |
271 | - def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None): |
272 | - |
273 | - """This is the constructor. The command parameter may be a string that |
274 | - includes a command and any arguments to the command. For example:: |
275 | - |
276 | - child = pexpect.spawn ('/usr/bin/ftp') |
277 | - child = pexpect.spawn ('/usr/bin/ssh user@example.com') |
278 | - child = pexpect.spawn ('ls -latr /tmp') |
279 | - |
280 | - You may also construct it with a list of arguments like so:: |
281 | - |
282 | - child = pexpect.spawn ('/usr/bin/ftp', []) |
283 | - child = pexpect.spawn ('/usr/bin/ssh', ['user@example.com']) |
284 | - child = pexpect.spawn ('ls', ['-latr', '/tmp']) |
285 | - |
286 | - After this the child application will be created and will be ready to |
287 | - talk to. For normal use, see expect() and send() and sendline(). |
288 | - |
289 | - Remember that Pexpect does NOT interpret shell meta characters such as |
290 | - redirect, pipe, or wild cards (>, |, or *). This is a common mistake. |
291 | - If you want to run a command and pipe it through another command then |
292 | - you must also start a shell. For example:: |
293 | - |
294 | - child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > log_list.txt"') |
295 | - child.expect(pexpect.EOF) |
296 | - |
297 | - The second form of spawn (where you pass a list of arguments) is useful |
298 | - in situations where you wish to spawn a command and pass it its own |
299 | - argument list. This can make syntax more clear. For example, the |
300 | - following is equivalent to the previous example:: |
301 | - |
302 | - shell_cmd = 'ls -l | grep LOG > log_list.txt' |
303 | - child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]) |
304 | - child.expect(pexpect.EOF) |
305 | - |
306 | - The maxread attribute sets the read buffer size. This is maximum number |
307 | - of bytes that Pexpect will try to read from a TTY at one time. Setting |
308 | - the maxread size to 1 will turn off buffering. Setting the maxread |
309 | - value higher may help performance in cases where large amounts of |
310 | - output are read back from the child. This feature is useful in |
311 | - conjunction with searchwindowsize. |
312 | - |
313 | - The searchwindowsize attribute sets the how far back in the incomming |
314 | - seach buffer Pexpect will search for pattern matches. Every time |
315 | - Pexpect reads some data from the child it will append the data to the |
316 | - incomming buffer. The default is to search from the beginning of the |
317 | - imcomming buffer each time new data is read from the child. But this is |
318 | - very inefficient if you are running a command that generates a large |
319 | - amount of data where you want to match The searchwindowsize does not |
320 | - effect the size of the incomming data buffer. You will still have |
321 | - access to the full buffer after expect() returns. |
322 | - |
323 | - The logfile member turns on or off logging. All input and output will |
324 | - be copied to the given file object. Set logfile to None to stop |
325 | - logging. This is the default. Set logfile to sys.stdout to echo |
326 | - everything to standard output. The logfile is flushed after each write. |
327 | - |
328 | - Example log input and output to a file:: |
329 | - |
330 | - child = pexpect.spawn('some_command') |
331 | - fout = file('mylog.txt','w') |
332 | - child.logfile = fout |
333 | - |
334 | - Example log to stdout:: |
335 | - |
336 | - child = pexpect.spawn('some_command') |
337 | - child.logfile = sys.stdout |
338 | - |
339 | - The logfile_read and logfile_send members can be used to separately log |
340 | - the input from the child and output sent to the child. Sometimes you |
341 | - don't want to see everything you write to the child. You only want to |
342 | - log what the child sends back. For example:: |
343 | - |
344 | - child = pexpect.spawn('some_command') |
345 | - child.logfile_read = sys.stdout |
346 | - |
347 | - To separately log output sent to the child use logfile_send:: |
348 | - |
349 | - self.logfile_send = fout |
350 | - |
351 | - The delaybeforesend helps overcome a weird behavior that many users |
352 | - were experiencing. The typical problem was that a user would expect() a |
353 | - "Password:" prompt and then immediately call sendline() to send the |
354 | - password. The user would then see that their password was echoed back |
355 | - to them. Passwords don't normally echo. The problem is caused by the |
356 | - fact that most applications print out the "Password" prompt and then |
357 | - turn off stdin echo, but if you send your password before the |
358 | - application turned off echo, then you get your password echoed. |
359 | - Normally this wouldn't be a problem when interacting with a human at a |
360 | - real keyboard. If you introduce a slight delay just before writing then |
361 | - this seems to clear up the problem. This was such a common problem for |
362 | - many users that I decided that the default pexpect behavior should be |
363 | - to sleep just before writing to the child application. 1/20th of a |
364 | - second (50 ms) seems to be enough to clear up the problem. You can set |
365 | - delaybeforesend to 0 to return to the old behavior. Most Linux machines |
366 | - don't like this to be below 0.03. I don't know why. |
367 | - |
368 | - Note that spawn is clever about finding commands on your path. |
369 | - It uses the same logic that "which" uses to find executables. |
370 | - |
371 | - If you wish to get the exit status of the child you must call the |
372 | - close() method. The exit or signal status of the child will be stored |
373 | - in self.exitstatus or self.signalstatus. If the child exited normally |
374 | - then exitstatus will store the exit return code and signalstatus will |
375 | - be None. If the child was terminated abnormally with a signal then |
376 | - signalstatus will store the signal value and exitstatus will be None. |
377 | - If you need more detail you can also read the self.status member which |
378 | - stores the status returned by os.waitpid. You can interpret this using |
379 | - os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. """ |
380 | - |
381 | - self.STDIN_FILENO = pty.STDIN_FILENO |
382 | - self.STDOUT_FILENO = pty.STDOUT_FILENO |
383 | - self.STDERR_FILENO = pty.STDERR_FILENO |
384 | - self.stdin = sys.stdin |
385 | - self.stdout = sys.stdout |
386 | - self.stderr = sys.stderr |
387 | - |
388 | - self.searcher = None |
389 | - self.ignorecase = False |
390 | - self.before = None |
391 | - self.after = None |
392 | - self.match = None |
393 | - self.match_index = None |
394 | - self.terminated = True |
395 | - self.exitstatus = None |
396 | - self.signalstatus = None |
397 | - self.status = None # status returned by os.waitpid |
398 | - self.flag_eof = False |
399 | - self.pid = None |
400 | - self.child_fd = -1 # initially closed |
401 | - self.timeout = timeout |
402 | - self.delimiter = EOF |
403 | - self.logfile = logfile |
404 | - self.logfile_read = None # input from child (read_nonblocking) |
405 | - self.logfile_send = None # output to send (send, sendline) |
406 | - self.maxread = maxread # max bytes to read at one time into buffer |
407 | - self.buffer = '' # This is the read buffer. See maxread. |
408 | - self.searchwindowsize = searchwindowsize # Anything before searchwindowsize point is preserved, but not searched. |
409 | - # Most Linux machines don't like delaybeforesend to be below 0.03 (30 ms). |
410 | - self.delaybeforesend = 0.05 # Sets sleep time used just before sending data to child. Time in seconds. |
411 | - self.delayafterclose = 0.1 # Sets delay in close() method to allow kernel time to update process status. Time in seconds. |
412 | - self.delayafterterminate = 0.1 # Sets delay in terminate() method to allow kernel time to update process status. Time in seconds. |
413 | - self.softspace = False # File-like object. |
414 | - self.name = '<' + repr(self) + '>' # File-like object. |
415 | - self.encoding = None # File-like object. |
416 | - self.closed = True # File-like object. |
417 | - self.cwd = cwd |
418 | - self.env = env |
419 | - self.__irix_hack = (sys.platform.lower().find('irix')>=0) # This flags if we are running on irix |
420 | - # Solaris uses internal __fork_pty(). All others use pty.fork(). |
421 | - if (sys.platform.lower().find('solaris')>=0) or (sys.platform.lower().find('sunos5')>=0): |
422 | - self.use_native_pty_fork = False |
423 | - else: |
424 | - self.use_native_pty_fork = True |
425 | - |
426 | - |
427 | - # allow dummy instances for subclasses that may not use command or args. |
428 | - if command is None: |
429 | - self.command = None |
430 | - self.args = None |
431 | - self.name = '<pexpect factory incomplete>' |
432 | - else: |
433 | - self._spawn (command, args) |
434 | - |
435 | - def __del__(self): |
436 | - |
437 | - """This makes sure that no system resources are left open. Python only |
438 | - garbage collects Python objects. OS file descriptors are not Python |
439 | - objects, so they must be handled explicitly. If the child file |
440 | - descriptor was opened outside of this class (passed to the constructor) |
441 | - then this does not close it. """ |
442 | - |
443 | - if not self.closed: |
444 | - # It is possible for __del__ methods to execute during the |
445 | - # teardown of the Python VM itself. Thus self.close() may |
446 | - # trigger an exception because os.close may be None. |
447 | - # -- Fernando Perez |
448 | - try: |
449 | - self.close() |
450 | - except AttributeError: |
451 | - pass |
452 | - |
453 | - def __str__(self): |
454 | - |
455 | - """This returns a human-readable string that represents the state of |
456 | - the object. """ |
457 | - |
458 | - s = [] |
459 | - s.append(repr(self)) |
460 | - s.append('version: ' + __version__ + ' (' + __revision__ + ')') |
461 | - s.append('command: ' + str(self.command)) |
462 | - s.append('args: ' + str(self.args)) |
463 | - s.append('searcher: ' + str(self.searcher)) |
464 | - s.append('buffer (last 100 chars): ' + str(self.buffer)[-100:]) |
465 | - s.append('before (last 100 chars): ' + str(self.before)[-100:]) |
466 | - s.append('after: ' + str(self.after)) |
467 | - s.append('match: ' + str(self.match)) |
468 | - s.append('match_index: ' + str(self.match_index)) |
469 | - s.append('exitstatus: ' + str(self.exitstatus)) |
470 | - s.append('flag_eof: ' + str(self.flag_eof)) |
471 | - s.append('pid: ' + str(self.pid)) |
472 | - s.append('child_fd: ' + str(self.child_fd)) |
473 | - s.append('closed: ' + str(self.closed)) |
474 | - s.append('timeout: ' + str(self.timeout)) |
475 | - s.append('delimiter: ' + str(self.delimiter)) |
476 | - s.append('logfile: ' + str(self.logfile)) |
477 | - s.append('logfile_read: ' + str(self.logfile_read)) |
478 | - s.append('logfile_send: ' + str(self.logfile_send)) |
479 | - s.append('maxread: ' + str(self.maxread)) |
480 | - s.append('ignorecase: ' + str(self.ignorecase)) |
481 | - s.append('searchwindowsize: ' + str(self.searchwindowsize)) |
482 | - s.append('delaybeforesend: ' + str(self.delaybeforesend)) |
483 | - s.append('delayafterclose: ' + str(self.delayafterclose)) |
484 | - s.append('delayafterterminate: ' + str(self.delayafterterminate)) |
485 | - return '\n'.join(s) |
486 | - |
487 | - def _spawn(self,command,args=[]): |
488 | - |
489 | - """This starts the given command in a child process. This does all the |
490 | - fork/exec type of stuff for a pty. This is called by __init__. If args |
491 | - is empty then command will be parsed (split on spaces) and args will be |
492 | - set to parsed arguments. """ |
493 | - |
494 | - # The pid and child_fd of this object get set by this method. |
495 | - # Note that it is difficult for this method to fail. |
496 | - # You cannot detect if the child process cannot start. |
497 | - # So the only way you can tell if the child process started |
498 | - # or not is to try to read from the file descriptor. If you get |
499 | - # EOF immediately then it means that the child is already dead. |
500 | - # That may not necessarily be bad because you may haved spawned a child |
501 | - # that performs some task; creates no stdout output; and then dies. |
502 | - |
503 | - # If command is an int type then it may represent a file descriptor. |
504 | - if type(command) == type(0): |
505 | - 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.') |
506 | - |
507 | - if type (args) != type([]): |
508 | - raise TypeError ('The argument, args, must be a list.') |
509 | - |
510 | - if args == []: |
511 | - self.args = split_command_line(command) |
512 | - self.command = self.args[0] |
513 | - else: |
514 | - self.args = args[:] # work with a copy |
515 | - self.args.insert (0, command) |
516 | - self.command = command |
517 | - |
518 | - command_with_path = which(self.command) |
519 | - if command_with_path is None: |
520 | - raise ExceptionPexpect ('The command was not found or was not executable: %s.' % self.command) |
521 | - self.command = command_with_path |
522 | - self.args[0] = self.command |
523 | - |
524 | - self.name = '<' + ' '.join (self.args) + '>' |
525 | - |
526 | - assert self.pid is None, 'The pid member should be None.' |
527 | - assert self.command is not None, 'The command member should not be None.' |
528 | - |
529 | - if self.use_native_pty_fork: |
530 | - try: |
531 | - self.pid, self.child_fd = pty.fork() |
532 | - except OSError, e: |
533 | - raise ExceptionPexpect('Error! pty.fork() failed: ' + str(e)) |
534 | - else: # Use internal __fork_pty |
535 | - self.pid, self.child_fd = self.__fork_pty() |
536 | - |
537 | - if self.pid == 0: # Child |
538 | - try: |
539 | - self.child_fd = sys.stdout.fileno() # used by setwinsize() |
540 | - self.setwinsize(24, 80) |
541 | - except Exception: |
542 | - # Some platforms do not like setwinsize (Cygwin). |
543 | - # This will cause problem when running applications that |
544 | - # are very picky about window size. |
545 | - # This is a serious limitation, but not a show stopper. |
546 | - pass |
547 | - # Do not allow child to inherit open file descriptors from parent. |
548 | - max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] |
549 | - for i in range (3, max_fd): |
550 | - try: |
551 | - os.close (i) |
552 | - except OSError: |
553 | - pass |
554 | - |
555 | - # I don't know why this works, but ignoring SIGHUP fixes a |
556 | - # problem when trying to start a Java daemon with sudo |
557 | - # (specifically, Tomcat). |
558 | - signal.signal(signal.SIGHUP, signal.SIG_IGN) |
559 | - |
560 | - if self.cwd is not None: |
561 | - os.chdir(self.cwd) |
562 | - if self.env is None: |
563 | - os.execv(self.command, self.args) |
564 | - else: |
565 | - os.execvpe(self.command, self.args, self.env) |
566 | - |
567 | - # Parent |
568 | - self.terminated = False |
569 | - self.closed = False |
570 | - |
571 | - def __fork_pty(self): |
572 | - |
573 | - """This implements a substitute for the forkpty system call. This |
574 | - should be more portable than the pty.fork() function. Specifically, |
575 | - this should work on Solaris. |
576 | - |
577 | - Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to |
578 | - resolve the issue with Python's pty.fork() not supporting Solaris, |
579 | - particularly ssh. Based on patch to posixmodule.c authored by Noah |
580 | - Spurrier:: |
581 | - |
582 | - http://mail.python.org/pipermail/python-dev/2003-May/035281.html |
583 | - |
584 | - """ |
585 | - |
586 | - parent_fd, child_fd = os.openpty() |
587 | - if parent_fd < 0 or child_fd < 0: |
588 | - raise ExceptionPexpect, "Error! Could not open pty with os.openpty()." |
589 | - |
590 | - pid = os.fork() |
591 | - if pid < 0: |
592 | - raise ExceptionPexpect, "Error! Failed os.fork()." |
593 | - elif pid == 0: |
594 | - # Child. |
595 | - os.close(parent_fd) |
596 | - self.__pty_make_controlling_tty(child_fd) |
597 | - |
598 | - os.dup2(child_fd, 0) |
599 | - os.dup2(child_fd, 1) |
600 | - os.dup2(child_fd, 2) |
601 | - |
602 | - if child_fd > 2: |
603 | - os.close(child_fd) |
604 | - else: |
605 | - # Parent. |
606 | - os.close(child_fd) |
607 | - |
608 | - return pid, parent_fd |
609 | - |
610 | - def __pty_make_controlling_tty(self, tty_fd): |
611 | - |
612 | - """This makes the pseudo-terminal the controlling tty. This should be |
613 | - more portable than the pty.fork() function. Specifically, this should |
614 | - work on Solaris. """ |
615 | - |
616 | - child_name = os.ttyname(tty_fd) |
617 | - |
618 | - # Disconnect from controlling tty if still connected. |
619 | - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); |
620 | - if fd >= 0: |
621 | - os.close(fd) |
622 | - |
623 | - os.setsid() |
624 | - |
625 | - # Verify we are disconnected from controlling tty |
626 | - try: |
627 | - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); |
628 | - if fd >= 0: |
629 | - os.close(fd) |
630 | - raise ExceptionPexpect, "Error! We are not disconnected from a controlling tty." |
631 | - except Exception: |
632 | - # Good! We are disconnected from a controlling tty. |
633 | - pass |
634 | - |
635 | - # Verify we can open child pty. |
636 | - fd = os.open(child_name, os.O_RDWR); |
637 | - if fd < 0: |
638 | - raise ExceptionPexpect, "Error! Could not open child pty, " + child_name |
639 | - else: |
640 | - os.close(fd) |
641 | - |
642 | - # Verify we now have a controlling tty. |
643 | - fd = os.open("/dev/tty", os.O_WRONLY) |
644 | - if fd < 0: |
645 | - raise ExceptionPexpect, "Error! Could not open controlling tty, /dev/tty" |
646 | - else: |
647 | - os.close(fd) |
648 | - |
649 | - def fileno (self): # File-like object. |
650 | - |
651 | - """This returns the file descriptor of the pty for the child. |
652 | - """ |
653 | - |
654 | - return self.child_fd |
655 | - |
656 | - def close (self, force=True): # File-like object. |
657 | - |
658 | - """This closes the connection with the child application. Note that |
659 | - calling close() more than once is valid. This emulates standard Python |
660 | - behavior with files. Set force to True if you want to make sure that |
661 | - the child is terminated (SIGKILL is sent if the child ignores SIGHUP |
662 | - and SIGINT). """ |
663 | - |
664 | - if not self.closed: |
665 | - self.flush() |
666 | - os.close (self.child_fd) |
667 | - time.sleep(self.delayafterclose) # Give kernel time to update process status. |
668 | - if self.isalive(): |
669 | - if not self.terminate(force): |
670 | - raise ExceptionPexpect ('close() could not terminate the child using terminate()') |
671 | - self.child_fd = -1 |
672 | - self.closed = True |
673 | - #self.pid = None |
674 | - |
675 | - def flush (self): # File-like object. |
676 | - |
677 | - """This does nothing. It is here to support the interface for a |
678 | - File-like object. """ |
679 | - |
680 | - pass |
681 | - |
682 | - def isatty (self): # File-like object. |
683 | - |
684 | - """This returns True if the file descriptor is open and connected to a |
685 | - tty(-like) device, else False. """ |
686 | - |
687 | - return os.isatty(self.child_fd) |
688 | - |
689 | - def waitnoecho (self, timeout=-1): |
690 | - |
691 | - """This waits until the terminal ECHO flag is set False. This returns |
692 | - True if the echo mode is off. This returns False if the ECHO flag was |
693 | - not set False before the timeout. This can be used to detect when the |
694 | - child is waiting for a password. Usually a child application will turn |
695 | - off echo mode when it is waiting for the user to enter a password. For |
696 | - example, instead of expecting the "password:" prompt you can wait for |
697 | - the child to set ECHO off:: |
698 | - |
699 | - p = pexpect.spawn ('ssh user@example.com') |
700 | - p.waitnoecho() |
701 | - p.sendline(mypassword) |
702 | - |
703 | - If timeout is None then this method to block forever until ECHO flag is |
704 | - False. |
705 | - |
706 | - """ |
707 | - |
708 | - if timeout == -1: |
709 | - timeout = self.timeout |
710 | - if timeout is not None: |
711 | - end_time = time.time() + timeout |
712 | - while True: |
713 | - if not self.getecho(): |
714 | - return True |
715 | - if timeout < 0 and timeout is not None: |
716 | - return False |
717 | - if timeout is not None: |
718 | - timeout = end_time - time.time() |
719 | - time.sleep(0.1) |
720 | - |
721 | - def getecho (self): |
722 | - |
723 | - """This returns the terminal echo mode. This returns True if echo is |
724 | - on or False if echo is off. Child applications that are expecting you |
725 | - to enter a password often set ECHO False. See waitnoecho(). """ |
726 | - |
727 | - attr = termios.tcgetattr(self.child_fd) |
728 | - if attr[3] & termios.ECHO: |
729 | - return True |
730 | - return False |
731 | - |
732 | - def setecho (self, state): |
733 | - |
734 | - """This sets the terminal echo mode on or off. Note that anything the |
735 | - child sent before the echo will be lost, so you should be sure that |
736 | - your input buffer is empty before you call setecho(). For example, the |
737 | - following will work as expected:: |
738 | - |
739 | - p = pexpect.spawn('cat') |
740 | - p.sendline ('1234') # We will see this twice (once from tty echo and again from cat). |
741 | - p.expect (['1234']) |
742 | - p.expect (['1234']) |
743 | - p.setecho(False) # Turn off tty echo |
744 | - p.sendline ('abcd') # We will set this only once (echoed by cat). |
745 | - p.sendline ('wxyz') # We will set this only once (echoed by cat) |
746 | - p.expect (['abcd']) |
747 | - p.expect (['wxyz']) |
748 | - |
749 | - The following WILL NOT WORK because the lines sent before the setecho |
750 | - will be lost:: |
751 | - |
752 | - p = pexpect.spawn('cat') |
753 | - p.sendline ('1234') # We will see this twice (once from tty echo and again from cat). |
754 | - p.setecho(False) # Turn off tty echo |
755 | - p.sendline ('abcd') # We will set this only once (echoed by cat). |
756 | - p.sendline ('wxyz') # We will set this only once (echoed by cat) |
757 | - p.expect (['1234']) |
758 | - p.expect (['1234']) |
759 | - p.expect (['abcd']) |
760 | - p.expect (['wxyz']) |
761 | - """ |
762 | - |
763 | - self.child_fd |
764 | - attr = termios.tcgetattr(self.child_fd) |
765 | - if state: |
766 | - attr[3] = attr[3] | termios.ECHO |
767 | - else: |
768 | - attr[3] = attr[3] & ~termios.ECHO |
769 | - # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent |
770 | - # and blocked on some platforms. TCSADRAIN is probably ideal if it worked. |
771 | - termios.tcsetattr(self.child_fd, termios.TCSANOW, attr) |
772 | - |
773 | - def read_nonblocking (self, size = 1, timeout = -1): |
774 | - |
775 | - """This reads at most size characters from the child application. It |
776 | - includes a timeout. If the read does not complete within the timeout |
777 | - period then a TIMEOUT exception is raised. If the end of file is read |
778 | - then an EOF exception will be raised. If a log file was set using |
779 | - setlog() then all data will also be written to the log file. |
780 | - |
781 | - If timeout is None then the read may block indefinitely. If timeout is -1 |
782 | - then the self.timeout value is used. If timeout is 0 then the child is |
783 | - polled and if there was no data immediately ready then this will raise |
784 | - a TIMEOUT exception. |
785 | - |
786 | - The timeout refers only to the amount of time to read at least one |
787 | - character. This is not effected by the 'size' parameter, so if you call |
788 | - read_nonblocking(size=100, timeout=30) and only one character is |
789 | - available right away then one character will be returned immediately. |
790 | - It will not wait for 30 seconds for another 99 characters to come in. |
791 | - |
792 | - This is a wrapper around os.read(). It uses select.select() to |
793 | - implement the timeout. """ |
794 | - |
795 | - if self.closed: |
796 | - raise ValueError ('I/O operation on closed file in read_nonblocking().') |
797 | - |
798 | - if timeout == -1: |
799 | - timeout = self.timeout |
800 | - |
801 | - # Note that some systems such as Solaris do not give an EOF when |
802 | - # the child dies. In fact, you can still try to read |
803 | - # from the child_fd -- it will block forever or until TIMEOUT. |
804 | - # For this case, I test isalive() before doing any reading. |
805 | - # If isalive() is false, then I pretend that this is the same as EOF. |
806 | - if not self.isalive(): |
807 | - r,w,e = self.__select([self.child_fd], [], [], 0) # timeout of 0 means "poll" @UnusedVariable |
808 | - if not r: |
809 | - self.flag_eof = True |
810 | - raise EOF ('End Of File (EOF) in read_nonblocking(). Braindead platform.') |
811 | - elif self.__irix_hack: |
812 | - # This is a hack for Irix. It seems that Irix requires a long delay before checking isalive. |
813 | - # This adds a 2 second delay, but only when the child is terminated. |
814 | - r, w, e = self.__select([self.child_fd], [], [], 2) #@UnusedVariable |
815 | - if not r and not self.isalive(): |
816 | - self.flag_eof = True |
817 | - raise EOF ('End Of File (EOF) in read_nonblocking(). Pokey platform.') |
818 | - |
819 | - r,w,e = self.__select([self.child_fd], [], [], timeout) #@UnusedVariable |
820 | - |
821 | - if not r: |
822 | - if not self.isalive(): |
823 | - # Some platforms, such as Irix, will claim that their processes are alive; |
824 | - # then timeout on the select; and then finally admit that they are not alive. |
825 | - self.flag_eof = True |
826 | - raise EOF ('End of File (EOF) in read_nonblocking(). Very pokey platform.') |
827 | - else: |
828 | - raise TIMEOUT ('Timeout exceeded in read_nonblocking().') |
829 | - |
830 | - if self.child_fd in r: |
831 | - try: |
832 | - s = os.read(self.child_fd, size) |
833 | - except OSError, e: # Linux does this |
834 | - self.flag_eof = True |
835 | - raise EOF ('End Of File (EOF) in read_nonblocking(). Exception style platform.') |
836 | - if s == '': # BSD style |
837 | - self.flag_eof = True |
838 | - raise EOF ('End Of File (EOF) in read_nonblocking(). Empty string style platform.') |
839 | - |
840 | - if self.logfile is not None: |
841 | - self.logfile.write (s) |
842 | - self.logfile.flush() |
843 | - if self.logfile_read is not None: |
844 | - self.logfile_read.write (s) |
845 | - self.logfile_read.flush() |
846 | - |
847 | - return s |
848 | - |
849 | - raise ExceptionPexpect ('Reached an unexpected state in read_nonblocking().') |
850 | - |
851 | - def read (self, size = -1): # File-like object. |
852 | - |
853 | - """This reads at most "size" bytes from the file (less if the read hits |
854 | - EOF before obtaining size bytes). If the size argument is negative or |
855 | - omitted, read all data until EOF is reached. The bytes are returned as |
856 | - a string object. An empty string is returned when EOF is encountered |
857 | - immediately. """ |
858 | - |
859 | - if size == 0: |
860 | - return '' |
861 | - if size < 0: |
862 | - self.expect (self.delimiter) # delimiter default is EOF |
863 | - return self.before |
864 | - |
865 | - # I could have done this more directly by not using expect(), but |
866 | - # I deliberately decided to couple read() to expect() so that |
867 | - # I would catch any bugs early and ensure consistant behavior. |
868 | - # It's a little less efficient, but there is less for me to |
869 | - # worry about if I have to later modify read() or expect(). |
870 | - # Note, it's OK if size==-1 in the regex. That just means it |
871 | - # will never match anything in which case we stop only on EOF. |
872 | - cre = re.compile('.{%d}' % size, re.DOTALL) |
873 | - index = self.expect ([cre, self.delimiter]) # delimiter default is EOF |
874 | - if index == 0: |
875 | - return self.after ### self.before should be ''. Should I assert this? |
876 | - return self.before |
877 | - |
878 | - def readline (self, size = -1): # File-like object. |
879 | - |
880 | - """This reads and returns one entire line. A trailing newline is kept |
881 | - in the string, but may be absent when a file ends with an incomplete |
882 | - line. Note: This readline() looks for a \\r\\n pair even on UNIX |
883 | - because this is what the pseudo tty device returns. So contrary to what |
884 | - you may expect you will receive the newline as \\r\\n. An empty string |
885 | - is returned when EOF is hit immediately. Currently, the size argument is |
886 | - mostly ignored, so this behavior is not standard for a file-like |
887 | - object. If size is 0 then an empty string is returned. """ |
888 | - |
889 | - if size == 0: |
890 | - return '' |
891 | - index = self.expect (['\r\n', self.delimiter]) # delimiter default is EOF |
892 | - if index == 0: |
893 | - return self.before + '\r\n' |
894 | - else: |
895 | - return self.before |
896 | - |
897 | - def __iter__ (self): # File-like object. |
898 | - |
899 | - """This is to support iterators over a file-like object. |
900 | - """ |
901 | - |
902 | - return self |
903 | - |
904 | - def next (self): # File-like object. |
905 | - |
906 | - """This is to support iterators over a file-like object. |
907 | - """ |
908 | - |
909 | - result = self.readline() |
910 | - if result == "": |
911 | - raise StopIteration |
912 | - return result |
913 | - |
914 | - def readlines (self, sizehint = -1): # File-like object. |
915 | - |
916 | - """This reads until EOF using readline() and returns a list containing |
917 | - the lines thus read. The optional "sizehint" argument is ignored. """ |
918 | - |
919 | - lines = [] |
920 | - while True: |
921 | - line = self.readline() |
922 | - if not line: |
923 | - break |
924 | - lines.append(line) |
925 | - return lines |
926 | - |
927 | - def write(self, s): # File-like object. |
928 | - |
929 | - """This is similar to send() except that there is no return value. |
930 | - """ |
931 | - |
932 | - self.send (s) |
933 | - |
934 | - def writelines (self, sequence): # File-like object. |
935 | - |
936 | - """This calls write() for each element in the sequence. The sequence |
937 | - can be any iterable object producing strings, typically a list of |
938 | - strings. This does not add line separators There is no return value. |
939 | - """ |
940 | - |
941 | - for s in sequence: |
942 | - self.write (s) |
943 | - |
944 | - def send(self, s): |
945 | - |
946 | - """This sends a string to the child process. This returns the number of |
947 | - bytes written. If a log file was set then the data is also written to |
948 | - the log. """ |
949 | - |
950 | - time.sleep(self.delaybeforesend) |
951 | - if self.logfile is not None: |
952 | - self.logfile.write (s) |
953 | - self.logfile.flush() |
954 | - if self.logfile_send is not None: |
955 | - self.logfile_send.write (s) |
956 | - self.logfile_send.flush() |
957 | - c = os.write(self.child_fd, s) |
958 | - return c |
959 | - |
960 | - def sendline(self, s=''): |
961 | - |
962 | - """This is like send(), but it adds a line feed (os.linesep). This |
963 | - returns the number of bytes written. """ |
964 | - |
965 | - n = self.send(s) |
966 | - n = n + self.send (os.linesep) |
967 | - return n |
968 | - |
969 | - def sendcontrol(self, char): |
970 | - |
971 | - """This sends a control character to the child such as Ctrl-C or |
972 | - Ctrl-D. For example, to send a Ctrl-G (ASCII 7):: |
973 | - |
974 | - child.sendcontrol('g') |
975 | - |
976 | - See also, sendintr() and sendeof(). |
977 | - """ |
978 | - |
979 | - char = char.lower() |
980 | - a = ord(char) |
981 | - if a>=97 and a<=122: |
982 | - a = a - ord('a') + 1 |
983 | - return self.send (chr(a)) |
984 | - d = {'@':0, '`':0, |
985 | - '[':27, '{':27, |
986 | - '\\':28, '|':28, |
987 | - ']':29, '}': 29, |
988 | - '^':30, '~':30, |
989 | - '_':31, |
990 | - '?':127} |
991 | - if char not in d: |
992 | - return 0 |
993 | - return self.send (chr(d[char])) |
994 | - |
995 | - def sendeof(self): |
996 | - |
997 | - """This sends an EOF to the child. This sends a character which causes |
998 | - the pending parent output buffer to be sent to the waiting child |
999 | - program without waiting for end-of-line. If it is the first character |
1000 | - of the line, the read() in the user program returns 0, which signifies |
1001 | - end-of-file. This means to work as expected a sendeof() has to be |
1002 | - called at the beginning of a line. This method does not send a newline. |
1003 | - It is the responsibility of the caller to ensure the eof is sent at the |
1004 | - beginning of a line. """ |
1005 | - |
1006 | - ### Hmmm... how do I send an EOF? |
1007 | - ###C if ((m = write(pty, *buf, p - *buf)) < 0) |
1008 | - ###C return (errno == EWOULDBLOCK) ? n : -1; |
1009 | - #fd = sys.stdin.fileno() |
1010 | - #old = termios.tcgetattr(fd) # remember current state |
1011 | - #attr = termios.tcgetattr(fd) |
1012 | - #attr[3] = attr[3] | termios.ICANON # ICANON must be set to recognize EOF |
1013 | - #try: # use try/finally to ensure state gets restored |
1014 | - # termios.tcsetattr(fd, termios.TCSADRAIN, attr) |
1015 | - # if hasattr(termios, 'CEOF'): |
1016 | - # os.write (self.child_fd, '%c' % termios.CEOF) |
1017 | - # else: |
1018 | - # # Silly platform does not define CEOF so assume CTRL-D |
1019 | - # os.write (self.child_fd, '%c' % 4) |
1020 | - #finally: # restore state |
1021 | - # termios.tcsetattr(fd, termios.TCSADRAIN, old) |
1022 | - if hasattr(termios, 'VEOF'): |
1023 | - char = termios.tcgetattr(self.child_fd)[6][termios.VEOF] |
1024 | - else: |
1025 | - # platform does not define VEOF so assume CTRL-D |
1026 | - char = chr(4) |
1027 | - self.send(char) |
1028 | - |
1029 | - def sendintr(self): |
1030 | - |
1031 | - """This sends a SIGINT to the child. It does not require |
1032 | - the SIGINT to be the first character on a line. """ |
1033 | - |
1034 | - if hasattr(termios, 'VINTR'): |
1035 | - char = termios.tcgetattr(self.child_fd)[6][termios.VINTR] |
1036 | - else: |
1037 | - # platform does not define VINTR so assume CTRL-C |
1038 | - char = chr(3) |
1039 | - self.send (char) |
1040 | - |
1041 | - def eof (self): |
1042 | - |
1043 | - """This returns True if the EOF exception was ever raised. |
1044 | - """ |
1045 | - |
1046 | - return self.flag_eof |
1047 | - |
1048 | - def terminate(self, force=False): |
1049 | - |
1050 | - """This forces a child process to terminate. It starts nicely with |
1051 | - SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This |
1052 | - returns True if the child was terminated. This returns False if the |
1053 | - child could not be terminated. """ |
1054 | - |
1055 | - if not self.isalive(): |
1056 | - return True |
1057 | - try: |
1058 | - self.kill(signal.SIGHUP) |
1059 | - time.sleep(self.delayafterterminate) |
1060 | - if not self.isalive(): |
1061 | - return True |
1062 | - self.kill(signal.SIGCONT) |
1063 | - time.sleep(self.delayafterterminate) |
1064 | - if not self.isalive(): |
1065 | - return True |
1066 | - self.kill(signal.SIGINT) |
1067 | - time.sleep(self.delayafterterminate) |
1068 | - if not self.isalive(): |
1069 | - return True |
1070 | - if force: |
1071 | - self.kill(signal.SIGKILL) |
1072 | - time.sleep(self.delayafterterminate) |
1073 | - if not self.isalive(): |
1074 | - return True |
1075 | - else: |
1076 | - return False |
1077 | - return False |
1078 | - except OSError, e: |
1079 | - # I think there are kernel timing issues that sometimes cause |
1080 | - # this to happen. I think isalive() reports True, but the |
1081 | - # process is dead to the kernel. |
1082 | - # Make one last attempt to see if the kernel is up to date. |
1083 | - time.sleep(self.delayafterterminate) |
1084 | - if not self.isalive(): |
1085 | - return True |
1086 | - else: |
1087 | - return False |
1088 | - |
1089 | - def wait(self): |
1090 | - |
1091 | - """This waits until the child exits. This is a blocking call. This will |
1092 | - not read any data from the child, so this will block forever if the |
1093 | - child has unread output and has terminated. In other words, the child |
1094 | - may have printed output then called exit(); but, technically, the child |
1095 | - is still alive until its output is read. """ |
1096 | - |
1097 | - if self.isalive(): |
1098 | - pid, status = os.waitpid(self.pid, 0) #@UnusedVariable |
1099 | - else: |
1100 | - raise ExceptionPexpect ('Cannot wait for dead child process.') |
1101 | - self.exitstatus = os.WEXITSTATUS(status) |
1102 | - if os.WIFEXITED (status): |
1103 | - self.status = status |
1104 | - self.exitstatus = os.WEXITSTATUS(status) |
1105 | - self.signalstatus = None |
1106 | - self.terminated = True |
1107 | - elif os.WIFSIGNALED (status): |
1108 | - self.status = status |
1109 | - self.exitstatus = None |
1110 | - self.signalstatus = os.WTERMSIG(status) |
1111 | - self.terminated = True |
1112 | - elif os.WIFSTOPPED (status): |
1113 | - raise ExceptionPexpect ('Wait was called for a child process that is stopped. This is not supported. Is some other process attempting job control with our child pid?') |
1114 | - return self.exitstatus |
1115 | - |
1116 | - def isalive(self): |
1117 | - |
1118 | - """This tests if the child process is running or not. This is |
1119 | - non-blocking. If the child was terminated then this will read the |
1120 | - exitstatus or signalstatus of the child. This returns True if the child |
1121 | - process appears to be running or False if not. It can take literally |
1122 | - SECONDS for Solaris to return the right status. """ |
1123 | - |
1124 | - if self.terminated: |
1125 | - return False |
1126 | - |
1127 | - if self.flag_eof: |
1128 | - # This is for Linux, which requires the blocking form of waitpid to get |
1129 | - # status of a defunct process. This is super-lame. The flag_eof would have |
1130 | - # been set in read_nonblocking(), so this should be safe. |
1131 | - waitpid_options = 0 |
1132 | - else: |
1133 | - waitpid_options = os.WNOHANG |
1134 | - |
1135 | - try: |
1136 | - pid, status = os.waitpid(self.pid, waitpid_options) |
1137 | - except OSError, e: # No child processes |
1138 | - if e[0] == errno.ECHILD: |
1139 | - raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?') |
1140 | - else: |
1141 | - raise e |
1142 | - |
1143 | - # I have to do this twice for Solaris. I can't even believe that I figured this out... |
1144 | - # If waitpid() returns 0 it means that no child process wishes to |
1145 | - # report, and the value of status is undefined. |
1146 | - if pid == 0: |
1147 | - try: |
1148 | - pid, status = os.waitpid(self.pid, waitpid_options) ### os.WNOHANG) # Solaris! |
1149 | - except OSError, e: # This should never happen... |
1150 | - if e[0] == errno.ECHILD: |
1151 | - raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?') |
1152 | - else: |
1153 | - raise e |
1154 | - |
1155 | - # If pid is still 0 after two calls to waitpid() then |
1156 | - # the process really is alive. This seems to work on all platforms, except |
1157 | - # for Irix which seems to require a blocking call on waitpid or select, so I let read_nonblocking |
1158 | - # take care of this situation (unfortunately, this requires waiting through the timeout). |
1159 | - if pid == 0: |
1160 | - return True |
1161 | - |
1162 | - if pid == 0: |
1163 | - return True |
1164 | - |
1165 | - if os.WIFEXITED (status): |
1166 | - self.status = status |
1167 | - self.exitstatus = os.WEXITSTATUS(status) |
1168 | - self.signalstatus = None |
1169 | - self.terminated = True |
1170 | - elif os.WIFSIGNALED (status): |
1171 | - self.status = status |
1172 | - self.exitstatus = None |
1173 | - self.signalstatus = os.WTERMSIG(status) |
1174 | - self.terminated = True |
1175 | - elif os.WIFSTOPPED (status): |
1176 | - raise ExceptionPexpect ('isalive() encountered condition where child process is stopped. This is not supported. Is some other process attempting job control with our child pid?') |
1177 | - return False |
1178 | - |
1179 | - def kill(self, sig): |
1180 | - |
1181 | - """This sends the given signal to the child application. In keeping |
1182 | - with UNIX tradition it has a misleading name. It does not necessarily |
1183 | - kill the child unless you send the right signal. """ |
1184 | - |
1185 | - # Same as os.kill, but the pid is given for you. |
1186 | - if self.isalive(): |
1187 | - os.kill(self.pid, sig) |
1188 | - |
1189 | - def compile_pattern_list(self, patterns): |
1190 | - |
1191 | - """This compiles a pattern-string or a list of pattern-strings. |
1192 | - Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of |
1193 | - those. Patterns may also be None which results in an empty list (you |
1194 | - might do this if waiting for an EOF or TIMEOUT condition without |
1195 | - expecting any pattern). |
1196 | - |
1197 | - This is used by expect() when calling expect_list(). Thus expect() is |
1198 | - nothing more than:: |
1199 | - |
1200 | - cpl = self.compile_pattern_list(pl) |
1201 | - return self.expect_list(cpl, timeout) |
1202 | - |
1203 | - If you are using expect() within a loop it may be more |
1204 | - efficient to compile the patterns first and then call expect_list(). |
1205 | - This avoid calls in a loop to compile_pattern_list():: |
1206 | - |
1207 | - cpl = self.compile_pattern_list(my_pattern) |
1208 | - while some_condition: |
1209 | - ... |
1210 | - i = self.expect_list(clp, timeout) |
1211 | - ... |
1212 | - """ |
1213 | - |
1214 | - if patterns is None: |
1215 | - return [] |
1216 | - if type(patterns) is not types.ListType: |
1217 | - patterns = [patterns] |
1218 | - |
1219 | - compile_flags = re.DOTALL # Allow dot to match \n |
1220 | - if self.ignorecase: |
1221 | - compile_flags = compile_flags | re.IGNORECASE |
1222 | - compiled_pattern_list = [] |
1223 | - for p in patterns: |
1224 | - if type(p) in types.StringTypes: |
1225 | - compiled_pattern_list.append(re.compile(p, compile_flags)) |
1226 | - elif p is EOF: |
1227 | - compiled_pattern_list.append(EOF) |
1228 | - elif p is TIMEOUT: |
1229 | - compiled_pattern_list.append(TIMEOUT) |
1230 | - elif type(p) is type(re.compile('')): |
1231 | - compiled_pattern_list.append(p) |
1232 | - else: |
1233 | - raise TypeError ('Argument must be one of StringTypes, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p))) |
1234 | - |
1235 | - return compiled_pattern_list |
1236 | - |
1237 | - def expect(self, pattern, timeout = -1, searchwindowsize=None): |
1238 | - |
1239 | - """This seeks through the stream until a pattern is matched. The |
1240 | - pattern is overloaded and may take several types. The pattern can be a |
1241 | - StringType, EOF, a compiled re, or a list of any of those types. |
1242 | - Strings will be compiled to re types. This returns the index into the |
1243 | - pattern list. If the pattern was not a list this returns index 0 on a |
1244 | - successful match. This may raise exceptions for EOF or TIMEOUT. To |
1245 | - avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern |
1246 | - list. That will cause expect to match an EOF or TIMEOUT condition |
1247 | - instead of raising an exception. |
1248 | - |
1249 | - If you pass a list of patterns and more than one matches, the first match |
1250 | - in the stream is chosen. If more than one pattern matches at that point, |
1251 | - the leftmost in the pattern list is chosen. For example:: |
1252 | - |
1253 | - # the input is 'foobar' |
1254 | - index = p.expect (['bar', 'foo', 'foobar']) |
1255 | - # returns 1 ('foo') even though 'foobar' is a "better" match |
1256 | - |
1257 | - Please note, however, that buffering can affect this behavior, since |
1258 | - input arrives in unpredictable chunks. For example:: |
1259 | - |
1260 | - # the input is 'foobar' |
1261 | - index = p.expect (['foobar', 'foo']) |
1262 | - # returns 0 ('foobar') if all input is available at once, |
1263 | - # but returs 1 ('foo') if parts of the final 'bar' arrive late |
1264 | - |
1265 | - After a match is found the instance attributes 'before', 'after' and |
1266 | - 'match' will be set. You can see all the data read before the match in |
1267 | - 'before'. You can see the data that was matched in 'after'. The |
1268 | - re.MatchObject used in the re match will be in 'match'. If an error |
1269 | - occurred then 'before' will be set to all the data read so far and |
1270 | - 'after' and 'match' will be None. |
1271 | - |
1272 | - If timeout is -1 then timeout will be set to the self.timeout value. |
1273 | - |
1274 | - A list entry may be EOF or TIMEOUT instead of a string. This will |
1275 | - catch these exceptions and return the index of the list entry instead |
1276 | - of raising the exception. The attribute 'after' will be set to the |
1277 | - exception type. The attribute 'match' will be None. This allows you to |
1278 | - write code like this:: |
1279 | - |
1280 | - index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) |
1281 | - if index == 0: |
1282 | - do_something() |
1283 | - elif index == 1: |
1284 | - do_something_else() |
1285 | - elif index == 2: |
1286 | - do_some_other_thing() |
1287 | - elif index == 3: |
1288 | - do_something_completely_different() |
1289 | - |
1290 | - instead of code like this:: |
1291 | - |
1292 | - try: |
1293 | - index = p.expect (['good', 'bad']) |
1294 | - if index == 0: |
1295 | - do_something() |
1296 | - elif index == 1: |
1297 | - do_something_else() |
1298 | - except EOF: |
1299 | - do_some_other_thing() |
1300 | - except TIMEOUT: |
1301 | - do_something_completely_different() |
1302 | - |
1303 | - These two forms are equivalent. It all depends on what you want. You |
1304 | - can also just expect the EOF if you are waiting for all output of a |
1305 | - child to finish. For example:: |
1306 | - |
1307 | - p = pexpect.spawn('/bin/ls') |
1308 | - p.expect (pexpect.EOF) |
1309 | - print p.before |
1310 | - |
1311 | - If you are trying to optimize for speed then see expect_list(). |
1312 | - """ |
1313 | - |
1314 | - compiled_pattern_list = self.compile_pattern_list(pattern) |
1315 | - return self.expect_list(compiled_pattern_list, timeout, searchwindowsize) |
1316 | - |
1317 | - def expect_list(self, pattern_list, timeout = -1, searchwindowsize = -1): |
1318 | - |
1319 | - """This takes a list of compiled regular expressions and returns the |
1320 | - index into the pattern_list that matched the child output. The list may |
1321 | - also contain EOF or TIMEOUT (which are not compiled regular |
1322 | - expressions). This method is similar to the expect() method except that |
1323 | - expect_list() does not recompile the pattern list on every call. This |
1324 | - may help if you are trying to optimize for speed, otherwise just use |
1325 | - the expect() method. This is called by expect(). If timeout==-1 then |
1326 | - the self.timeout value is used. If searchwindowsize==-1 then the |
1327 | - self.searchwindowsize value is used. """ |
1328 | - |
1329 | - return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize) |
1330 | - |
1331 | - def expect_exact(self, pattern_list, timeout = -1, searchwindowsize = -1): |
1332 | - |
1333 | - """This is similar to expect(), but uses plain string matching instead |
1334 | - of compiled regular expressions in 'pattern_list'. The 'pattern_list' |
1335 | - may be a string; a list or other sequence of strings; or TIMEOUT and |
1336 | - EOF. |
1337 | - |
1338 | - This call might be faster than expect() for two reasons: string |
1339 | - searching is faster than RE matching and it is possible to limit the |
1340 | - search to just the end of the input buffer. |
1341 | - |
1342 | - This method is also useful when you don't want to have to worry about |
1343 | - escaping regular expression characters that you want to match.""" |
1344 | - |
1345 | - if type(pattern_list) in types.StringTypes or pattern_list in (TIMEOUT, EOF): |
1346 | - pattern_list = [pattern_list] |
1347 | - return self.expect_loop(searcher_string(pattern_list), timeout, searchwindowsize) |
1348 | - |
1349 | - def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): |
1350 | - |
1351 | - """This is the common loop used inside expect. The 'searcher' should be |
1352 | - an instance of searcher_re or searcher_string, which describes how and what |
1353 | - to search for in the input. |
1354 | - |
1355 | - See expect() for other arguments, return value and exceptions. """ |
1356 | - |
1357 | - self.searcher = searcher |
1358 | - |
1359 | - if timeout == -1: |
1360 | - timeout = self.timeout |
1361 | - if timeout is not None: |
1362 | - end_time = time.time() + timeout |
1363 | - if searchwindowsize == -1: |
1364 | - searchwindowsize = self.searchwindowsize |
1365 | - |
1366 | - try: |
1367 | - incoming = self.buffer |
1368 | - freshlen = len(incoming) |
1369 | - while True: # Keep reading until exception or return. |
1370 | - index = searcher.search(incoming, freshlen, searchwindowsize) |
1371 | - if index >= 0: |
1372 | - self.buffer = incoming[searcher.end : ] |
1373 | - self.before = incoming[ : searcher.start] |
1374 | - self.after = incoming[searcher.start : searcher.end] |
1375 | - self.match = searcher.match |
1376 | - self.match_index = index |
1377 | - return self.match_index |
1378 | - # No match at this point |
1379 | - if timeout < 0 and timeout is not None: |
1380 | - raise TIMEOUT ('Timeout exceeded in expect_any().') |
1381 | - # Still have time left, so read more data |
1382 | - c = self.read_nonblocking (self.maxread, timeout) |
1383 | - freshlen = len(c) |
1384 | - time.sleep (0.0001) |
1385 | - incoming = incoming + c |
1386 | - if timeout is not None: |
1387 | - timeout = end_time - time.time() |
1388 | - except EOF, e: |
1389 | - self.buffer = '' |
1390 | - self.before = incoming |
1391 | - self.after = EOF |
1392 | - index = searcher.eof_index |
1393 | - if index >= 0: |
1394 | - self.match = EOF |
1395 | - self.match_index = index |
1396 | - return self.match_index |
1397 | - else: |
1398 | - self.match = None |
1399 | - self.match_index = None |
1400 | - raise EOF (str(e) + '\n' + str(self)) |
1401 | - except TIMEOUT, e: |
1402 | - self.buffer = incoming |
1403 | - self.before = incoming |
1404 | - self.after = TIMEOUT |
1405 | - index = searcher.timeout_index |
1406 | - if index >= 0: |
1407 | - self.match = TIMEOUT |
1408 | - self.match_index = index |
1409 | - return self.match_index |
1410 | - else: |
1411 | - self.match = None |
1412 | - self.match_index = None |
1413 | - raise TIMEOUT (str(e) + '\n' + str(self)) |
1414 | - except Exception: |
1415 | - self.before = incoming |
1416 | - self.after = None |
1417 | - self.match = None |
1418 | - self.match_index = None |
1419 | - raise |
1420 | - |
1421 | - def getwinsize(self): |
1422 | - |
1423 | - """This returns the terminal window size of the child tty. The return |
1424 | - value is a tuple of (rows, cols). """ |
1425 | - |
1426 | - TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912L) |
1427 | - s = struct.pack('HHHH', 0, 0, 0, 0) |
1428 | - x = fcntl.ioctl(self.fileno(), TIOCGWINSZ, s) |
1429 | - return struct.unpack('HHHH', x)[0:2] |
1430 | - |
1431 | - def setwinsize(self, r, c): |
1432 | - |
1433 | - """This sets the terminal window size of the child tty. This will cause |
1434 | - a SIGWINCH signal to be sent to the child. This does not change the |
1435 | - physical window size. It changes the size reported to TTY-aware |
1436 | - applications like vi or curses -- applications that respond to the |
1437 | - SIGWINCH signal. """ |
1438 | - |
1439 | - # Check for buggy platforms. Some Python versions on some platforms |
1440 | - # (notably OSF1 Alpha and RedHat 7.1) truncate the value for |
1441 | - # termios.TIOCSWINSZ. It is not clear why this happens. |
1442 | - # These platforms don't seem to handle the signed int very well; |
1443 | - # yet other platforms like OpenBSD have a large negative value for |
1444 | - # TIOCSWINSZ and they don't have a truncate problem. |
1445 | - # Newer versions of Linux have totally different values for TIOCSWINSZ. |
1446 | - # Note that this fix is a hack. |
1447 | - TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) |
1448 | - if TIOCSWINSZ == 2148037735L: # L is not required in Python >= 2.2. |
1449 | - TIOCSWINSZ = -2146929561 # Same bits, but with sign. |
1450 | - # Note, assume ws_xpixel and ws_ypixel are zero. |
1451 | - s = struct.pack('HHHH', r, c, 0, 0) |
1452 | - fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) |
1453 | - |
1454 | - def interact(self, escape_character = chr(29), input_filter = None, output_filter = None): |
1455 | - |
1456 | - """This gives control of the child process to the interactive user (the |
1457 | - human at the keyboard). Keystrokes are sent to the child process, and |
1458 | - the stdout and stderr output of the child process is printed. This |
1459 | - simply echos the child stdout and child stderr to the real stdout and |
1460 | - it echos the real stdin to the child stdin. When the user types the |
1461 | - escape_character this method will stop. The default for |
1462 | - escape_character is ^]. This should not be confused with ASCII 27 -- |
1463 | - the ESC character. ASCII 29 was chosen for historical merit because |
1464 | - this is the character used by 'telnet' as the escape character. The |
1465 | - escape_character will not be sent to the child process. |
1466 | - |
1467 | - You may pass in optional input and output filter functions. These |
1468 | - functions should take a string and return a string. The output_filter |
1469 | - will be passed all the output from the child process. The input_filter |
1470 | - will be passed all the keyboard input from the user. The input_filter |
1471 | - is run BEFORE the check for the escape_character. |
1472 | - |
1473 | - Note that if you change the window size of the parent the SIGWINCH |
1474 | - signal will not be passed through to the child. If you want the child |
1475 | - window size to change when the parent's window size changes then do |
1476 | - something like the following example:: |
1477 | - |
1478 | - import pexpect, struct, fcntl, termios, signal, sys |
1479 | - def sigwinch_passthrough (sig, data): |
1480 | - s = struct.pack("HHHH", 0, 0, 0, 0) |
1481 | - a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ , s)) |
1482 | - global p |
1483 | - p.setwinsize(a[0],a[1]) |
1484 | - p = pexpect.spawn('/bin/bash') # Note this is global and used in sigwinch_passthrough. |
1485 | - signal.signal(signal.SIGWINCH, sigwinch_passthrough) |
1486 | - p.interact() |
1487 | - """ |
1488 | - |
1489 | - # Flush the buffer. |
1490 | - self.stdout.write (self.buffer) |
1491 | - self.stdout.flush() |
1492 | - self.buffer = '' |
1493 | - mode = tty.tcgetattr(self.STDIN_FILENO) |
1494 | - tty.setraw(self.STDIN_FILENO) |
1495 | - try: |
1496 | - self.__interact_copy(escape_character, input_filter, output_filter) |
1497 | - finally: |
1498 | - tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) |
1499 | - |
1500 | - def __interact_writen(self, fd, data): |
1501 | - |
1502 | - """This is used by the interact() method. |
1503 | - """ |
1504 | - |
1505 | - while data != '' and self.isalive(): |
1506 | - n = os.write(fd, data) |
1507 | - data = data[n:] |
1508 | - |
1509 | - def __interact_read(self, fd): |
1510 | - |
1511 | - """This is used by the interact() method. |
1512 | - """ |
1513 | - |
1514 | - return os.read(fd, 1000) |
1515 | - |
1516 | - def __interact_copy(self, escape_character = None, input_filter = None, output_filter = None): |
1517 | - |
1518 | - """This is used by the interact() method. |
1519 | - """ |
1520 | - |
1521 | - while self.isalive(): |
1522 | - r,w,e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) #@UnusedVariable |
1523 | - if self.child_fd in r: |
1524 | - data = self.__interact_read(self.child_fd) |
1525 | - if output_filter: data = output_filter(data) |
1526 | - if self.logfile is not None: |
1527 | - self.logfile.write (data) |
1528 | - self.logfile.flush() |
1529 | - os.write(self.STDOUT_FILENO, data) |
1530 | - if self.STDIN_FILENO in r: |
1531 | - data = self.__interact_read(self.STDIN_FILENO) |
1532 | - if input_filter: data = input_filter(data) |
1533 | - i = data.rfind(escape_character) |
1534 | - if i != -1: |
1535 | - data = data[:i] |
1536 | - self.__interact_writen(self.child_fd, data) |
1537 | - break |
1538 | - self.__interact_writen(self.child_fd, data) |
1539 | - |
1540 | - def __select (self, iwtd, owtd, ewtd, timeout=None): |
1541 | - |
1542 | - """This is a wrapper around select.select() that ignores signals. If |
1543 | - select.select raises a select.error exception and errno is an EINTR |
1544 | - error then it is ignored. Mainly this is used to ignore sigwinch |
1545 | - (terminal resize). """ |
1546 | - |
1547 | - # if select() is interrupted by a signal (errno==EINTR) then |
1548 | - # we loop back and enter the select() again. |
1549 | - if timeout is not None: |
1550 | - end_time = time.time() + timeout |
1551 | - while True: |
1552 | - try: |
1553 | - return select.select (iwtd, owtd, ewtd, timeout) |
1554 | - except select.error, e: |
1555 | - if e[0] == errno.EINTR: |
1556 | - # if we loop back we have to subtract the amount of time we already waited. |
1557 | - if timeout is not None: |
1558 | - timeout = end_time - time.time() |
1559 | - if timeout < 0: |
1560 | - return ([],[],[]) |
1561 | - else: # something else caused the select.error, so this really is an exception |
1562 | - raise |
1563 | - |
1564 | -############################################################################## |
1565 | -# The following methods are no longer supported or allowed. |
1566 | - |
1567 | - def setmaxread (self, maxread): |
1568 | - |
1569 | - """This method is no longer supported or allowed. I don't like getters |
1570 | - and setters without a good reason. """ |
1571 | - |
1572 | - raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the maxread member variable.') |
1573 | - |
1574 | - def setlog (self, fileobject): |
1575 | - |
1576 | - """This method is no longer supported or allowed. |
1577 | - """ |
1578 | - |
1579 | - raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the logfile member variable.') |
1580 | - |
1581 | -############################################################################## |
1582 | -# End of spawn class |
1583 | -############################################################################## |
1584 | - |
1585 | -class searcher_string (object): |
1586 | - |
1587 | - """This is a plain string search helper for the spawn.expect_any() method. |
1588 | - |
1589 | - Attributes: |
1590 | - |
1591 | - eof_index - index of EOF, or -1 |
1592 | - timeout_index - index of TIMEOUT, or -1 |
1593 | - |
1594 | - After a successful match by the search() method the following attributes |
1595 | - are available: |
1596 | - |
1597 | - start - index into the buffer, first byte of match |
1598 | - end - index into the buffer, first byte after match |
1599 | - match - the matching string itself |
1600 | - """ |
1601 | - |
1602 | - def __init__(self, strings): |
1603 | - |
1604 | - """This creates an instance of searcher_string. This argument 'strings' |
1605 | - may be a list; a sequence of strings; or the EOF or TIMEOUT types. """ |
1606 | - |
1607 | - self.eof_index = -1 |
1608 | - self.timeout_index = -1 |
1609 | - self._strings = [] |
1610 | - for n, s in zip(range(len(strings)), strings): |
1611 | - if s is EOF: |
1612 | - self.eof_index = n |
1613 | - continue |
1614 | - if s is TIMEOUT: |
1615 | - self.timeout_index = n |
1616 | - continue |
1617 | - self._strings.append((n, s)) |
1618 | - |
1619 | - def __str__(self): |
1620 | - |
1621 | - """This returns a human-readable string that represents the state of |
1622 | - the object.""" |
1623 | - |
1624 | - ss = [ (ns[0],' %d: "%s"' % ns) for ns in self._strings ] |
1625 | - ss.append((-1,'searcher_string:')) |
1626 | - if self.eof_index >= 0: |
1627 | - ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) |
1628 | - if self.timeout_index >= 0: |
1629 | - ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) |
1630 | - ss.sort() |
1631 | - ss = zip(*ss)[1] |
1632 | - return '\n'.join(ss) |
1633 | - |
1634 | - def search(self, buffer, freshlen, searchwindowsize=None): |
1635 | - |
1636 | - """This searches 'buffer' for the first occurence of one of the search |
1637 | - strings. 'freshlen' must indicate the number of bytes at the end of |
1638 | - 'buffer' which have not been searched before. It helps to avoid |
1639 | - searching the same, possibly big, buffer over and over again. |
1640 | - |
1641 | - See class spawn for the 'searchwindowsize' argument. |
1642 | - |
1643 | - If there is a match this returns the index of that string, and sets |
1644 | - 'start', 'end' and 'match'. Otherwise, this returns -1. """ |
1645 | - |
1646 | - absurd_match = len(buffer) |
1647 | - first_match = absurd_match |
1648 | - |
1649 | - # 'freshlen' helps a lot here. Further optimizations could |
1650 | - # possibly include: |
1651 | - # |
1652 | - # using something like the Boyer-Moore Fast String Searching |
1653 | - # Algorithm; pre-compiling the search through a list of |
1654 | - # strings into something that can scan the input once to |
1655 | - # search for all N strings; realize that if we search for |
1656 | - # ['bar', 'baz'] and the input is '...foo' we need not bother |
1657 | - # rescanning until we've read three more bytes. |
1658 | - # |
1659 | - # Sadly, I don't know enough about this interesting topic. /grahn |
1660 | - |
1661 | - for index, s in self._strings: |
1662 | - if searchwindowsize is None: |
1663 | - # the match, if any, can only be in the fresh data, |
1664 | - # or at the very end of the old data |
1665 | - offset = -(freshlen+len(s)) |
1666 | - else: |
1667 | - # better obey searchwindowsize |
1668 | - offset = -searchwindowsize |
1669 | - n = buffer.find(s, offset) |
1670 | - if n >= 0 and n < first_match: |
1671 | - first_match = n |
1672 | - best_index, best_match = index, s |
1673 | - if first_match == absurd_match: |
1674 | - return -1 |
1675 | - self.match = best_match |
1676 | - self.start = first_match |
1677 | - self.end = self.start + len(self.match) |
1678 | - return best_index |
1679 | - |
1680 | -class searcher_re (object): |
1681 | - |
1682 | - """This is regular expression string search helper for the |
1683 | - spawn.expect_any() method. |
1684 | - |
1685 | - Attributes: |
1686 | - |
1687 | - eof_index - index of EOF, or -1 |
1688 | - timeout_index - index of TIMEOUT, or -1 |
1689 | - |
1690 | - After a successful match by the search() method the following attributes |
1691 | - are available: |
1692 | - |
1693 | - start - index into the buffer, first byte of match |
1694 | - end - index into the buffer, first byte after match |
1695 | - match - the re.match object returned by a succesful re.search |
1696 | - |
1697 | - """ |
1698 | - |
1699 | - def __init__(self, patterns): |
1700 | - |
1701 | - """This creates an instance that searches for 'patterns' Where |
1702 | - 'patterns' may be a list or other sequence of compiled regular |
1703 | - expressions, or the EOF or TIMEOUT types.""" |
1704 | - |
1705 | - self.eof_index = -1 |
1706 | - self.timeout_index = -1 |
1707 | - self._searches = [] |
1708 | - for n, s in zip(range(len(patterns)), patterns): |
1709 | - if s is EOF: |
1710 | - self.eof_index = n |
1711 | - continue |
1712 | - if s is TIMEOUT: |
1713 | - self.timeout_index = n |
1714 | - continue |
1715 | - self._searches.append((n, s)) |
1716 | - |
1717 | - def __str__(self): |
1718 | - |
1719 | - """This returns a human-readable string that represents the state of |
1720 | - the object.""" |
1721 | - |
1722 | - ss = [ (n,' %d: re.compile("%s")' % (n,str(s.pattern))) for n,s in self._searches] |
1723 | - ss.append((-1,'searcher_re:')) |
1724 | - if self.eof_index >= 0: |
1725 | - ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) |
1726 | - if self.timeout_index >= 0: |
1727 | - ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) |
1728 | - ss.sort() |
1729 | - ss = zip(*ss)[1] |
1730 | - return '\n'.join(ss) |
1731 | - |
1732 | - def search(self, buffer, freshlen, searchwindowsize=None): |
1733 | - |
1734 | - """This searches 'buffer' for the first occurence of one of the regular |
1735 | - expressions. 'freshlen' must indicate the number of bytes at the end of |
1736 | - 'buffer' which have not been searched before. |
1737 | - |
1738 | - See class spawn for the 'searchwindowsize' argument. |
1739 | - |
1740 | - If there is a match this returns the index of that string, and sets |
1741 | - 'start', 'end' and 'match'. Otherwise, returns -1.""" |
1742 | - |
1743 | - absurd_match = len(buffer) |
1744 | - first_match = absurd_match |
1745 | - # 'freshlen' doesn't help here -- we cannot predict the |
1746 | - # length of a match, and the re module provides no help. |
1747 | - if searchwindowsize is None: |
1748 | - searchstart = 0 |
1749 | - else: |
1750 | - searchstart = max(0, len(buffer)-searchwindowsize) |
1751 | - for index, s in self._searches: |
1752 | - match = s.search(buffer, searchstart) |
1753 | - if match is None: |
1754 | - continue |
1755 | - n = match.start() |
1756 | - if n < first_match: |
1757 | - first_match = n |
1758 | - the_match = match |
1759 | - best_index = index |
1760 | - if first_match == absurd_match: |
1761 | - return -1 |
1762 | - self.start = first_match |
1763 | - self.match = the_match |
1764 | - self.end = self.match.end() |
1765 | - return best_index |
1766 | - |
1767 | -def which (filename): |
1768 | - |
1769 | - """This takes a given filename; tries to find it in the environment path; |
1770 | - then checks if it is executable. This returns the full path to the filename |
1771 | - if found and executable. Otherwise this returns None.""" |
1772 | - |
1773 | - # Special case where filename already contains a path. |
1774 | - if os.path.dirname(filename) != '': |
1775 | - if os.access (filename, os.X_OK): |
1776 | - return filename |
1777 | - |
1778 | - if not os.environ.has_key('PATH') or os.environ['PATH'] == '': |
1779 | - p = os.defpath |
1780 | - else: |
1781 | - p = os.environ['PATH'] |
1782 | - |
1783 | - # Oddly enough this was the one line that made Pexpect |
1784 | - # incompatible with Python 1.5.2. |
1785 | - #pathlist = p.split (os.pathsep) |
1786 | - pathlist = string.split (p, os.pathsep) |
1787 | - |
1788 | - for path in pathlist: |
1789 | - f = os.path.join(path, filename) |
1790 | - if os.access(f, os.X_OK): |
1791 | - return f |
1792 | - return None |
1793 | - |
1794 | -def split_command_line(command_line): |
1795 | - |
1796 | - """This splits a command line into a list of arguments. It splits arguments |
1797 | - on spaces, but handles embedded quotes, doublequotes, and escaped |
1798 | - characters. It's impossible to do this with a regular expression, so I |
1799 | - wrote a little state machine to parse the command line. """ |
1800 | - |
1801 | - arg_list = [] |
1802 | - arg = '' |
1803 | - |
1804 | - # Constants to name the states we can be in. |
1805 | - state_basic = 0 |
1806 | - state_esc = 1 |
1807 | - state_singlequote = 2 |
1808 | - state_doublequote = 3 |
1809 | - state_whitespace = 4 # The state of consuming whitespace between commands. |
1810 | - state = state_basic |
1811 | - |
1812 | - for c in command_line: |
1813 | - if state == state_basic or state == state_whitespace: |
1814 | - if c == '\\': # Escape the next character |
1815 | - state = state_esc |
1816 | - elif c == r"'": # Handle single quote |
1817 | - state = state_singlequote |
1818 | - elif c == r'"': # Handle double quote |
1819 | - state = state_doublequote |
1820 | - elif c.isspace(): |
1821 | - # Add arg to arg_list if we aren't in the middle of whitespace. |
1822 | - if state == state_whitespace: |
1823 | - None # Do nothing. |
1824 | - else: |
1825 | - arg_list.append(arg) |
1826 | - arg = '' |
1827 | - state = state_whitespace |
1828 | - else: |
1829 | - arg = arg + c |
1830 | - state = state_basic |
1831 | - elif state == state_esc: |
1832 | - arg = arg + c |
1833 | - state = state_basic |
1834 | - elif state == state_singlequote: |
1835 | - if c == r"'": |
1836 | - state = state_basic |
1837 | - else: |
1838 | - arg = arg + c |
1839 | - elif state == state_doublequote: |
1840 | - if c == r'"': |
1841 | - state = state_basic |
1842 | - else: |
1843 | - arg = arg + c |
1844 | - |
1845 | - if arg != '': |
1846 | - arg_list.append(arg) |
1847 | - return arg_list |
1848 | - |
1849 | -# vi:ts=4:sw=4:expandtab:ft=python: |