# 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()