webmcp

changeset 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 b29e082cafb8
files framework/env/execute/command.lua
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)

Impressum / About Us