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