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 +4 -4
- data/README.md +10 -0
- data/lib/childprocess/abstract_process.rb +14 -0
- data/lib/childprocess/unix/fork_exec_process.rb +1 -1
- data/lib/childprocess/unix/posix_spawn_process.rb +1 -1
- data/lib/childprocess/unix/process.rb +3 -18
- data/lib/childprocess/version.rb +1 -1
- data/lib/childprocess/windows/process.rb +18 -6
- data/spec/childprocess_spec.rb +3 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1bf2633335fa2da24ffd367d4a83e624b9e22b1
|
4
|
+
data.tar.gz: 4f05990d1fb49c76270f9ff11211fe4e05daca46
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
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
|
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
|
|
data/lib/childprocess/version.rb
CHANGED
@@ -16,8 +16,8 @@ module ChildProcess
|
|
16
16
|
|
17
17
|
poll_for_exit(timeout)
|
18
18
|
ensure
|
19
|
-
|
20
|
-
|
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
|
-
|
30
|
-
|
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
|
-
|
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)
|
data/spec/childprocess_spec.rb
CHANGED
@@ -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)
|
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
|
+
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-
|
11
|
+
date: 2014-02-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|