def launch_process
if @io
stdout = @io.stdout
stderr = @io.stderr
end
exec_r, exec_w = ::IO.pipe
ChildProcess.close_on_exec exec_w
if duplex?
reader, writer = ::IO.pipe
end
@pid = Kernel.fork {
::Process.setpgid 0, 0 if leader?
if @cwd
Dir.chdir(@cwd)
end
exec_r.close
set_env
if stdout
STDOUT.reopen(stdout)
else
STDOUT.reopen("/dev/null", "a+")
end
if stderr
STDERR.reopen(stderr)
else
STDERR.reopen("/dev/null", "a+")
end
if duplex?
STDIN.reopen(reader)
writer.close
end
executable, *args = @args
begin
Kernel.exec([executable, executable], *args)
rescue SystemCallError => ex
exec_w << ex.message
end
}
exec_w.close
if duplex?
io._stdin = writer
reader.close
end
unless exec_r.eof?
raise LaunchError, exec_r.read || "executing command with #{@args.inspect} failed"
end
::Process.detach(@pid) if detach?
end