def launch_process
pid_ptr = FFI::MemoryPointer.new(:pid_t)
actions = Lib::FileActions.new
attrs = Lib::Attrs.new
if io.stdout
actions.add_dup fileno_for(io.stdout), fileno_for(STDOUT)
else
actions.add_open fileno_for(STDOUT), "/dev/null", File::WRONLY, 0644
end
if io.stderr
actions.add_dup fileno_for(io.stderr), fileno_for(STDERR)
else
actions.add_open fileno_for(STDERR), "/dev/null", File::WRONLY, 0644
end
if duplex?
reader, writer = ::IO.pipe
actions.add_dup fileno_for(reader), fileno_for(STDIN)
actions.add_close fileno_for(writer)
end
attrs.pgroup = 0 if leader?
attrs.flags |= Platform::POSIX_SPAWN_USEVFORK if defined? Platform::POSIX_SPAWN_USEVFORK
argv = Argv.new(@args)
envp = Envp.new(ENV.to_hash.merge(@environment))
ret = 0
@@cwd_lock.synchronize do
Dir.chdir(@cwd || Dir.pwd) do
if ChildProcess.jruby?
Lib.chdir Dir.pwd
end
ret = Lib.posix_spawnp(
pid_ptr,
@args.first,
actions,
attrs,
argv,
envp
)
end
end
if duplex?
io._stdin = writer
reader.close
end
actions.free
attrs.free
if ret != 0
raise LaunchError, "#{Lib.strerror(ret)} (#{ret})"
end
@pid = pid_ptr.read_int
::Process.detach(@pid) if detach?
end