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).
495 496 497 |
# File 'lib/toys/utils/exec.rb', line 495 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.
515 516 517 |
# File 'lib/toys/utils/exec.rb', line 515 def exception @exception end |
#in ⇒ IO? (readonly)
The subcommand's standard input stream (which can be written to).
477 478 479 |
# File 'lib/toys/utils/exec.rb', line 477 def in @in end |
#name ⇒ Object (readonly)
The subcommand's name.
468 469 470 |
# File 'lib/toys/utils/exec.rb', line 468 def name @name end |
#out ⇒ IO? (readonly)
The subcommand's standard output stream (which can be read from).
486 487 488 |
# File 'lib/toys/utils/exec.rb', line 486 def out @out end |
#pid ⇒ Integer? (readonly)
The process ID.
Exactly one of #exception and #pid will be non-nil.
505 506 507 |
# File 'lib/toys/utils/exec.rb', line 505 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.
524 525 526 527 528 529 530 531 532 533 534 535 |
# File 'lib/toys/utils/exec.rb', line 524 def capture(which) stream = stream_for(which) @join_threads << ::Thread.new do data = stream.read @captures_mutex.synchronize do @captures[which] = data end ensure stream.close 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.
553 554 555 |
# File 'lib/toys/utils/exec.rb', line 553 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.
543 544 545 |
# File 'lib/toys/utils/exec.rb', line 543 def capture_out capture(:out) end |
#executing? ⇒ Boolean
Determine whether the subcommand is still executing
673 674 675 |
# File 'lib/toys/utils/exec.rb', line 673 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.
662 663 664 665 |
# File 'lib/toys/utils/exec.rb', line 662 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.
If the stream is redirected to an IO-like object, it is not closed when the process is completed. (If it is redirected to a file specified by path, the file is closed on completion.)
After calling this, do not interact directly with the stream.
577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 |
# File 'lib/toys/utils/exec.rb', line 577 def redirect(which, io, *io_args) io = ::File::NULL if io == :null close_afterward = false if io.is_a?(::String) io_args = which == :in ? ["r"] : ["w"] if io_args.empty? io = ::File.open(io, *io_args) close_afterward = true end stream = stream_for(which, allow_in: true) @join_threads << ::Thread.new do if which == :in ::IO.copy_stream(io, stream) else ::IO.copy_stream(stream, io) end ensure stream.close io.close if close_afterward 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.
651 652 653 |
# File 'lib/toys/utils/exec.rb', line 651 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.
614 615 616 |
# File 'lib/toys/utils/exec.rb', line 614 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.
633 634 635 |
# File 'lib/toys/utils/exec.rb', line 633 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.
685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
# File 'lib/toys/utils/exec.rb', line 685 def result(timeout: nil) return nil if @wait_thread && !@wait_thread.join(timeout) should_run_callback = false @result_mutex.synchronize do @result ||= begin should_run_callback = true close_streams(:both) @join_threads.each(&:join) Result.new(name, @captures[:out], @captures[:err], @wait_thread&.value, @exception) end end @result_callback&.call(@result) if should_run_callback @result end |