If using --log or -j > 1, disable stdin.

Parallelism and redo-log cause lots of confusion for any rules that try
to ask the user for questions, so disable it altogether.

Arguably, we should just disable stdin all the time, but maybe it's
still occasionally useful (even though you have to pass --no-log to get
it back).
This commit is contained in:
Avery Pennarun 2018-12-02 22:53:00 -05:00
commit 1966a0fac7
4 changed files with 17 additions and 4 deletions

View file

@ -38,6 +38,11 @@ instead.
A .do script can call redo recursively to build its A .do script can call redo recursively to build its
dependencies. dependencies.
To avoid confusion caused by multiple programs trying to
use the terminal, inside .do scripts, stdin is normally
redirected to /dev/null. The only exception is if the `-j`
option is *not* given and `--no-log` is used.
# OPTIONS # OPTIONS

View file

@ -22,9 +22,14 @@ def _try_stat(filename):
log_reader_pid = None log_reader_pid = None
def close_stdin():
f = open('/dev/null')
os.dup2(f.fileno(), 0)
f.close()
def start_stdin_log_reader(status, details, pretty, color, def start_stdin_log_reader(status, details, pretty, color,
debug_locks, debug_pids): debug_locks, debug_pids):
if not vars.LOG: return
global log_reader_pid global log_reader_pid
r, w = os.pipe() # main pipe to redo-log r, w = os.pipe() # main pipe to redo-log
ar, aw = os.pipe() # ack pipe from redo-log --ack-fd ar, aw = os.pipe() # ack pipe from redo-log --ack-fd

View file

@ -19,7 +19,8 @@ def should_build(t):
rv = 202 rv = 202
try: try:
if vars_init.is_toplevel: if vars_init.is_toplevel and vars.LOG:
builder.close_stdin()
builder.start_stdin_log_reader(status=True, details=True, builder.start_stdin_log_reader(status=True, details=True,
pretty=True, color=True, debug_locks=False, debug_pids=False) pretty=True, color=True, debug_locks=False, debug_pids=False)
if vars.TARGET and not vars.UNLOCKED: if vars.TARGET and not vars.UNLOCKED:

View file

@ -79,7 +79,10 @@ import vars, state, builder, jwack
from logs import warn, err from logs import warn, err
try: try:
if vars_init.is_toplevel: j = atoi(opt.jobs or 1)
if vars_init.is_toplevel and (vars.LOG or j > 1):
builder.close_stdin()
if vars_init.is_toplevel and vars.LOG:
builder.start_stdin_log_reader(status=opt.status, details=opt.details, builder.start_stdin_log_reader(status=opt.status, details=opt.details,
pretty=opt.pretty, color=opt.color, pretty=opt.pretty, color=opt.color,
debug_locks=opt.debug_locks, debug_pids=opt.debug_pids) debug_locks=opt.debug_locks, debug_pids=opt.debug_pids)
@ -91,7 +94,6 @@ try:
% f.nicename()) % f.nicename())
state.rollback() state.rollback()
j = atoi(opt.jobs or 1)
if j < 1 or j > 1000: if j < 1 or j > 1000:
err('invalid --jobs value: %r\n' % opt.jobs) err('invalid --jobs value: %r\n' % opt.jobs)
jwack.setup(j) jwack.setup(j)