Class: Toys::Utils::Exec::Controller
- Inherits:
-
Object
- Object
- Toys::Utils::Exec::Controller
- Defined in:
- lib/toys/utils/exec.rb
Overview
An object that controls a subprocess. This object is returned from an execution running in the background, or is yielded to a control block for an execution running in the foreground. You can use this object to interact with the subcommand's streams, send signals to the process, and get its result.
Instance Attribute Summary collapse
-
#err ⇒ IO?
readonly
The subcommand's standard error stream (which can be read from).
-
#exception ⇒ Exception?
readonly
The exception raised when the process failed to start.
-
#in ⇒ IO?
readonly
The subcommand's standard input stream (which can be written to).
-
#name ⇒ Object
readonly
The subcommand's name.
-
#out ⇒ IO?
readonly
The subcommand's standard output stream (which can be read from).
-
#pid ⇒ Integer?
readonly
The process ID.
Instance Method Summary collapse
-
#capture(which) ⇒ self
Captures the remaining data in the given stream.
-
#capture_err ⇒ self
Captures the remaining data in the standard error stream.
-
#capture_out ⇒ self
Captures the remaining data in the standard output stream.
-
#executing? ⇒ Boolean
Determine whether the subcommand is still executing.
-
#kill(sig) ⇒ self
(also: #signal)
Send the given signal to the process.
-
#redirect(which, io, *io_args) ⇒ self
Redirects the remainder of the given stream.
-
#redirect_err(io, *io_args) ⇒ self
Redirects the remainder of the standard error stream.
-
#redirect_in(io, *io_args) ⇒ self
Redirects the remainder of the standard input stream.
-
#redirect_out(io, *io_args) ⇒ self
Redirects the remainder of the standard output stream.
-
#result(timeout: nil) ⇒ Toys::Utils::Exec::Result?
Wait for the subcommand to complete, and return a result object.
Instance Attribute Details
#err ⇒ IO? (readonly)
The subcommand's standard error stream (which can be read from).
472 473 474 |
# File 'lib/toys/utils/exec.rb', line 472 def err @err end |
#exception ⇒ Exception? (readonly)
The exception raised when the process failed to start.
Exactly one of #exception and #pid will be non-nil.
492 493 494 |
# File 'lib/toys/utils/exec.rb', line 492 def exception @exception end |
#in ⇒ IO? (readonly)
The subcommand's standard input stream (which can be written to).
454 455 456 |
# File 'lib/toys/utils/exec.rb', line 454 def in @in end |
#name ⇒ Object (readonly)
The subcommand's name.
445 446 447 |
# File 'lib/toys/utils/exec.rb', line 445 def name @name end |
#out ⇒ IO? (readonly)
The subcommand's standard output stream (which can be read from).
463 464 465 |
# File 'lib/toys/utils/exec.rb', line 463 def out @out end |
#pid ⇒ Integer? (readonly)
The process ID.
Exactly one of #exception and #pid will be non-nil.
482 483 484 |
# File 'lib/toys/utils/exec.rb', line 482 def pid @pid end |
Instance Method Details
#capture(which) ⇒ self
Captures the remaining data in the given stream. After calling this, do not read directly from the stream.
501 502 503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/toys/utils/exec.rb', line 501 def capture(which) stream = stream_for(which) @join_threads << ::Thread.new do begin data = stream.read @mutex.synchronize do @captures[which] = data end ensure stream.close end end self end |
#capture_err ⇒ self
Captures the remaining data in the standard error stream. After calling this, do not read directly from the stream.
532 533 534 |
# File 'lib/toys/utils/exec.rb', line 532 def capture_err capture(:err) end |
#capture_out ⇒ self
Captures the remaining data in the standard output stream. After calling this, do not read directly from the stream.
522 523 524 |
# File 'lib/toys/utils/exec.rb', line 522 def capture_out capture(:out) end |
#executing? ⇒ Boolean
Determine whether the subcommand is still executing
648 649 650 |
# File 'lib/toys/utils/exec.rb', line 648 def executing? @wait_thread&.status ? true : false end |
#kill(sig) ⇒ self Also known as: signal
Send the given signal to the process. The signal can be specified by name or number.
637 638 639 640 |
# File 'lib/toys/utils/exec.rb', line 637 def kill(sig) ::Process.kill(sig, pid) if pid self end |
#redirect(which, io, *io_args) ⇒ self
Redirects the remainder of the given stream.
You can specify the stream as an IO or IO-like object, or as a file
specified by its path. If specifying a file, you can optionally
provide the mode and permissions for the call to File#open. You can
also specify the value :null to indicate the null file.
After calling this, do not interact directly with the stream.
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
# File 'lib/toys/utils/exec.rb', line 552 def redirect(which, io, *io_args) io = ::File::NULL if io == :null if io.is_a?(::String) io_args = which == :in ? ["r"] : ["w"] if io_args.empty? io = ::File.open(io, *io_args) end stream = stream_for(which, allow_in: true) @join_threads << ::Thread.new do begin if which == :in ::IO.copy_stream(io, stream) else ::IO.copy_stream(stream, io) end ensure stream.close io.close end end self end |
#redirect_err(io, *io_args) ⇒ self
Redirects the remainder of the standard error stream.
You can specify the stream as an IO or IO-like object, or as a file
specified by its path. If specifying a file, you can optionally
provide the mode and permissions for the call to File#open.
After calling this, do not interact directly with the stream.
626 627 628 |
# File 'lib/toys/utils/exec.rb', line 626 def redirect_err(io, *io_args) redirect(:err, io, *io_args) end |
#redirect_in(io, *io_args) ⇒ self
Redirects the remainder of the standard input stream.
You can specify the stream as an IO or IO-like object, or as a file
specified by its path. If specifying a file, you can optionally
provide the mode and permissions for the call to File#open. You can
also specify the value :null to indicate the null file.
After calling this, do not interact directly with the stream.
589 590 591 |
# File 'lib/toys/utils/exec.rb', line 589 def redirect_in(io, *io_args) redirect(:in, io, *io_args) end |
#redirect_out(io, *io_args) ⇒ self
Redirects the remainder of the standard output stream.
You can specify the stream as an IO or IO-like object, or as a file
specified by its path. If specifying a file, you can optionally
provide the mode and permissions for the call to File#open. You can
also specify the value :null to indicate the null file.
After calling this, do not interact directly with the stream.
608 609 610 |
# File 'lib/toys/utils/exec.rb', line 608 def redirect_out(io, *io_args) redirect(:out, io, *io_args) end |
#result(timeout: nil) ⇒ Toys::Utils::Exec::Result?
Wait for the subcommand to complete, and return a result object.
Closes the control streams if present. The stdin stream is always closed, even if the call times out. The stdout and stderr streams are closed only after the command terminates.
664 665 666 667 668 669 670 671 672 673 |
# File 'lib/toys/utils/exec.rb', line 664 def result(timeout: nil) close_streams(:in) return nil if @wait_thread && !@wait_thread.join(timeout) @result ||= begin close_streams(:out) @join_threads.each(&:join) Result.new(name, @captures[:out], @captures[:err], @wait_thread&.value, @exception) .tap { |result| @result_callback&.call(result) } end end |