class ChildProcess::ProcessSpawnProcess

Attributes

pid[R]

Public Instance Methods

exited?() click to toggle source
# File lib/childprocess/process_spawn_process.rb, line 7
def exited?
  return true if @exit_code

  assert_started
  pid, status = ::Process.waitpid2(@pid, ::Process::WNOHANG | ::Process::WUNTRACED)
  pid = nil if pid == 0 # may happen on jruby

  log(:pid => pid, :status => status)

  if pid
    set_exit_code(status)
  end

  !!pid
rescue Errno::ECHILD
  # may be thrown for detached processes
  true
end
wait() click to toggle source
# File lib/childprocess/process_spawn_process.rb, line 26
def wait
  assert_started

  if exited?
    exit_code
  else
    _, status = ::Process.waitpid2(@pid)

    set_exit_code(status)
  end
end

Private Instance Methods

launch_process() click to toggle source
# File lib/childprocess/process_spawn_process.rb, line 40
def launch_process
  environment = {}
  @environment.each_pair do |key, value|
    key = key.to_s
    value = value.nil? ? nil : value.to_s

    if key.include?("\0") || key.include?("=") || value.to_s.include?("\0")
      raise InvalidEnvironmentVariable, "#{key.inspect} => #{value.to_s.inspect}"
    end
    environment[key] = value
  end

  options = {}

  options[:out] = io.stdout ? io.stdout.fileno : File::NULL
  options[:err] = io.stderr ? io.stderr.fileno : File::NULL

  if duplex?
    reader, writer = ::IO.pipe
    options[:in] = reader.fileno
    unless ChildProcess.windows?
      options[writer.fileno] = :close
    end
  end

  if leader?
    if ChildProcess.windows?
      options[:new_pgroup] = true
    else
      options[:pgroup] = true
    end
  end

  options[:chdir] = @cwd if @cwd

  if @args.size == 1
    # When given a single String, Process.spawn would think it should use the shell
    # if there is any special character in it. However,  ChildProcess should never
    # use the shell. So we use the [cmdname, argv0] form to force no shell.
    arg = @args[0]
    args = [[arg, arg]]
  else
    args = @args
  end

  begin
    @pid = ::Process.spawn(environment, *args, options)
  rescue SystemCallError => e
    raise LaunchError, e.message
  end

  if duplex?
    io._stdin = writer
    reader.close
  end

  ::Process.detach(@pid) if detach?
end
send_kill() click to toggle source
# File lib/childprocess/process_spawn_process.rb, line 107
def send_kill
  send_signal 'KILL'
end
send_signal(sig) click to toggle source
# File lib/childprocess/process_spawn_process.rb, line 111
def send_signal(sig)
  assert_started

  log "sending #{sig}"
  if leader?
    if ChildProcess.unix?
      ::Process.kill sig, -@pid # negative pid == process group
    else
      output = `taskkill /F /T /PID #{@pid}`
      log output
    end
  else
    ::Process.kill sig, @pid
  end
end
send_term() click to toggle source
# File lib/childprocess/process_spawn_process.rb, line 103
def send_term
  send_signal 'TERM'
end
set_exit_code(status) click to toggle source
# File lib/childprocess/process_spawn_process.rb, line 99
def set_exit_code(status)
  @exit_code = status.exitstatus || status.termsig
end