fixbot/logwatch/fifo.py
changeset 63 a849c00b63f8
parent 45 5f35f8ce452b
--- /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()
+