Class: R10K::Util::Subprocess::POSIX::Runner Private

Inherits:
Runner
  • Object
show all
Defined in:
lib/r10k/util/subprocess/posix/runner.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Implement a POSIX command runner by using fork/exec.

This implementation is optimized to run commands in the background, and has a few noteworthy implementation details.

First off, when the child process is forked, it calls setsid() to detach from the controlling TTY. This has two main ramifications: sending signals will never be send to the forked process, and the forked process does not have access to stdin.

Instance Attribute Summary

Attributes inherited from Runner

#cwd, #io, #pid, #result, #status

Instance Method Summary collapse

Constructor Details

#initialize(argv) ⇒ Runner

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Runner.



16
17
18
19
20
21
# File 'lib/r10k/util/subprocess/posix/runner.rb', line 16

def initialize(argv)
  @argv = argv
  @io = R10K::Util::Subprocess::POSIX::IO.new

  attach_pipes
end

Instance Method Details

#crashed?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


59
60
61
# File 'lib/r10k/util/subprocess/posix/runner.rb', line 59

def crashed?
  exit_code != 0
end

#exit_codeObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



63
64
65
# File 'lib/r10k/util/subprocess/posix/runner.rb', line 63

def exit_code
  @status.exitstatus
end

#runObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



53
54
55
56
57
# File 'lib/r10k/util/subprocess/posix/runner.rb', line 53

def run
  start
  wait
  @result
end

#startObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/r10k/util/subprocess/posix/runner.rb', line 23

def start
  exec_r, exec_w = status_pipe()


  @pid = fork do
    exec_r.close
    execute_child(exec_w)
  end

  exec_w.close
  execute_parent(exec_r)
end

#waitObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/r10k/util/subprocess/posix/runner.rb', line 36

def wait
  if @pid
    _, @status = Process.waitpid2(@pid)
  end

  stdout = @stdout_r.read
  # Use non-blocking read for stderr_r to work around an issue with OpenSSH
  # ControlPersist: https://bugzilla.mindrot.org/show_bug.cgi?id=1988
  # Blocking should not occur in any other case since the process that was
  # attached to the pipe has already terminated.
  stderr = read_nonblock(@stderr_r)

  @stdout_r.close
  @stderr_r.close
  @result = R10K::Util::Subprocess::Result.new(@argv, stdout, stderr, @status.exitstatus)
end