fifo.py
author Tero Marttila <terom@paivola.fi>
Wed, 26 Mar 2008 02:30:34 +0200
changeset 17 24dc72473ff9
permissions -rw-r--r--
add support for fifos in logwatch

committer: Tero Marttila <terom@paivola.fi>
17
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
# read a stream from a fifo
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
from twisted.internet import reactor, interfaces
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
from twisted.python import log
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
from zope.interface import implements
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
import os, fcntl, errno
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
class EOF (Exception) : pass
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
BUF_SIZE = 2048
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
class Fifo (object) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
    implements(interfaces.IReadDescriptor)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
    def __init__ (self, path) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
        self.path = path
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
        self._open()
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
    def _open (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
        self.fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
        reactor.addReader(self)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
        
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
        log.msg("opened fifo %s as %d" % (self.path, self.fd))
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
    def _close (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
        if self.fd :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
            reactor.removeReader(self)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
            os.close(self.fd)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
            log.msg("closed fifo %d at %s" % (self.fd, self.path))
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
            
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
            self.fd = None
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
    close = _close
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
    def reopen (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
        """
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
            Close and re-open the fifo. This is useful for handling EOF
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
        """
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
        self._close()
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
        self._open()
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
    def _read (self, length) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
        log.msg("(read %d bytes from %d:%s)" % (length, self.fd, self.path))
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
        try :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
            data = os.read(self.fd, length)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
        except OSError, e :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
            if e.errno == errno.EAGAIN :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
                log.msg("\tEAGAIN")
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
                return None
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
            else :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
                log.msg("\tERROR: %s" % e)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
                raise
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
        if not data :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
            log.msg("\tEOF")
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
            raise EOF()
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
        
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
        log.msg("\tDATA: %d: %r" % (len(data), data))
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
        return data
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
    
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
    def fileno (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
        return self.fd
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
    def doRead (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
        while True :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
            log.msg("fifo doRead loop")
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
            try :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
                data = self._read(BUF_SIZE)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
            except EOF :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
                self.handleEOF()
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
                return
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
            if data :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
                self.dataReceived(data)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
            else :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
                break
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
        
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
    def dataReceived (self, data) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
        pass
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
    
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
    def handleEOF (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
        pass
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
    
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
    def connectionLost (self, reason) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
        self.close()
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
    
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
    def logPrefix (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
        return "FIFO:%d:%s" % (self.fd, self.path)
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
    def __del__ (self) :
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
        """
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
            !!! this is important
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
        """
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
        self.close()
24dc72473ff9 add support for fifos in logwatch
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100