pvl/syslog/fifo.py
author Tero Marttila <terom@paivola.fi>
Sat, 08 Mar 2014 14:37:20 +0200
changeset 30 1053e69664a6
parent 18 48d94f45b242
permissions -rw-r--r--
pvl.invoke: setenv
2
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     1
"""
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     2
    Non-blocking fifo reads.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     3
"""
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     4
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     5
import os
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     6
import errno
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     7
import fcntl
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     8
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
     9
import logging
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    10
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    11
log = logging.getLogger('pvl.syslog.fifo')
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    12
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    13
class Pipe (object) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    14
    """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    15
        A pipe from a fd.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    16
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    17
        Supports reading lines in a non-blocking fashion.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
    """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    19
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    20
    @classmethod
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    21
    def file (cls, file) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    23
            Create Pipe from file, e.g. sys.stdin.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    24
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    25
            Puts fd into nonblocking mode, which means that the given file will stop working!
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    26
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    27
        
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    28
        fd = file.fileno()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    29
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    30
        log.debug("%s: %s", file, fd)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    32
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    33
        fl |= os.O_NONBLOCK
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    34
        fcntl.fcntl(fd, fcntl.F_SETFL, fl)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    35
        
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    36
        return cls(fd)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    37
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    38
    def __init__ (self, fd) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    39
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    40
            May pass fd=None to open as closed.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    41
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    42
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    43
        self._fd = fd
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    44
        self._buf = ''
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    45
        
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    46
        log.debug("pipe: %d", fd)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    47
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    48
    def open (self, fd) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    49
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    50
            re-open closed pipe to use the given fd.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    51
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    52
            Raises ValueError if already open.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    53
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    54
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    55
        if self._fd is None :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    56
            self._fd = fd
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    57
        else :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    58
            raise ValueError("%s: re-opening already open pipe: %s" % (self, fd))
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    59
    
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    60
    # XXX: good idea?
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    61
    def __nonzero__ (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    62
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    63
            Test if we are open.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    64
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    65
            XXX: signal EOF as well?
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    66
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    67
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    68
        return self._fd is not None
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    69
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    70
    def fileno (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    71
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    72
            Return the internal fd.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    73
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    74
            Raises ValueError if we are closed.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    75
            XXX: EOFError?
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    76
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    77
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    78
        if self._fd is None :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    79
            raise ValueError("I/O operation on closed pipe: %s" % (self, ))
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    80
        else :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    81
            return self._fd
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    82
    
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    83
    # XXX: this is almost identical to pvl.socket.ReadStream
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    84
    def read (self, n=512) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    85
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    86
            Read up to n bytes.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    87
            
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    88
            Returns None if we would block.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    89
            Raises EOFError on EOF, or closed.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    90
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    91
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    92
        try :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    93
            buf = os.read(self.fileno(), n)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    94
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    95
        except OSError as ex :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    96
            # block?
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    97
            if ex.errno == errno.EAGAIN :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    98
                # empty
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    99
                buf = None
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   100
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   101
            else :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   102
                raise
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   103
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   104
        log.debug("%s: %s", self, buf)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   105
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   106
        if buf is None :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   107
            return None
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   108
        elif buf :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   109
            return buf
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   110
        else :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   111
            raise EOFError()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   112
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   113
    def readline (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   114
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   115
            Read and return next waiting line from input.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   116
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   117
            Line is returned without trailing '\n'.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   118
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   119
            Returns None if there is no line available.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   120
            Raises EOFError if the fifo write end was closed.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   121
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   122
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   123
        while '\n' not in self._buf :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   124
            # read chunk
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   125
            read = self.read()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   126
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   127
            if read is None :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   128
                return None
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   129
            
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   130
            self._buf += read
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   131
        
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   132
        # split out one line
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   133
        line, self._buf = self._buf.split('\n', 1)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   134
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   135
        log.debug("%s", line)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   136
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   137
        return line
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   138
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   139
    def readlines (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   140
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   141
            Read any available input, yielding lines.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   142
            
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   143
            Re-opens the FIFO on EOF.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   144
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   145
            Returns None if there was no more input available, or the fifo was re-opened after EOF.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   146
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   147
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   148
        while True :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   149
            # pull line
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   150
            line = self.readline()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   151
18
48d94f45b242 pvl.syslog.fifo: fix difference between empty line and EOF
Tero Marttila <terom@paivola.fi>
parents: 2
diff changeset
   152
            if line is not None :
2
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   153
                yield line
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   154
            else :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   155
                return # block
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   156
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   157
    __iter__ = readlines
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   158
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   159
    def close (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   160
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
            Close our fd, if open.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
            May be open()'d again. Meanwhile, all operatations will raise EOFError.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   164
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   165
            log.warn's if already closed.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   166
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   167
        
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
        if self._fd is None :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   169
            log.warn("%s: already closed", self)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   171
        else :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
            log.debug("%s: %s", self, self._fd)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   173
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   174
            os.close(self._fd)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
            self._fd = None
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   176
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
    def __str__ (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   178
        return "pipe({self._fd})".format(self=self)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   180
class Fifo (Pipe) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
    """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   182
        A named pipe(7) on the filesystem.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   183
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   184
        Supports reading lines in a non-blocking fashion, and re-opening on EOF.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   185
    """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   186
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   187
    def __init__ (self, path) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   188
        self.path = path
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   189
        Pipe.__init__(self, self._open())
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   190
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   191
    def _open (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   192
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   193
            Open the internal fd (nonblocking).
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   194
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   195
        
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   196
        fd = os.open(self.path, os.O_RDONLY | os.O_NONBLOCK)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   197
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   198
        log.debug("%s: open: %s", self, fd)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   199
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   200
        return fd
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   201
   
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   202
    def open (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   203
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   204
            Re-open the FIFO.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   205
            
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   206
            Used when the writing end was closed, and read gave EOF. Opening the fifo again will clear the EOF condition,
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   207
            and resume nonblocking mode.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   208
            
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   209
            Raises ValueError() if already open. close() first.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   210
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   211
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   212
        Pipe.open(self, self._open())
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   213
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   214
    def readlines (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   215
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   216
            Read any available input, yielding lines.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   217
            
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
            Re-opens the FIFO on EOF.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   220
            Returns None if there was no more input available, or the fifo was re-opened after EOF.
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   221
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   222
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
        while True :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
            try :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   225
                # pull line
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   226
                line = self.readline()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   228
            except EOFError :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   229
                log.debug("%s: EOF: reopen", self)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   230
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   231
                # reopen and go back to waiting
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   232
                self.close()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
                self.open()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   234
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
                return
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   236
            
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
            if line is None :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   238
                log.debug("%s: EOF: wait", self)
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
                return # wait
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   240
            else :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   241
                yield line
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   242
    
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
    __iter__ = readlines
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   244
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   245
    def __str__ (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   246
        return self.path
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   248
    # XXX: we need to figure out what references we have lying around, and clean those out!
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
    def __del__ (self) :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   250
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   251
            Cleanup
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   252
        """
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   253
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   254
        if self._fd is not None :
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   255
            self.close()
5a8a32cbc944 import pvl.syslog from pvl-verkko
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   256