Class: ProcessWatcher::ProcessMonitor

Inherits:
Object
  • Object
show all
Includes:
Windows::Handle, Windows::Process, Windows::Synchronize
Defined in:
lib/process_watcher/linux/process_monitor.rb,
lib/process_watcher/win32/process_monitor.rb

Overview

Windows specific watcher implementation

Defined Under Namespace

Classes: Status

Instance Method Summary collapse

Instance Method Details

#cleanupObject

Cleanup underlying handle

Return

true

Always return true



96
97
98
99
# File 'lib/process_watcher/linux/process_monitor.rb', line 96

def cleanup
  @reader.join if @reader
  @io.close if @io && !@io.closed?
end

#spawn(cmd, *args) ⇒ Object

Spawn given process and callback given block with output and exit code

Parameters

cmd(String)

Process command line (including arguments)

arg1(String)

Optional, first command-line argumument

arg2(String)

Optional, first command-line argumument

argN(String)

Optional, Nth command-line argumument

Block

Given block should take one argument which is a hash which may contain the keys :output and :exit_code. The value associated with :output is a chunk of output while the value associated with :exit_code is the process exit code This block won’t be called anymore once the :exit_code key has associated value

Return

pid(Integer)

Spawned process pid



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/process_watcher/linux/process_monitor.rb', line 46

def spawn(cmd, *args)
  args = args.map { |a| a.to_s } #exec only likes string arguments

  #Run subprocess; capture its output using a pipe
  pr, pw = IO::pipe
  @pid = fork do
    oldstderr = STDERR.clone
    pr.close
    STDIN.close
    STDOUT.reopen(pw)
    STDERR.reopen(pw)
    begin
      exec(cmd, *args)
    rescue
      oldstderr.puts "Couldn't exec: #{$!}"
    end
  end

  #Monitor subprocess output and status in a dedicated thread
  pw.close
  @io = pr
  @reader = Thread.new do
    status = nil
    loop do
      status = Process.waitpid(@pid, Process::WNOHANG)
      break unless $?.nil?
      array = select([@io], nil, [@io], 0.1)
      array[0].each do |fdes|
        unless fdes.eof?
          # HACK HACK HACK 4096 is a magic number I pulled out of my
          # ass, the real one should depend on the kernel's buffer
          # sizes.
          result = fdes.readpartial(4096)
          yield(:output => result) if block_given?
        end
      end unless array.nil?
      array[2].each do |fdes|
        # Do something with erroneous condition.
      end unless array.nil?
    end
    yield(:exit_code => $?.exitstatus, :exit_status => $?) if block_given?
  end

  return @pid
end