15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"""This is like pexpect, but will work on any file descriptor that you pass it. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)You are reponsible for opening and close the file descriptor. 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PEXPECT LICENSE 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) This license is approved by the OSI and FSF as GPL-compatible. 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) http://opensource.org/licenses/isc-license.txt 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Copyright (c) 2012, Noah Spurrier <noah@noah.org> 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)""" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from pexpect import * 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)__all__ = ['fdspawn'] 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class fdspawn (spawn): 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This is like pexpect.spawn but allows you to supply your own open file 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) descriptor. For example, you could use it to read through a file looking 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for patterns, or to control a modem or serial device. """ 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __init__ (self, fd, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None): 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This takes a file descriptor (an int) or an object that support the 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fileno() method (returning an int). All Python file-like objects 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) support fileno(). """ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ### TODO: Add better handling of trying to use fdspawn in place of spawn 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ### TODO: (overload to allow fdspawn to also handle commands as spawn does. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if type(fd) != type(0) and hasattr(fd, 'fileno'): 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fd = fd.fileno() 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if type(fd) != type(0): 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ExceptionPexpect ('The fd argument is not an int. If this is a command string then maybe you want to use pexpect.spawn.') 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: # make sure fd is a valid file descriptor 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.fstat(fd) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except OSError: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ExceptionPexpect, 'The fd argument is not a valid file descriptor.' 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.args = None 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.command = None 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spawn.__init__(self, None, args, timeout, maxread, searchwindowsize, logfile) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.child_fd = fd 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.own_fd = False 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.closed = False 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.name = '<file descriptor %d>' % fd 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def __del__ (self): 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def close (self): 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.child_fd == -1: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.own_fd: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.close (self) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else: 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.flush() 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.close(self.child_fd) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.child_fd = -1 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self.closed = True 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def isalive (self): 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) """This checks if the file descriptor is still valid. If os.fstat() 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) does not raise an exception then we assume it is alive. """ 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if self.child_fd == -1: 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) os.fstat(self.child_fd) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return True 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) except: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return False 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def terminate (self, force=False): 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) raise ExceptionPexpect ('This method is not valid for file descriptors.') 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) def kill (self, sig): 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 99