def launch_process
pid_ptr = FFI::MemoryPointer.new(:pid_t)
actions = Lib::FileActions.new
attrs = Lib::Attrs.new
flags = 0
if @io
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
end
if duplex?
reader, writer = ::IO.pipe
actions.add_dup fileno_for(reader), fileno_for($stdin)
actions.add_close fileno_for(writer)
end
if defined? Platform::POSIX_SPAWN_USEVFORK
flags |= Platform::POSIX_SPAWN_USEVFORK
end
attrs.flags = flags
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