fixbot/logwatch/fifo.py
author Tero Marttila <terom@fixme.fi>
Sat, 20 Feb 2010 22:32:18 +0200
changeset 63 a849c00b63f8
parent 45 fixbot/fifo.py@5f35f8ce452b
permissions -rw-r--r--
move fixbot.fifo to fixbot.logwatch.fifo
# 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()