move pcucontrol package into pcucontrol module.
[pcucontrol.git] / pcucontrol / transports / ssh / fdpexpect.py
1 """
2 TODO: This is BETA. When it gets stable I will move it into the pexpect.py file.
3 """
4
5 from pexpect import *
6 import os
7
8 __all__ = ['fdspawn']
9
10 class fdspawn (spawn):
11     """This is like pexpect.spawn but allows you to supply your own,
12     already open file descriptor. For example, you could use it to
13     read through a file looking for patterns, or to control a modem or
14     serial device.
15     """
16     def __init__ (self, fd, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None):
17         """This takes a file descriptor (an int) or an object that support the fileno() method
18             (returning an int). All Python file-like objects support fileno().
19         """
20         ### TODO: Add better handling of trying to use fdspawn in place of spawn
21         ### TODO: (overload to allow fdspawn to also handle commands as spawn does.
22
23         if type(fd) != type(0) and hasattr(fd, 'fileno'):
24             fd = fd.fileno()
25
26         if type(fd) != type(0):
27             raise ExceptionPexpect ('The fd argument is not an int. If this is a command string then maybe you want to use pexpect.spawn.')
28
29         try: # make sure fd is a valid file descriptor
30             os.fstat(fd)
31         except OSError:
32             raise ExceptionPexpect, 'The fd argument is not a valid file descriptor.'
33
34         self.args = None
35         self.command = None
36         spawn.__init__(self, None, args, timeout, maxread, searchwindowsize, logfile)
37         self.child_fd = fd
38         self.own_fd = False
39         self.closed = False
40         self.name = '<file descriptor %d>' % fd
41
42     def __del__ (self):
43         return
44
45     def close (self):
46         if super(fdspawn, self).child_fd == -1:
47             return
48         if self.own_fd:
49             super(fdspawn, self).close (self)
50         else:
51             self.flush()
52             os.close(super(fdspawn, self).child_fd)
53             self.child_fd = -1
54             self.closed = True
55
56     def isalive (self):
57         """This checks if the file descriptor is still valid.
58             If os.fstat() does not raise an exception then we assume it is alive.
59         """
60         if self.child_fd == -1:
61             return False
62         try:
63             os.fstat(self.child_fd)
64             return True
65         except:
66             return False
67
68     def terminate (self, force=False):
69         raise ExceptionPexpect ('This method is not valid for file descriptors.')
70
71     def kill (self, sig):
72         return
73