shexecutor 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b7bd1eafe5b0bcf3c40dfb7abcb428642fd8f56a
4
- data.tar.gz: 5b24e222f42885b8e4e3e4f231d44eb623f60f09
3
+ metadata.gz: c90615e32be8148e01050f014d0bf7e107b403ad
4
+ data.tar.gz: 55607d1521893564995bea9da74153b084bd92ec
5
5
  SHA512:
6
- metadata.gz: 562083bd0cd5db122e2332955518bb19cc403940bb98fdadc8edcaacc26724269dec003a28bfdcbff5107f1d0376357fd4e5e038ff1d806582091531253f111f
7
- data.tar.gz: c46cd8e3d5f8835bf70bce083a02c692b75f35e87b818725e2dfee1e50104f0b66a48f7c99fdabb675f4dc54b7b43139abe55907f9293b108372b88f1dc61db2
6
+ metadata.gz: 54788b1980134c365b3b4c8cfb20c0d73ad74b3283e398f86e2b24662c57fcc382978dec80dfe10f463cf730ab7bab1244475dd1a32c609988a70ed888204b9d
7
+ data.tar.gz: becd1258cd4c5c1a526f180a419503430d5549c4064df9078300ba102d4100fb9229df812b6ca5b79787ec4d94894d00eea7ff993ed7bbd6073de8474f991af9
data/README.md CHANGED
@@ -20,6 +20,31 @@ For a full description of status, please see Process::Status
20
20
 
21
21
  This gem is sponsored by Hetzner (Pty) Ltd - http://hetzner.co.za
22
22
 
23
+ ## Initialization options:
24
+
25
+ Required / optional:
26
+
27
+ ```
28
+ {
29
+ :application_path # Path of the command to run
30
+ :params # Parameters to pass the command
31
+ }
32
+ ```
33
+
34
+ ```
35
+ @@default_options = {
36
+ :timeout => -1, # Seconds after which to raise Timeout::Error if not completed
37
+ :protect_against_injection => true, # look for spaces in and tainted application path
38
+ :stdout_path => nil, # file to append stdout to
39
+ :stderr_path => nil, # file to append stderr to
40
+ :append_stdout_path => true, # if true, will append, otherwise will overwrite
41
+ :append_stderr_path => true, # if true, will append, otherwise will overwrite
42
+ :replace => false, # replace the running process with the command
43
+ :wait_for_completion => false, # block until the command completes
44
+ :timeout_sig_kill_retry => 500 # if timeout occurs, send TERM, and send signal 9 if still present after X ms
45
+ }
46
+ ```
47
+
23
48
  ## Installation
24
49
 
25
50
  Add this line to your application's Gemfile:
@@ -1,3 +1,3 @@
1
1
  module SHExecutor
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
data/lib/shexecutor.rb CHANGED
@@ -3,14 +3,15 @@ require 'open3'
3
3
 
4
4
  module SHExecutor
5
5
  @@default_options = {
6
- :timeout => -1,
7
- :protect_against_injection => true,
8
- :stdout_path => nil,
9
- :stderr_path => nil,
10
- :append_stdout_path => true,
11
- :append_stderr_path => true,
12
- :replace => false,
13
- :wait_for_completion => false
6
+ :timeout => -1, # Seconds after which to raise Timeout::Error if not completed
7
+ :protect_against_injection => true, # look for spaces in and tainted application path
8
+ :stdout_path => nil, # file to append stdout to
9
+ :stderr_path => nil, # file to append stderr to
10
+ :append_stdout_path => true, # if true, will append, otherwise will overwrite
11
+ :append_stderr_path => true, # if true, will append, otherwise will overwrite
12
+ :replace => false, # replace the running process with the command
13
+ :wait_for_completion => false, # block until the command completes
14
+ :timeout_sig_kill_retry => 500 # if timeout occurs, send TERM, and send signal 9 if still present after X ms
14
15
  }
15
16
 
