Package paramiko :: Module pipe
[frames] | no frames]

Source Code for Module paramiko.pipe

  1  # Copyright (C) 2003-2007  Robey Pointer <robeypointer@gmail.com> 
  2  # 
  3  # This file is part of paramiko. 
  4  # 
  5  # Paramiko is free software; you can redistribute it and/or modify it under the 
  6  # terms of the GNU Lesser General Public License as published by the Free 
  7  # Software Foundation; either version 2.1 of the License, or (at your option) 
  8  # any later version. 
  9  # 
 10  # Paramiko is distributed in the hope that it will be useful, but WITHOUT ANY 
 11  # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 
 12  # A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 13  # details. 
 14  # 
 15  # You should have received a copy of the GNU Lesser General Public License 
 16  # along with Paramiko; if not, write to the Free Software Foundation, Inc., 
 17  # 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA. 
 18   
 19  """ 
 20  Abstraction of a one-way pipe where the read end can be used in 
 21  `select.select`. Normally this is trivial, but Windows makes it nearly 
 22  impossible. 
 23   
 24  The pipe acts like an Event, which can be set or cleared. When set, the pipe 
 25  will trigger as readable in `select <select.select>`. 
 26  """ 
 27   
 28  import sys 
 29  import os 
 30  import socket 
 31   
 32   
33 -def make_pipe():
34 if sys.platform[:3] != 'win': 35 p = PosixPipe() 36 else: 37 p = WindowsPipe() 38 return p
39 40
41 -class PosixPipe (object):
42 - def __init__(self):
43 self._rfd, self._wfd = os.pipe() 44 self._set = False 45 self._forever = False 46 self._closed = False
47
48 - def close(self):
49 os.close(self._rfd) 50 os.close(self._wfd) 51 # used for unit tests: 52 self._closed = True
53
54 - def fileno(self):
55 return self._rfd
56
57 - def clear(self):
58 if not self._set or self._forever: 59 return 60 os.read(self._rfd, 1) 61 self._set = False
62
63 - def set(self):
64 if self._set or self._closed: 65 return 66 self._set = True 67 os.write(self._wfd, b'*')
68
69 - def set_forever(self):
70 self._forever = True 71 self.set()
72 73
74 -class WindowsPipe (object):
75 """ 76 On Windows, only an OS-level "WinSock" may be used in select(), but reads 77 and writes must be to the actual socket object. 78 """
79 - def __init__(self):
80 serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 81 serv.bind(('127.0.0.1', 0)) 82 serv.listen(1) 83 84 # need to save sockets in _rsock/_wsock so they don't get closed 85 self._rsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 86 self._rsock.connect(('127.0.0.1', serv.getsockname()[1])) 87 88 self._wsock, addr = serv.accept() 89 serv.close() 90 self._set = False 91 self._forever = False 92 self._closed = False
93
94 - def close(self):
95 self._rsock.close() 96 self._wsock.close() 97 # used for unit tests: 98 self._closed = True
99
100 - def fileno(self):
101 return self._rsock.fileno()
102
103 - def clear (self):
104 if not self._set or self._forever: 105 return 106 self._rsock.recv(1) 107 self._set = False
108
109 - def set (self):
110 if self._set or self._closed: 111 return 112 self._set = True 113 self._wsock.send(b'*')
114
115 - def set_forever (self):
116 self._forever = True 117 self.set()
118 119
120 -class OrPipe (object):
121 - def __init__(self, pipe):
122 self._set = False 123 self._partner = None 124 self._pipe = pipe
125
126 - def set(self):
127 self._set = True 128 if not self._partner._set: 129 self._pipe.set()
130
131 - def clear(self):
132 self._set = False 133 if not self._partner._set: 134 self._pipe.clear()
135 136
137 -def make_or_pipe(pipe):
138 """ 139 wraps a pipe into two pipe-like objects which are "or"d together to 140 affect the real pipe. if either returned pipe is set, the wrapped pipe 141 is set. when both are cleared, the wrapped pipe is cleared. 142 """ 143 p1 = OrPipe(pipe) 144 p2 = OrPipe(pipe) 145 p1._partner = p2 146 p2._partner = p1 147 return p1, p2
148