# HG changeset patch # User jbe # Date 1497743905 -7200 # Node ID 42ddff7319e0a144e53fede990919775ff7a1deb # Parent 5b1c4f76e44fb8877726f350591fe688a82df415 Avoid blocking of execute.command{...} if child process closes file descriptors but doesn't terminate diff -r 5b1c4f76e44f -r 42ddff7319e0 framework/env/execute/command.lua --- a/framework/env/execute/command.lua Mon Jun 12 03:32:23 2017 +0200 +++ b/framework/env/execute/command.lua Sun Jun 18 01:58:25 2017 +0200 @@ -44,8 +44,14 @@ local process, errmsg = moonbridge_io.exec(table.unpack(args.command)) if not process then return nil, errmsg end - local read_fds = {[process.stdout] = true, [process.stderr] = true} - local write_fds = {[process.stdin] = true} + local read_fds = { + [process] = true, + [process.stdout] = true, + [process.stderr] = true + } + local write_fds = { + [process.stdin] = true + } if args.db then read_fds[args.db.fd] = true end @@ -61,7 +67,10 @@ end write(args.stdin_data or "") + local status + while + not status or read_fds[process.stdout] or read_fds[process.stderr] or write_fds[process.stdin] do @@ -69,7 +78,9 @@ local pollready, pollmsg, pollterm = poll(read_fds, write_fds, timeout, args.abortable) if not pollready then - process:kill():wait() + if not status then + process:kill():wait() + end if pollterm then if args.abort_handler then args.abort_handler(pollmsg) end else @@ -77,6 +88,12 @@ end return return_error(pollmsg) end + if not status then + status = process:wait_nb() + if status then + read_fds[process] = nil + end + end if args.db then local channel, payload, pid = db:wait(0) if channel then @@ -123,8 +140,6 @@ write() end - local status = process:wait() - if status < 0 then if args.signal_handler then args.signal_handler(-status)