Class: Toys::Utils::Exec::Controller

Inherits:
Object
  • Object
show all
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 may use this object to interact with the subcommand's streams, send signals to the process, and get its result.

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#errIO? (readonly)

Return the subcommand's standard error stream (which can be read from), if the command was configured with err: :controller. Returns nil otherwise.

Returns:

  • (IO, nil)


432
433
434
# File 'lib/toys/utils/exec.rb', line 432

def err
  @err
end

#inIO? (readonly)

Return the subcommand's standard input stream (which can be written to), if the command was configured with in: :controller. Returns nil otherwise.

Returns:

  • (IO, nil)


416
417
418
# File 'lib/toys/utils/exec.rb', line 416

def in
  @in
end

#outIO? (readonly)

Return the subcommand's standard output stream (which can be read from), if the command was configured with out: :controller. Returns nil otherwise.

Returns:

  • (IO, nil)


424
425
426
# File 'lib/toys/utils/exec.rb', line 424

def out
  @out
end

#pidInteger (readonly)

Returns the process ID.

Returns:

  • (Integer)


438
439
440
# File 'lib/toys/utils/exec.rb', line 438

def pid
  @pid
end

Instance Method Details

#capture(which) ⇒ Object

Captures the remaining data in the given stream. After calling this, do not read directly from the stream.

Parameters:

  • which (:out, :err)

    Which stream to capture



446
447
448
449
450
451
452
453
454
455
456
# File 'lib/toys/utils/exec.rb', line 446

def capture(which)
  stream = stream_for(which)
  @join_threads << ::Thread.new do
    begin
      @captures[which] = stream.read
    ensure
      stream.close
    end
  end
  self
end

#capture_errObject

Captures the remaining data in the stdandard error stream. After calling this, do not read directly from the stream.



470
471
472
# File 'lib/toys/utils/exec.rb', line 470

def capture_err
  capture(:err)
end

#capture_outObject

Captures the remaining data in the stdandard output stream. After calling this, do not read directly from the stream.



462
463
464
# File 'lib/toys/utils/exec.rb', line 462

def capture_out
  capture(:out)
end

#executing?Boolean

Determine whether the subcommand is still executing

Returns:

  • (Boolean)


579
580
581
# File 'lib/toys/utils/exec.rb', line 579

def executing?
  @wait_thread.status ? true : false
end

#kill(sig) ⇒ Object Also known as: signal

Send the given signal to the process. The signal may be specified by name or number.

Parameters:

  • sig (Integer, String)

    The signal to send.



569
570
571
# File 'lib/toys/utils/exec.rb', line 569

def kill(sig)
  ::Process.kill(sig, pid)
end

#redirect(which, io, *io_args) ⇒ Object

Redirects the remainder of the given stream.

You may specify the stream as an IO or IO-like object, or as a file specified by its path. If specifying a file, you may 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.

Parameters:

  • which (:in, :out, :err)

    Which stream to redirect

  • io (IO, StringIO, String, :null)

    Where to redirect the stream

  • io_args (Object...)

    The mode and permissions for opening the file, if redirecting to/from a file.



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
# File 'lib/toys/utils/exec.rb', line 489

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
end

#redirect_err(io, *io_args) ⇒ Object

Redirects the remainder of the standard error stream.

You may specify the stream as an IO or IO-like object, or as a file specified by its path. If specifying a file, you may optionally provide the mode and permissions for the call to File#open.

After calling this, do not interact directly with the stream.

Parameters:

  • io (IO, StringIO, String)

    Where to redirect the stream

  • io_args (Object...)

    The mode and permissions for opening the file, if redirecting to a file.



559
560
561
# File 'lib/toys/utils/exec.rb', line 559

def redirect_err(io, *io_args)
  redirect(:err, io, *io_args)
end

#redirect_in(io, *io_args) ⇒ Object

Redirects the remainder of the standard input stream.

You may specify the stream as an IO or IO-like object, or as a file specified by its path. If specifying a file, you may 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.

Parameters:

  • io (IO, StringIO, String, :null)

    Where to redirect the stream

  • io_args (Object...)

    The mode and permissions for opening the file, if redirecting from a file.



524
525
526
# File 'lib/toys/utils/exec.rb', line 524

def redirect_in(io, *io_args)
  redirect(:in, io, *io_args)
end

#redirect_out(io, *io_args) ⇒ Object

Redirects the remainder of the standard output stream.

You may specify the stream as an IO or IO-like object, or as a file specified by its path. If specifying a file, you may 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.

Parameters:

  • io (IO, StringIO, String, :null)

    Where to redirect the stream

  • io_args (Object...)

    The mode and permissions for opening the file, if redirecting to a file.



542
543
544
# File 'lib/toys/utils/exec.rb', line 542

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.

Parameters:

  • timeout (Numeric, nil) (defaults to: nil)

    The timeout in seconds, or nil to wait indefinitely.

Returns:



591
592
593
594
595
596
597
598
599
600
601
602
# File 'lib/toys/utils/exec.rb', line 591

def result(timeout: nil)
  return nil unless @wait_thread.join(timeout)
  @result ||= begin
    close_streams
    @join_threads.each(&:join)
    status = @wait_thread.value
    if @nonzero_status_handler && status.exitstatus != 0
      @nonzero_status_handler.call(status)
    end
    Result.new(@captures[:out], @captures[:err], status)
  end
end