childprocess 0.4.2 → 0.5.0

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: 63503076c91b015a05049ce4909a79dccffb1fc6
4
- data.tar.gz: 06207a205990b72490b31ce3af1088b6a49c21c2
3
+ metadata.gz: c1bf2633335fa2da24ffd367d4a83e624b9e22b1
4
+ data.tar.gz: 4f05990d1fb49c76270f9ff11211fe4e05daca46
5
5
  SHA512:
6
- metadata.gz: 81e45d2d76bf9a7d79c3f2accdac8b769994942292ffc2a80d7b9809e06c6d4dd068bcd56c861e0440784287f4c3165030b994173a93369112fcad4ab862a1d2
7
- data.tar.gz: 29132e001b36f540c75d66984721e23cbef19ff10124b95b53c59a33bec33170a10c9411dd2d96dd36e779d7ade95cf2089d8d0106f8484bee5c8c99937cea2c
6
+ metadata.gz: 08bc35f482edba588bf05e54777a2e3f1c2a91c0126a32d9cbdf126511deaf6c6958366e5fafd7e2f00fa370942ffe791fbb1b2aa211a0f34748f94a85789beb
7
+ data.tar.gz: 7531827c11b12ab23b4f87c487a05bce4cf3fb4a2ee0fd3f45f8dbe7c1803364a7f9577b43c6d0a4b62e92e3bd03ab9a5cb263bf64bf623f1c84a6b7f830c38b
data/README.md CHANGED
@@ -124,6 +124,16 @@ ChildProcess.posix_spawn = true
124
124
  process = ChildProcess.build(*args)
125
125
  ```
126
126
 
127
+ ### Ensure entire process tree dies
128
+
129
+ By default, the child process does not create a new process group. This means there's no guarantee that the entire process tree will die when the child process is killed. To solve this:
130
+
131
+ ```ruby
132
+ process = ChildProcess.build(*args)
133
+ process.new_process_group = true
134
+ process.start
135
+ ```
136
+
127
137
  #### Detach from parent
128
138
 
129
139
  ```ruby
@@ -24,6 +24,15 @@ module ChildProcess
24
24
  #
25
25
  attr_accessor :cwd
26
26
 
27
+ #
28
+ #
29
+ # Set this to true to make the child process the leader of a new process group
30
+ #
31
+ # This can be used to make sure that all grandchildren are killed
32
+ # when the child process dies.
33
+ #
34
+ attr_accessor :leader
35
+
27
36
  #
28
37
  # Create a new process with the given args.
29
38
  #
@@ -43,6 +52,7 @@ module ChildProcess
43
52
  @cwd = nil
44
53
  @detach = false
45
54
  @duplex = false
55
+ @leader = false
46
56
  @environment = {}
47
57
  end
48
58
 
@@ -161,6 +171,10 @@ module ChildProcess
161
171
  @duplex
162
172
  end
163
173
 
174
+ def leader?
175
+ @leader
176
+ end
177
+
164
178
  def log(*args)
165
179
  $stderr.puts "#{self.inspect} : #{args.inspect}" if $DEBUG
166
180
  end
@@ -20,7 +20,7 @@ module ChildProcess
20
20
  @pid = fork {
21
21
  # Children of the forked process will inherit its process group
22
22
  # This is to make sure that all grandchildren dies when this Process instance is killed
23
- ::Process.setpgid 0, 0 unless keep_pgid?
23
+ ::Process.setpgid 0, 0 if leader?
24
24
 
25
25
  if @cwd
26
26
  Dir.chdir(@cwd)
@@ -33,7 +33,7 @@ module ChildProcess
33
33
  actions.add_close fileno_for(writer)
34
34
  end
35
35
 
36
- attrs.pgroup = 0 unless keep_pgid?
36
+ attrs.pgroup = 0 if leader?
37
37
  attrs.flags |= Platform::POSIX_SPAWN_USEVFORK if defined? Platform::POSIX_SPAWN_USEVFORK
38
38
 
39
39
  # wrap in helper classes in order to avoid GC'ed pointers
@@ -52,21 +52,6 @@ module ChildProcess
52
52
  end
53
53
  end
54
54
 
55
- #
56
- # Set this to true to avoid resetting the parent group id in the child
57
- #
58
- # This is a temporary workaround for https://github.com/jarib/childprocess/issues/69
59
- # and will probably be removed in the future.
60
- #
61
-
62
- def keep_pgid=(bool)
63
- @keep_pgid = bool
64
- end
65
-
66
- def keep_pgid?
67
- !!@keep_pgid
68
- end
69
-
70
55
  private
71
56
 
72
57
  def send_term
@@ -89,10 +74,10 @@ module ChildProcess
89
74
  end
90
75
 
91
76
  def _pid
92
- if keep_pgid?
93
- @pid
94
- else
77
+ if leader?
95
78
  -@pid # negative pid == process group
79
+ else
80
+ @pid
96
81
  end
97
82
  end
98
83
 
@@ -1,3 +1,3 @@
1
1
  module ChildProcess
2
- VERSION = "0.4.2"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -16,8 +16,8 @@ module ChildProcess
16
16
 
17
17
  poll_for_exit(timeout)
18
18
  ensure
19
- @handle.close
20
- @job.close
19
+ close_handle
20
+ close_job_if_necessary
21
21
  end
22
22
 
23
23
  def wait
@@ -26,8 +26,9 @@ module ChildProcess
26
26
  else
27
27
  @handle.wait
28
28
  @exit_code = @handle.exit_code
29
- @handle.close
30
- @job.close
29
+
30
+ close_handle
31
+ close_job_if_necessary
31
32
 
32
33
  @exit_code
33
34
  end
@@ -64,11 +65,13 @@ module ChildProcess
64
65
  builder.stderr = @io.stderr
65
66
  end
66
67
 
67
- @job = Job.new
68
68
  @pid = builder.start
69
69
  @handle = Handle.open @pid
70
70
 
71
- @job << @handle
71
+ if leader?
72
+ @job = Job.new
73
+ @job << @handle
74
+ end
72
75
 
73
76
  if duplex?
74
77
  raise Error, "no stdin stream" unless builder.stdin
@@ -78,6 +81,15 @@ module ChildProcess
78
81
  self
79
82
  end
80
83
 
84
+ def close_handle
85
+ @handle.close
86
+ end
87
+
88
+ def close_job_if_necessary
89
+ @job.close if leader?
90
+ end
91
+
92
+
81
93
  class Job
82
94
  def initialize
83
95
  @pointer = Lib.create_job_object(nil, nil)
@@ -205,7 +205,9 @@ describe ChildProcess do
205
205
 
206
206
  it 'kills the full process tree', :process_builder => false do
207
207
  Tempfile.open('kill-process-tree') do |file|
208
- process = write_pid_in_sleepy_grand_child(file.path).start
208
+ process = write_pid_in_sleepy_grand_child(file.path)
209
+ process.leader = true
210
+ process.start
209
211
 
210
212
  pid = wait_until(30) do
211
213
  Integer(rewind_and_read(file)) rescue nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: childprocess
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jari Bakken
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-14 00:00:00.000000000 Z
11
+ date: 2014-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec