class FIFOFileDescriptor FileDescriptor An abstract base class impleme

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
class FIFOFileDescriptor(FileDescriptor):
"""
An abstract base class, implementing common functionality for FIFO-related
classes.
@ivar path: Filesystem path of the FIFO
@type path: L{FilePath<twisted.python.filepath.FilePath>}
"""
def __init__(self, path, _reactor=None):
self._fd = None
self.path = path
FileDescriptor.__init__(self, _reactor)
def fileno(self):
"""
Return the integer "file descriptor" for this FIFO
"""
return self._fd
def connectionLost(self, reason):
"""
The connection was lost.
"""
FileDescriptor.connectionLost(self, reason)
self.protocol.connectionLost(reason)
self.connected = 0
if self._fd is not None:
os.close(self._fd)
def logPrefix(self):
return "%s: %s" % (self.__class__.__name__, self.path)
class FIFOReader(FIFOFileDescriptor):
"""
A reading end of a FIFO.
"""
chunk_size = 8192
implements(IReadDescriptor)
def startReading(self):
"""
Start waiting for read availability
"""
if self.connected:
FileDescriptor.startReading(self)
return
self._fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK)
self.connected = 1
FileDescriptor.startReading(self)
def doRead(self):
"""
Data is available for reading on this FIFO
"""
while True:
try:
output = os.read(self.fileno(), self.chunk_size)
except (OSError, IOError), err:
if err.args[0] in (errno.EAGAIN, errno.EINTR):
return
else:
return main.CONNECTION_LOST
if not output:
return main.CONNECTION_DONE
self.protocol.dataReceived(output)
def loseConnection(self, _connDone=failure.Failure(main.CONNECTION_DONE)):
"""
Close the connection
"""
if self.connected and not self.disconnecting:
self.disconnecting = 1
self.stopReading()
self.reactor.callLater(0, self.connectionLost, _connDone)
def readFromFIFO(path, proto, _reactor=None):
"""
Start reading from the FIFO under a filesystem path C{path}.
@param path: Filesystem path of the FIFO
@type path: L{FilePath<twisted.python.filepath.FilePath>}
@param proto: A protocol to use
@param _reactor: A reactor to use. Defaults to C{twisted.internet.reactor},
if not provided
"""
if _reactor is None:
_reactor = reactor
fifo = FIFOReader(path, _reactor)
fifo.protocol = proto
proto.makeConnection(fifo)
# startReading comes last here, because we don't want to have a possibility
# of losing data
fifo.startReading()