Class: POSIX::Spawn::Child
- Inherits:
-
Object
- Object
- POSIX::Spawn::Child
- Includes:
- POSIX::Spawn
- Defined in:
- lib/posix/spawn/child.rb
Overview
POSIX::Spawn::Child includes logic for executing child processes and reading/writing from their standard input, output, and error streams. It’s designed to take all input in a single string and provides all output (stderr and stdout) as single strings and is therefore not well-suited to streaming large quantities of data in and out of commands.
Create and run a process to completion:
>> child = POSIX::Spawn::Child.new('git', '--help')
Retrieve stdout or stderr output:
>> child.out
=> "usage: git [--version] [--exec-path[=GIT_EXEC_PATH]]\n ..."
>> child.err
=> ""
Check process exit status information:
>> child.status
=> #<Process::Status: pid=80718,exited(0)>
To write data on the new process’s stdin immediately after spawning:
>> child = POSIX::Spawn::Child.new('bc', :input => '40 + 2')
>> child.out
"42\n"
Q: Why use POSIX::Spawn::Child instead of popen3, hand rolled fork/exec code, or Process::spawn?
-
It’s more efficient than popen3 and provides meaningful process hierarchies because it performs a single fork/exec. (popen3 double forks to avoid needing to collect the exit status and also calls Process::detach which creates a Ruby Thread!!!!).
-
It handles all max pipe buffer (PIPE_BUF) hang cases when reading and writing semi-large amounts of data. This is non-trivial to implement correctly and must be accounted for with popen3, spawn, or hand rolled fork/exec code.
-
It’s more portable than hand rolled pipe, fork, exec code because fork(2) and exec aren’t available on all platforms. In those cases, POSIX::Spawn::Child falls back to using whatever janky substitutes the platform provides.
Constant Summary
Constants included from POSIX::Spawn
Instance Attribute Summary collapse
-
#err ⇒ Object
readonly
All data written to the child process’s stderr stream as a String.
-
#out ⇒ Object
readonly
All data written to the child process’s stdout stream as a String.
-
#runtime ⇒ Object
readonly
Total command execution time (wall-clock time).
-
#status ⇒ Object
readonly
A Process::Status object with information on how the child exited.
Instance Method Summary collapse
-
#initialize(*args) ⇒ Child
constructor
Spawn a new process, write all input and read all output, and wait for the program to exit.
-
#success? ⇒ Boolean
Determine if the process did exit with a zero exit status.
Methods included from POSIX::Spawn
#_pspawn, #`, #fspawn, #popen4, #pspawn, #spawn, #system
Constructor Details
#initialize(*args) ⇒ Child
Spawn a new process, write all input and read all output, and wait for the program to exit. Supports the standard spawn interface as described in the POSIX::Spawn module documentation:
new([env], command, [argv1, ...], [options])
The following options are supported in addition to the standard POSIX::Spawn options:
:input => str Write str to the new process's standard input.
:timeout => int Maximum number of seconds to allow the process
to execute before aborting with a TimeoutExceeded
exception.
:max => total Maximum number of bytes of output to allow the
process to generate before aborting with a
MaximumOutputExceeded exception.
Returns a new Child instance whose underlying process has already executed to completion. The out, err, and status attributes are immediately available.
73 74 75 76 77 78 79 80 81 |
# File 'lib/posix/spawn/child.rb', line 73 def initialize(*args) @env, @argv, = extract_process_spawn_arguments(*args) @options = .dup @input = @options.delete(:input) @timeout = @options.delete(:timeout) @max = @options.delete(:max) @options.delete(:chdir) if @options[:chdir].nil? exec! end |
Instance Attribute Details
#err ⇒ Object (readonly)
All data written to the child process’s stderr stream as a String.
87 88 89 |
# File 'lib/posix/spawn/child.rb', line 87 def err @err end |
#out ⇒ Object (readonly)
All data written to the child process’s stdout stream as a String.
84 85 86 |
# File 'lib/posix/spawn/child.rb', line 84 def out @out end |
#runtime ⇒ Object (readonly)
Total command execution time (wall-clock time)
93 94 95 |
# File 'lib/posix/spawn/child.rb', line 93 def runtime @runtime end |
#status ⇒ Object (readonly)
A Process::Status object with information on how the child exited.
90 91 92 |
# File 'lib/posix/spawn/child.rb', line 90 def status @status end |
Instance Method Details
#success? ⇒ Boolean
Determine if the process did exit with a zero exit status.
96 97 98 |
# File 'lib/posix/spawn/child.rb', line 96 def success? @status && @status.success? end |