1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 """Implementation of the standard :mod:`subprocess` module that spawns greenlets"""
41 import errno
42 import sys
43 import fcntl, os
44
45 _subprocess = __import__('subprocess')
46
47 from gevent import socket, select, hub
48
49
50 CalledProcessError = _subprocess.CalledProcessError
51 MAXFD = _subprocess.MAXFD
52 PIPE = _subprocess.PIPE
53 STDOUT = _subprocess.STDOUT
54 call = _subprocess.call
55 check_call = _subprocess.check_call
56 list2cmdline = _subprocess.list2cmdline
57
58
61
62 self.__p = _subprocess.Popen(*args, **kwargs)
63
64 if self.stdin is not None:
65 fcntl.fcntl(self.stdin, fcntl.F_SETFL, os.O_NONBLOCK)
66 if self.stdout is not None:
67 fcntl.fcntl(self.stdout, fcntl.F_SETFL, os.O_NONBLOCK)
68 if self.stderr is not None:
69 fcntl.fcntl(self.stderr, fcntl.F_SETFL, os.O_NONBLOCK)
70
72
73 return getattr(self.__p, name)
74
76
77 if input:
78 bytes_total = len(input)
79 bytes_written = 0
80 while bytes_written < bytes_total:
81 try:
82
83 bytes_written += os.write(f.fileno(), input[bytes_written:])
84 except IOError, ex:
85 if ex[0] != errno.EAGAIN:
86 raise
87 sys.exc_clear()
88 socket.wait_write(f.fileno())
89 f.close()
90
92
93
94 chunks = []
95 while True:
96 try:
97 chunk = f.read(4096)
98 if not chunk:
99 break
100 chunks.append(chunk)
101 except IOError, ex:
102 if ex[0] != errno.EAGAIN:
103 raise
104 sys.exc_clear()
105 socket.wait_read(f.fileno())
106 f.close()
107 return ''.join(chunks)
108
110
111
112 if [self.stdin, self.stdout, self.stderr].count(None) >= 2:
113 stdout = None
114 stderr = None
115 if self.stdin:
116 self._write_pipe(self.stdin, input)
117 elif self.stdout:
118 stdout = self._read_pipe(self.stdout)
119 elif self.stderr:
120 stderr = self._read_pipe(self.stderr)
121 self.wait()
122 return (stdout, stderr)
123 else:
124 return self._communicate(input)
125
127
128
129 read_set = []
130 write_set = []
131 stdout = None
132 stderr = None
133
134 if self.stdin:
135
136 self.stdin.flush()
137 if input:
138 write_set.append(self.stdin)
139 else:
140 self.stdin.close()
141 if self.stdout:
142 read_set.append(self.stdout)
143 stdout = []
144 if self.stderr:
145 read_set.append(self.stderr)
146 stderr = []
147
148 input_offset = 0
149 while read_set or write_set:
150 try:
151 rlist, wlist, xlist = select.select(read_set, write_set, [])
152 except select.error, e:
153 if e.args[0] == errno.EINTR:
154 continue
155 raise
156
157 if self.stdin in wlist:
158
159
160
161 bytes_written = os.write(self.stdin.fileno(), buffer(input, input_offset, 512))
162 input_offset += bytes_written
163 if input_offset >= len(input):
164 self.stdin.close()
165 write_set.remove(self.stdin)
166
167 if self.stdout in rlist:
168 data = os.read(self.stdout.fileno(), 1024)
169 if data == "":
170 self.stdout.close()
171 read_set.remove(self.stdout)
172 stdout.append(data)
173
174 if self.stderr in rlist:
175 data = os.read(self.stderr.fileno(), 1024)
176 if data == "":
177 self.stderr.close()
178 read_set.remove(self.stderr)
179 stderr.append(data)
180
181
182 if stdout is not None:
183 stdout = ''.join(stdout)
184 if stderr is not None:
185 stderr = ''.join(stderr)
186
187
188
189
190
191 if self.universal_newlines and hasattr(file, 'newlines'):
192 if stdout:
193 stdout = self._translate_newlines(stdout)
194 if stderr:
195 stderr = self._translate_newlines(stderr)
196
197 self.wait()
198 return (stdout, stderr)
199
200 - def wait(self, check_interval=0.01):
201
202 try:
203 while True:
204 status = self.poll()
205 if status >= 0:
206 return status
207 hub.sleep(check_interval)
208 except OSError, e:
209 if e.errno == errno.ECHILD:
210
211
212 return -1
213 else:
214 raise
215