Class: Bake::ProcessHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/common/process.rb

Constant Summary collapse

@@pid =
nil
@@rd =
nil

Class Method Summary collapse

Class Method Details

.killProcess(force) ⇒ Object

do not kill compile processes or implement rd and pid array if really needed



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/common/process.rb', line 76

def self.killProcess(force) # do not kill compile processes or implement rd and pid array if really needed

  if @@rd
    begin
      @@rd.close
    rescue Exception => e
    end
    @@rd = nil
  end
  if @@pid
    begin
      5.times do |i|
        Process.kill("TERM",@@pid)
        sleep(1)
        break unless Process.waitpid(@@pid, Process::WNOHANG).nil? # nil = process still running

      end
    rescue Exception => e
    end
    begin
      Process.kill("KILL",@@pid)
    rescue Exception => e
    end
    @@pid = nil
  end
end

.run(cmdLineArray, immediateOutput = false, force = true, outpipe = nil, exitCodeArray = [0], dir = Dir.pwd, timeout = 0) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
# File 'lib/common/process.rb', line 9

def self.run(cmdLineArray, immediateOutput=false, force=true, outpipe=nil, exitCodeArray = [0], dir = Dir.pwd, timeout = 0)
  rd, wr = IO.pipe
  @@rd = force ? rd : nil
  duppedCmdLineArray = cmdLineArray.dup
  duppedCmdLineArray << { :chdir=>dir, :err=>wr, :out=>(outpipe ? outpipe : wr) }
  begin
    pid = spawn(*duppedCmdLineArray)
  rescue Exception => e
    return [false, e.message]
  end
  @@pid = force ? pid : nil
  wr.close
  output = ""
  begin
    begin
      Timeout::timeout(timeout) {
      while not rd.eof?
        tmp = rd.read(1)
        if (tmp != nil)
          tmp.encode!('UTF-8',  :invalid => :replace, :undef => :replace, :replace => '')
          tmp.encode!('binary', :invalid => :replace, :undef => :replace, :replace => '')
          output << tmp

          print tmp if immediateOutput
        end
      end
      }
    rescue Timeout::Error
      @@rd = rd
      @@pid = pid
      ProcessHelper::killProcess(true)
      output << "Process timeout (#{timeout} seconds).\n"
      return [false, output]
    end

  rescue
    # Seems to be a bug in ruby: sometimes there is a bad file descriptor on Windows instead of eof, which causes

    # an exception on read(). However, this happens not before everything is read, so there is no practical difference

    # how to "break" the loop.

    # This problem occurs on Windows command shell and Cygwin.

  end

  begin
    rd.close
  rescue
  end
  pid, status = Process.wait2(pid)

  @@pid = nil
  @@rd = nil

  if status.nil? && output.empty?
    puts output.inspect
    output = "Process returned with unknown exit status"
    puts output if immediateOutput
  end
  return [false, output] if status.nil?

  exitCodeArray = [0] if exitCodeArray.empty?
  ret = (exitCodeArray.include?status.exitstatus)
  if ret == false && output.empty?
    output = "Process returned with exit status #{status.exitstatus}"
    puts output if immediateOutput
  end
  [ret, output]
end