webmcp
diff framework/env/execute/command.lua @ 489:42ddff7319e0
Avoid blocking of execute.command{...} if child process closes file descriptors but doesn't terminate
author | jbe |
---|---|
date | Sun Jun 18 01:58:25 2017 +0200 (2017-06-18) |
parents | 5b1c4f76e44f |
children |
line diff
1.1 --- a/framework/env/execute/command.lua Mon Jun 12 03:32:23 2017 +0200 1.2 +++ b/framework/env/execute/command.lua Sun Jun 18 01:58:25 2017 +0200 1.3 @@ -44,8 +44,14 @@ 1.4 local process, errmsg = moonbridge_io.exec(table.unpack(args.command)) 1.5 if not process then return nil, errmsg end 1.6 1.7 - local read_fds = {[process.stdout] = true, [process.stderr] = true} 1.8 - local write_fds = {[process.stdin] = true} 1.9 + local read_fds = { 1.10 + [process] = true, 1.11 + [process.stdout] = true, 1.12 + [process.stderr] = true 1.13 + } 1.14 + local write_fds = { 1.15 + [process.stdin] = true 1.16 + } 1.17 if args.db then 1.18 read_fds[args.db.fd] = true 1.19 end 1.20 @@ -61,7 +67,10 @@ 1.21 end 1.22 write(args.stdin_data or "") 1.23 1.24 + local status 1.25 + 1.26 while 1.27 + not status or 1.28 read_fds[process.stdout] or read_fds[process.stderr] or 1.29 write_fds[process.stdin] 1.30 do 1.31 @@ -69,7 +78,9 @@ 1.32 local pollready, pollmsg, pollterm = 1.33 poll(read_fds, write_fds, timeout, args.abortable) 1.34 if not pollready then 1.35 - process:kill():wait() 1.36 + if not status then 1.37 + process:kill():wait() 1.38 + end 1.39 if pollterm then 1.40 if args.abort_handler then args.abort_handler(pollmsg) end 1.41 else 1.42 @@ -77,6 +88,12 @@ 1.43 end 1.44 return return_error(pollmsg) 1.45 end 1.46 + if not status then 1.47 + status = process:wait_nb() 1.48 + if status then 1.49 + read_fds[process] = nil 1.50 + end 1.51 + end 1.52 if args.db then 1.53 local channel, payload, pid = db:wait(0) 1.54 if channel then 1.55 @@ -123,8 +140,6 @@ 1.56 write() 1.57 end 1.58 1.59 - local status = process:wait() 1.60 - 1.61 if status < 0 then 1.62 if args.signal_handler then 1.63 args.signal_handler(-status)