rename plugin fixbot -> fixbot_nexus, add fixbot_logwatch plugin, fix some random bugs
# 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)
log.msg("opened fifo %s as %d" % (self.path, self.fd))
def _close (self) :
if self.fd :
reactor.removeReader(self)
os.close(self.fd)
log.msg("closed fifo %d at %s" % (self.fd, self.path))
self.fd = None
close = _close
def reopen (self) :
"""
Close and re-open the fifo. This is useful for handling EOF
"""
self._close()
self._open()
def _read (self, length) :
log.msg("(read %d bytes from %d:%s)" % (length, self.fd, self.path))
try :
data = os.read(self.fd, length)
except OSError, e :
if e.errno == errno.EAGAIN :
log.msg("\tEAGAIN")
return None
else :
log.msg("\tERROR: %s" % e)
raise
if not data :
log.msg("\tEOF")
raise EOF()
log.msg("\tDATA: %d: %r" % (len(data), data))
return data
def fileno (self) :
return self.fd
def doRead (self) :
while True :
log.msg("fifo doRead loop")
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:%d:%s" % (self.fd, self.path)
def __del__ (self) :
"""
!!! this is important
"""
self.close()