Revision 9c233417
b/lib/utils.py | ||
---|---|---|
36 | 36 |
import errno |
37 | 37 |
import pwd |
38 | 38 |
import itertools |
39 |
import select |
|
40 |
import fcntl |
|
41 |
|
|
42 |
from cStringIO import StringIO |
|
39 | 43 |
|
40 | 44 |
from ganeti import logger |
41 | 45 |
from ganeti import errors |
... | ... | |
222 | 226 |
shell = True |
223 | 227 |
env = os.environ.copy() |
224 | 228 |
env["LC_ALL"] = "C" |
229 |
poller = select.poll() |
|
225 | 230 |
child = subprocess.Popen(cmd, shell=shell, |
226 | 231 |
stderr=subprocess.PIPE, |
227 | 232 |
stdout=subprocess.PIPE, |
... | ... | |
229 | 234 |
close_fds=True, env=env) |
230 | 235 |
|
231 | 236 |
child.stdin.close() |
232 |
out = child.stdout.read() |
|
233 |
err = child.stderr.read() |
|
237 |
poller.register(child.stdout, select.POLLIN) |
|
238 |
poller.register(child.stderr, select.POLLIN) |
|
239 |
out = StringIO() |
|
240 |
err = StringIO() |
|
241 |
fdmap = { |
|
242 |
child.stdout.fileno(): (out, child.stdout), |
|
243 |
child.stderr.fileno(): (err, child.stderr), |
|
244 |
} |
|
245 |
for fd in fdmap: |
|
246 |
status = fcntl.fcntl(fd, fcntl.F_GETFL) |
|
247 |
fcntl.fcntl(fd, fcntl.F_SETFL, status | os.O_NONBLOCK) |
|
248 |
|
|
249 |
while fdmap: |
|
250 |
for fd, event in poller.poll(): |
|
251 |
if event & select.POLLIN or event & select.POLLPRI: |
|
252 |
data = fdmap[fd][1].read() |
|
253 |
# no data from read signifies EOF (the same as POLLHUP) |
|
254 |
if not data: |
|
255 |
poller.unregister(fd) |
|
256 |
del fdmap[fd] |
|
257 |
continue |
|
258 |
fdmap[fd][0].write(data) |
|
259 |
if (event & select.POLLNVAL or event & select.POLLHUP or |
|
260 |
event & select.POLLERR): |
|
261 |
poller.unregister(fd) |
|
262 |
del fdmap[fd] |
|
263 |
|
|
264 |
out = out.getvalue() |
|
265 |
err = err.getvalue() |
|
234 | 266 |
|
235 | 267 |
status = child.wait() |
236 | 268 |
if status >= 0: |
Also available in: Unified diff