def fspawn(*args)
env, argv, options = extract_process_spawn_arguments(*args)
valid_options = [:chdir, :unsetenv_others, :pgroup]
if badopt = options.find{ |key,val| !fd?(key) && !valid_options.include?(key) }
raise ArgumentError, "Invalid option: #{badopt[0].inspect}"
elsif !argv.is_a?(Array) || !argv[0].is_a?(Array) || argv[0].size != 2
raise ArgumentError, "Invalid command name"
end
fork do
begin
options.each do |key, val|
if fd?(key)
key = fd_to_io(key)
if fd?(val)
val = fd_to_io(val)
key.reopen(val)
elsif val == :close
if key.respond_to?(:close_on_exec=)
key.close_on_exec = true
else
key.close
end
elsif val.is_a?(Array)
file, mode_string, perms = *val
key.reopen(File.open(file, mode_string, perms))
end
end
end
ENV.replace({}) if options[:unsetenv_others] == true
env.each { |k, v| ENV[k] = v }
::Dir.chdir(options[:chdir]) if options[:chdir]
pgroup = options[:pgroup]
pgroup = 0 if pgroup == true
Process::setpgid(0, pgroup) if pgroup
::Kernel::exec(*argv)
ensure
exit!(127)
end
end
end