16
17
  def self.default_options
@@ -127,9 +128,9 @@ module SHExecutor
127
128
  def run_process(application_path, options = "")
128
129
  data_out = StringIO.new
129
130
  data_err = StringIO.new
130
- t0 = nil
131
+ @t0 = nil
131
132
  Open3::popen3(application_path, options) do |stdin, stdout, stderr, thr|
132
- t0 = thr
133
+ @t0 = thr
133
134
  # read srderr and stdout into buffers to prevent blocking
134
135
  t1 = Thread.new do
135
136
  IO.copy_stream(stdout, data_out)
@@ -151,7 +152,7 @@ module SHExecutor
151
152
  t1.join if not should_timeout?
152
153
  t2.join if not should_timeout?
153
154
  end
154
- return data_out, data_err, t0
155
+ return data_out, data_err, @t0
155
156
  end
156
157
 
157
158
  def block_process
@@ -170,17 +171,35 @@ module SHExecutor
170
171
  @result.join
171
172
  @result.value
172
173
  rescue Timeout::Error => ex
174
+ kill_process(@t0.pid)
173
175
  raise ex
174
176
  end
175
177
  end
176
178
 
179
+ def process?(pid)
180
+ begin
181
+ Process.getpgid(pid)
182
+ true
183
+ rescue Errno::ESRCH
184
+ false
185
+ end
186
+ end
187
+
188
+ def kill_process(pid)
189
+ return if pid.nil?
190
+ Process.kill("TERM", pid)
191
+ count = 0
192
+ while (count < (@options[:timeout_sig_kill_retry]/100) and process?(pid)) do
193
+ sleep 0.1
194
+ end
195
+ Process.kill(9, pid) if process?(pid)
196
+ end
197
+
177
198
  def fork_process
178
199
  validate
179
200
  @stdin_stream, @stdout_stream, @stderr_stream, @result = Open3::popen3(@options[:application_path], *@options[:params])
180
201
  end
181
202
 
182
- private
183
-
184
203
  def should_timeout?
185
204
  @options[:timeout] > 0
186
205
  end
@@ -27,7 +27,8 @@ describe 'Executor' do
27
27
  :append_stdout_path => false,
28
28
  :append_stderr_path => false,
29
29
  :replace => false,
30
- :wait_for_completion => true
30
+ :wait_for_completion => true,
31
+ :timeout_sig_kill_retry => 500
31
32
  }
32
33
  @iut = SHExecutor::Executor.new(iut_options)
33
34
  expect(@iut.options).to eq(iut_options)
@@ -207,7 +208,7 @@ describe 'Executor' do
207
208
  end
208
209
 
209
210
  context 'when asked to execute and block' do
210
- it 'should raise a TimeoutException if a timeout is specified and the process does not exit before' do
211
+ it 'should raise a Timeout::Error if a timeout is specified and the process does not exit before' do
211
212
  test_command = "/bin/sleep"
212
213
  test_params = ["5"]
213
214
  iut = SHExecutor::Executor.new({:timeout => 1, :wait_for_completion => true, :application_path => test_command, :params => test_params})
@@ -219,6 +220,16 @@ describe 'Executor' do
219
220
  expect(after - before).to be < 2.1
220
221
  end
221
222
 
223
+ it 'should kill the subprocess when a TimeoutError is raised' do
224
+ test_command = "/bin/sleep"
225
+ test_params = ["2"]
226
+ iut = SHExecutor::Executor.new({:timeout => 1, :wait_for_completion => true, :application_path => test_command, :params => test_params})
227
+ expect(Process).to receive(:kill)
228
+ expect {
229
+ iut.execute
230
+ }.to raise_error(Timeout::Error, "execution expired")
231
+ end
232
+
222
233
  it 'should call run_process with the command and parameters specified' do
223
234
  test_command = "/bin/ls"
224
235
  test_params = ["/tmp/"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shexecutor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ernst van Graan