aboutsummaryrefslogtreecommitdiff
path: root/paramiko/pipe.py
diff options
context:
space:
mode:
authorJeremy T. Bouse <jbouse@debian.org>2009-11-27 16:20:12 -0500
committerJeremy T. Bouse <jbouse@debian.org>2009-11-27 16:20:12 -0500
commited280d5ac360e2af796e9bd973d7b4df89f0c449 (patch)
treece892d6ce9dad8c0ecbc9cbe73f8095195bef0b4 /paramiko/pipe.py
parent176c6caf4ea7918e1698438634b237fab8456471 (diff)
downloadpython-paramiko-ed280d5ac360e2af796e9bd973d7b4df89f0c449.tar
python-paramiko-ed280d5ac360e2af796e9bd973d7b4df89f0c449.tar.gz
Imported Upstream version 1.7.4upstream/1.7.4
Diffstat (limited to 'paramiko/pipe.py')
-rw-r--r--paramiko/pipe.py52
1 files changed, 47 insertions, 5 deletions
diff --git a/paramiko/pipe.py b/paramiko/pipe.py
index cc28f43..1cfed2d 100644
--- a/paramiko/pipe.py
+++ b/paramiko/pipe.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2003-2005 Robey Pointer <robey@lag.net>
+# Copyright (C) 2003-2007 Robey Pointer <robey@lag.net>
#
# This file is part of paramiko.
#
@@ -19,6 +19,9 @@
"""
Abstraction of a one-way pipe where the read end can be used in select().
Normally this is trivial, but Windows makes it nearly impossible.
+
+The pipe acts like an Event, which can be set or cleared. When set, the pipe
+will trigger as readable in select().
"""
import sys
@@ -28,8 +31,10 @@ import socket
def make_pipe ():
if sys.platform[:3] != 'win':
- return PosixPipe()
- return WindowsPipe()
+ p = PosixPipe()
+ else:
+ p = WindowsPipe()
+ return p
class PosixPipe (object):
@@ -37,10 +42,13 @@ class PosixPipe (object):
self._rfd, self._wfd = os.pipe()
self._set = False
self._forever = False
+ self._closed = False
def close (self):
os.close(self._rfd)
os.close(self._wfd)
+ # used for unit tests:
+ self._closed = True
def fileno (self):
return self._rfd
@@ -52,7 +60,7 @@ class PosixPipe (object):
self._set = False
def set (self):
- if self._set:
+ if self._set or self._closed:
return
self._set = True
os.write(self._wfd, '*')
@@ -80,10 +88,13 @@ class WindowsPipe (object):
serv.close()
self._set = False
self._forever = False
+ self._closed = False
def close (self):
self._rsock.close()
self._wsock.close()
+ # used for unit tests:
+ self._closed = True
def fileno (self):
return self._rsock.fileno()
@@ -95,7 +106,7 @@ class WindowsPipe (object):
self._set = False
def set (self):
- if self._set:
+ if self._set or self._closed:
return
self._set = True
self._wsock.send('*')
@@ -103,3 +114,34 @@ class WindowsPipe (object):
def set_forever (self):
self._forever = True
self.set()
+
+
+class OrPipe (object):
+ def __init__(self, pipe):
+ self._set = False
+ self._partner = None
+ self._pipe = pipe
+
+ def set(self):
+ self._set = True
+ if not self._partner._set:
+ self._pipe.set()
+
+ def clear(self):
+ self._set = False
+ if not self._partner._set:
+ self._pipe.clear()
+
+
+def make_or_pipe(pipe):
+ """
+ wraps a pipe into two pipe-like objects which are "or"d together to
+ affect the real pipe. if either returned pipe is set, the wrapped pipe
+ is set. when both are cleared, the wrapped pipe is cleared.
+ """
+ p1 = OrPipe(pipe)
+ p2 = OrPipe(pipe)
+ p1._partner = p2
+ p2._partner = p1
+ return p1, p2
+