--- a/pvl/syslog/fifo.py Sun Jan 13 12:57:49 2013 +0200
+++ b/pvl/syslog/fifo.py Sun Jan 13 12:59:05 2013 +0200
@@ -36,14 +36,43 @@
return cls(fd)
def __init__ (self, fd) :
+ """
+ May pass fd=None to open as closed.
+ """
+
self._fd = fd
self._buf = ''
log.debug("pipe: %d", fd)
+ def open (self, fd) :
+ """
+ re-open closed pipe to use the given fd.
+
+ Raises ValueError if already open.
+ """
+
+ if self._fd is None :
+ self._fd = fd
+ else :
+ raise ValueError("%s: re-opening already open pipe: %s" % (self, fd))
+
+ # XXX: good idea?
+ def __nonzero__ (self) :
+ """
+ Test if we are open.
+
+ XXX: signal EOF as well?
+ """
+
+ return self._fd is not None
+
def fileno (self) :
"""
- Fetch the internal fd, failing if we are not open..
+ Return the internal fd.
+
+ Raises ValueError if we are closed.
+ XXX: EOFError?
"""
if self._fd is None :
@@ -57,7 +86,7 @@
Read up to n bytes.
Returns None if we would block.
- Raises EOFError on EOF.
+ Raises EOFError on EOF, or closed.
"""
try :
@@ -127,8 +156,26 @@
__iter__ = readlines
+ def close (self) :
+ """
+ Close our fd, if open.
+
+ May be open()'d again. Meanwhile, all operatations will raise EOFError.
+
+ log.warn's if already closed.
+ """
+
+ if self._fd is None :
+ log.warn("%s: already closed", self)
+
+ else :
+ log.debug("%s: %s", self, self._fd)
+
+ os.close(self._fd)
+ self._fd = None
+
def __str__ (self) :
- return "pipe:{self._fd}".format(self=self)
+ return "pipe({self._fd})".format(self=self)
class Fifo (Pipe) :
"""
@@ -151,22 +198,18 @@
log.debug("%s: open: %s", self, fd)
return fd
-
- def _close (self, fd) :
+
+ def open (self) :
"""
- Close.
+ Re-open the FIFO.
+
+ Used when the writing end was closed, and read gave EOF. Opening the fifo again will clear the EOF condition,
+ and resume nonblocking mode.
+
+ Raises ValueError() if already open. close() first.
"""
- os.close(fd)
-
- def _reopen (self) :
- """
- Re-open the FIFO in case the writing end was closed, and read gave EOF.
- """
-
- self._close(self._fd)
- self._fd = None
- self._fd = self._open()
+ self.open(self._open())
def readlines (self) :
"""
@@ -186,7 +229,8 @@
log.debug("%s: EOF: reopen", self)
# reopen and go back to waiting
- self._reopen()
+ self.close()
+ self.open()
return
@@ -198,20 +242,15 @@
__iter__ = readlines
- def close (self) :
- """
- Close the fifo.
- """
+ def __str__ (self) :
+ return self.path
- self._close(self.fileno())
- self._fd = None
-
+ # XXX: we need to figure out what references we have lying around, and clean those out!
def __del__ (self) :
"""
Cleanup
"""
if self._fd is not None :
- self._close(self._fd)
- self._fd = None
-
+ self.close()
+