6
7
8
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
|
# File 'lib/frontkick/command.rb', line 6
def self.exec(cmd, opts = {})
stdout, stderr, exit_code, duration = nil
stdin, out, err, wait_thr, pid = nil
cmd_array = cmd.kind_of?(Array) ? cmd : [cmd]
lock_fd = file_lock(opts[:exclusive]) if opts[:exclusive]
begin
timeout(opts[:timeout]) do duration = Benchmark.realtime do
stdin, out, err, wait_thr = Open3.popen3(*cmd_array)
stdin.close
pid = wait_thr.pid
stdout = out.read
stderr = err.read
exit_code = wait_thr.value.exitstatus
process_wait(pid)
end
end
rescue Timeout::Error => e
Process.kill('SIGINT', pid)
exit_code = wait_thr.value.exitstatus
process_wait(pid)
duration = opts[:timeout]
stdout = ""
stderr = "pid:#{pid}\tcommand:#{cmd_array.join(' ')} is timeout!"
ensure
stdin.close if stdin and !stdin.closed?
out.close if out and !out.closed?
err.close if err and !err.closed?
wait_thr.kill if wait_thr and !wait_thr.stop?
lock_fd.flock(File::LOCK_UN) if lock_fd
end
Result.new(:stdout => stdout, :stderr => stderr, :exit_code => exit_code, :duration => duration)
end
|