Coverage for /pythoncovmergedfiles/medio/medio/src/paramiko/paramiko/pipe.py: 28%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

85 statements  

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# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 

18 

19""" 

20Abstraction 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 

22impossible. 

23 

24The pipe acts like an Event, which can be set or cleared. When set, the pipe 

25will trigger as readable in `select <select.select>`. 

26""" 

27 

28import sys 

29import os 

30import socket 

31 

32 

33def make_pipe(): 

34 if sys.platform[:3] != "win": 

35 p = PosixPipe() 

36 else: 

37 p = WindowsPipe() 

38 return p 

39 

40 

41class PosixPipe: 

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 

74class WindowsPipe: 

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 

80 def __init__(self): 

81 serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

82 serv.bind(("127.0.0.1", 0)) 

83 serv.listen(1) 

84 

85 # need to save sockets in _rsock/_wsock so they don't get closed 

86 self._rsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

87 self._rsock.connect(("127.0.0.1", serv.getsockname()[1])) 

88 

89 self._wsock, addr = serv.accept() 

90 serv.close() 

91 self._set = False 

92 self._forever = False 

93 self._closed = False 

94 

95 def close(self): 

96 self._rsock.close() 

97 self._wsock.close() 

98 # used for unit tests: 

99 self._closed = True 

100 

101 def fileno(self): 

102 return self._rsock.fileno() 

103 

104 def clear(self): 

105 if not self._set or self._forever: 

106 return 

107 self._rsock.recv(1) 

108 self._set = False 

109 

110 def set(self): 

111 if self._set or self._closed: 

112 return 

113 self._set = True 

114 self._wsock.send(b"*") 

115 

116 def set_forever(self): 

117 self._forever = True 

118 self.set() 

119 

120 

121class OrPipe: 

122 def __init__(self, pipe): 

123 self._set = False 

124 self._partner = None 

125 self._pipe = pipe 

126 

127 def set(self): 

128 self._set = True 

129 if not self._partner._set: 

130 self._pipe.set() 

131 

132 def clear(self): 

133 self._set = False 

134 if not self._partner._set: 

135 self._pipe.clear() 

136 

137 

138def make_or_pipe(pipe): 

139 """ 

140 wraps a pipe into two pipe-like objects which are "or"d together to 

141 affect the real pipe. if either returned pipe is set, the wrapped pipe 

142 is set. when both are cleared, the wrapped pipe is cleared. 

143 """ 

144 p1 = OrPipe(pipe) 

145 p2 = OrPipe(pipe) 

146 p1._partner = p2 

147 p2._partner = p1 

148 return p1, p2