diff -r e4db89a5f6bc -r a849c00b63f8 fixbot/logwatch/fifo.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fixbot/logwatch/fifo.py Sat Feb 20 22:32:18 2010 +0200 @@ -0,0 +1,90 @@ +# read a stream from a fifo + +from twisted.internet import reactor, interfaces +from twisted.python import log +from zope.interface import implements + +import os, fcntl, errno + +class EOF (Exception) : pass + +BUF_SIZE = 2048 + +class Fifo (object) : + implements(interfaces.IReadDescriptor) + + def __init__ (self, path) : + self.path = path + self.fd = None + + self._open() + + def _open (self) : + self.fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK) + + reactor.addReader(self) + + def close (self) : + if self.fd : + reactor.removeReader(self) + os.close(self.fd) + + self.fd = None + + def reopen (self) : + """ + Close and re-open the fifo. This is useful for handling EOF + """ + self.close() + self._open() + + def _read (self, length) : + + try : + data = os.read(self.fd, length) + + except OSError, e : + if e.errno == errno.EAGAIN : + return None + else : + raise + + if not data : + raise EOF() + + return data + + def fileno (self) : + return self.fd + + def doRead (self) : + while True : + try : + data = self._read(BUF_SIZE) + except EOF : + self.handleEOF() + return + + if data : + self.dataReceived(data) + else : + break + + def dataReceived (self, data) : + pass + + def handleEOF (self) : + pass + + def connectionLost (self, reason) : + self.close() + + def logPrefix (self) : + return "fifo(%s)" % (self.path, ) + + def __del__ (self) : + """ + !!! this is important + """ + self.close() +