summaryrefslogtreecommitdiffstats
path: root/subcmds/forall.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/forall.py')
-rw-r--r--subcmds/forall.py36
1 files changed, 16 insertions, 20 deletions
diff --git a/subcmds/forall.py b/subcmds/forall.py
index 07ee8d58..52eb5e28 100644
--- a/subcmds/forall.py
+++ b/subcmds/forall.py
@@ -15,17 +15,16 @@
15 15
16from __future__ import print_function 16from __future__ import print_function
17import errno 17import errno
18import fcntl
19import multiprocessing 18import multiprocessing
20import re 19import re
21import os 20import os
22import select
23import signal 21import signal
24import sys 22import sys
25import subprocess 23import subprocess
26 24
27from color import Coloring 25from color import Coloring
28from command import Command, MirrorSafeCommand 26from command import Command, MirrorSafeCommand
27import platform_utils
29 28
30_CAN_COLOR = [ 29_CAN_COLOR = [
31 'branch', 30 'branch',
@@ -105,6 +104,13 @@ annotating tree details.
105shell positional arguments ($1, $2, .., $#) are set to any arguments 104shell positional arguments ($1, $2, .., $#) are set to any arguments
106following <command>. 105following <command>.
107 106
107Example: to list projects:
108
109 %prog% forall -c 'echo $REPO_PROJECT'
110
111Notice that $REPO_PROJECT is quoted to ensure it is expanded in
112the context of running <command> instead of in the calling shell.
113
108Unless -p is used, stdin, stdout, stderr are inherited from the 114Unless -p is used, stdin, stdout, stderr are inherited from the
109terminal and are not redirected. 115terminal and are not redirected.
110 116
@@ -344,35 +350,25 @@ def DoWork(project, mirror, opt, cmd, shell, cnt, config):
344 if opt.project_header: 350 if opt.project_header:
345 out = ForallColoring(config) 351 out = ForallColoring(config)
346 out.redirect(sys.stdout) 352 out.redirect(sys.stdout)
347 class sfd(object):
348 def __init__(self, fd, dest):
349 self.fd = fd
350 self.dest = dest
351 def fileno(self):
352 return self.fd.fileno()
353
354 empty = True 353 empty = True
355 errbuf = '' 354 errbuf = ''
356 355
357 p.stdin.close() 356 p.stdin.close()
358 s_in = [sfd(p.stdout, sys.stdout), 357 s_in = platform_utils.FileDescriptorStreams.create()
359 sfd(p.stderr, sys.stderr)] 358 s_in.add(p.stdout, sys.stdout, 'stdout')
360 359 s_in.add(p.stderr, sys.stderr, 'stderr')
361 for s in s_in:
362 flags = fcntl.fcntl(s.fd, fcntl.F_GETFL)
363 fcntl.fcntl(s.fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
364 360
365 while s_in: 361 while not s_in.is_done:
366 in_ready, _out_ready, _err_ready = select.select(s_in, [], []) 362 in_ready = s_in.select()
367 for s in in_ready: 363 for s in in_ready:
368 buf = s.fd.read(4096) 364 buf = s.read()
369 if not buf: 365 if not buf:
370 s.fd.close() 366 s.close()
371 s_in.remove(s) 367 s_in.remove(s)
372 continue 368 continue
373 369
374 if not opt.verbose: 370 if not opt.verbose:
375 if s.fd != p.stdout: 371 if s.std_name == 'stderr':
376 errbuf += buf 372 errbuf += buf
377 continue 373 continue
378 374