Index: third_party/pexpect/pexpect/fdpexpect.py |
diff --git a/third_party/pexpect/pexpect/fdpexpect.py b/third_party/pexpect/pexpect/fdpexpect.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..dd1b492f02248f922c943c221e03147422412092 |
--- /dev/null |
+++ b/third_party/pexpect/pexpect/fdpexpect.py |
@@ -0,0 +1,114 @@ |
+'''This is like pexpect, but it will work with any file descriptor that you |
+pass it. You are reponsible for opening and close the file descriptor. |
+This allows you to use Pexpect with sockets and named pipes (FIFOs). |
+ |
+PEXPECT LICENSE |
+ |
+ This license is approved by the OSI and FSF as GPL-compatible. |
+ http://opensource.org/licenses/isc-license.txt |
+ |
+ Copyright (c) 2012, Noah Spurrier <noah@noah.org> |
+ PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY |
+ PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE |
+ COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. |
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
+ |
+''' |
+ |
+from .spawnbase import SpawnBase |
+from .exceptions import ExceptionPexpect |
+import os |
+ |
+__all__ = ['fdspawn'] |
+ |
+class fdspawn(SpawnBase): |
+ '''This is like pexpect.spawn but allows you to supply your own 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. ''' |
+ |
+ def __init__ (self, fd, args=None, timeout=30, maxread=2000, searchwindowsize=None, |
+ logfile=None, encoding=None, codec_errors='strict'): |
+ '''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(). ''' |
+ |
+ if type(fd) != type(0) and hasattr(fd, 'fileno'): |
+ fd = fd.fileno() |
+ |
+ 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(fd) |
+ except OSError: |
+ raise ExceptionPexpect('The fd argument is not a valid file descriptor.') |
+ |
+ self.args = None |
+ self.command = None |
+ SpawnBase.__init__(self, timeout, maxread, searchwindowsize, logfile, |
+ encoding=encoding, codec_errors=codec_errors) |
+ self.child_fd = fd |
+ self.own_fd = False |
+ self.closed = False |
+ self.name = '<file descriptor %d>' % fd |
+ |
+ def close (self): |
+ """Close the file descriptor. |
+ |
+ Calling this method a second time does nothing, but if the file |
+ descriptor was closed elsewhere, :class:`OSError` will be raised. |
+ """ |
+ if self.child_fd == -1: |
+ return |
+ |
+ self.flush() |
+ os.close(self.child_fd) |
+ self.child_fd = -1 |
+ self.closed = True |
+ |
+ def isalive (self): |
+ '''This checks if the file descriptor is still valid. If :func:`os.fstat` |
+ does not raise an exception then we assume it is alive. ''' |
+ |
+ if self.child_fd == -1: |
+ return False |
+ try: |
+ os.fstat(self.child_fd) |
+ return True |
+ except: |
+ return False |
+ |
+ def terminate (self, force=False): # pragma: no cover |
+ '''Deprecated and invalid. Just raises an exception.''' |
+ raise ExceptionPexpect('This method is not valid for file descriptors.') |
+ |
+ # These four methods are left around for backwards compatibility, but not |
+ # documented as part of fdpexpect. You're encouraged to use os.write |
+ # directly. |
+ def send(self, s): |
+ "Write to fd, return number of bytes written" |
+ s = self._coerce_send_string(s) |
+ self._log(s, 'send') |
+ |
+ b = self._encoder.encode(s, final=False) |
+ return os.write(self.child_fd, b) |
+ |
+ def sendline(self, s): |
+ "Write to fd with trailing newline, return number of bytes written" |
+ s = self._coerce_send_string(s) |
+ return self.send(s + self.linesep) |
+ |
+ def write(self, s): |
+ "Write to fd, return None" |
+ self.send(s) |
+ |
+ def writelines(self, sequence): |
+ "Call self.write() for each item in sequence" |
+ for s in sequence: |
+ self.write(s) |