childprocess 0.8.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.document +6 -6
  3. data/.gitignore +28 -28
  4. data/.rspec +1 -1
  5. data/.travis.yml +42 -36
  6. data/CHANGELOG.md +67 -44
  7. data/Gemfile +18 -15
  8. data/LICENSE +20 -20
  9. data/README.md +216 -192
  10. data/Rakefile +61 -61
  11. data/appveyor.yml +42 -43
  12. data/childprocess.gemspec +32 -30
  13. data/ext/mkrf_conf.rb +24 -0
  14. data/lib/childprocess/abstract_io.rb +36 -36
  15. data/lib/childprocess/abstract_process.rb +192 -192
  16. data/lib/childprocess/errors.rb +37 -26
  17. data/lib/childprocess/jruby/io.rb +16 -16
  18. data/lib/childprocess/jruby/process.rb +184 -159
  19. data/lib/childprocess/jruby/pump.rb +53 -53
  20. data/lib/childprocess/jruby.rb +56 -56
  21. data/lib/childprocess/tools/generator.rb +145 -145
  22. data/lib/childprocess/unix/fork_exec_process.rb +78 -70
  23. data/lib/childprocess/unix/io.rb +21 -21
  24. data/lib/childprocess/unix/lib.rb +186 -186
  25. data/lib/childprocess/unix/platform/i386-linux.rb +12 -12
  26. data/lib/childprocess/unix/platform/i386-solaris.rb +11 -11
  27. data/lib/childprocess/unix/platform/x86_64-linux.rb +12 -12
  28. data/lib/childprocess/unix/platform/x86_64-macosx.rb +11 -11
  29. data/lib/childprocess/unix/posix_spawn_process.rb +134 -134
  30. data/lib/childprocess/unix/process.rb +90 -89
  31. data/lib/childprocess/unix.rb +9 -9
  32. data/lib/childprocess/version.rb +3 -3
  33. data/lib/childprocess/windows/handle.rb +91 -91
  34. data/lib/childprocess/windows/io.rb +25 -25
  35. data/lib/childprocess/windows/lib.rb +416 -416
  36. data/lib/childprocess/windows/process.rb +130 -130
  37. data/lib/childprocess/windows/process_builder.rb +178 -175
  38. data/lib/childprocess/windows/structs.rb +148 -148
  39. data/lib/childprocess/windows.rb +33 -33
  40. data/lib/childprocess.rb +210 -205
  41. data/spec/abstract_io_spec.rb +12 -12
  42. data/spec/childprocess_spec.rb +447 -391
  43. data/spec/get_env.ps1 +13 -0
  44. data/spec/io_spec.rb +228 -228
  45. data/spec/jruby_spec.rb +24 -24
  46. data/spec/pid_behavior.rb +12 -12
  47. data/spec/platform_detection_spec.rb +86 -86
  48. data/spec/spec_helper.rb +270 -261
  49. data/spec/unix_spec.rb +57 -57
  50. data/spec/windows_spec.rb +23 -23
  51. metadata +18 -33
data/spec/get_env.ps1 ADDED
@@ -0,0 +1,13 @@
1
+ param($p1)
2
+ $env_list = Get-ChildItem Env:
3
+
4
+ # Builds a ruby hash compatible string
5
+ $hash_string = "{"
6
+
7
+ foreach ($item in $env_list)
8
+ {
9
+ $hash_string += "`"" + $item.Name + "`" => `"" + $item.value.replace('\','\\').replace('"','\"') + "`","
10
+ }
11
+ $hash_string += "}"
12
+
13
+ $hash_string | out-File -Encoding "UTF8" $p1
data/spec/io_spec.rb CHANGED
@@ -1,228 +1,228 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- describe ChildProcess do
4
- it "can run even when $stdout is a StringIO" do
5
- begin
6
- stdout = $stdout
7
- $stdout = StringIO.new
8
- expect { sleeping_ruby.start }.to_not raise_error
9
- ensure
10
- $stdout = stdout
11
- end
12
- end
13
-
14
- it "can redirect stdout, stderr" do
15
- process = ruby(<<-CODE)
16
- [STDOUT, STDERR].each_with_index do |io, idx|
17
- io.sync = true
18
- io.puts idx
19
- end
20
- CODE
21
-
22
- out = Tempfile.new("stdout-spec")
23
- err = Tempfile.new("stderr-spec")
24
-
25
- begin
26
- process.io.stdout = out
27
- process.io.stderr = err
28
-
29
- process.start
30
- expect(process.io.stdin).to be_nil
31
- process.wait
32
-
33
- expect(rewind_and_read(out)).to eq "0\n"
34
- expect(rewind_and_read(err)).to eq "1\n"
35
- ensure
36
- out.close
37
- err.close
38
- end
39
- end
40
-
41
- it "can redirect stdout only" do
42
- process = ruby(<<-CODE)
43
- [STDOUT, STDERR].each_with_index do |io, idx|
44
- io.sync = true
45
- io.puts idx
46
- end
47
- CODE
48
-
49
- out = Tempfile.new("stdout-spec")
50
-
51
- begin
52
- process.io.stdout = out
53
-
54
- process.start
55
- process.wait
56
-
57
- expect(rewind_and_read(out)).to eq "0\n"
58
- ensure
59
- out.close
60
- end
61
- end
62
-
63
- it "pumps all output" do
64
- process = echo
65
-
66
- out = Tempfile.new("pump")
67
-
68
- begin
69
- process.io.stdout = out
70
-
71
- process.start
72
- process.wait
73
-
74
- expect(rewind_and_read(out)).to eq "hello\n"
75
- ensure
76
- out.close
77
- end
78
- end
79
-
80
- it "can write to stdin if duplex = true" do
81
- process = cat
82
-
83
- out = Tempfile.new("duplex")
84
- out.sync = true
85
-
86
- begin
87
- process.io.stdout = out
88
- process.io.stderr = out
89
- process.duplex = true
90
-
91
- process.start
92
- process.io.stdin.puts "hello world"
93
- process.io.stdin.close
94
-
95
- process.poll_for_exit(exit_timeout)
96
-
97
- expect(rewind_and_read(out)).to eq "hello world\n"
98
- ensure
99
- out.close
100
- end
101
- end
102
-
103
- it "can write to stdin interactively if duplex = true" do
104
- process = cat
105
-
106
- out = Tempfile.new("duplex")
107
- out.sync = true
108
-
109
- out_receiver = File.open(out.path, "rb")
110
- begin
111
- process.io.stdout = out
112
- process.io.stderr = out
113
- process.duplex = true
114
-
115
- process.start
116
-
117
- stdin = process.io.stdin
118
-
119
- stdin.puts "hello"
120
- stdin.flush
121
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\n\z/m) }
122
-
123
- stdin.putc "n"
124
- stdin.flush
125
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nn\z/m) }
126
-
127
- stdin.print "e"
128
- stdin.flush
129
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nne\z/m) }
130
-
131
- stdin.printf "w"
132
- stdin.flush
133
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\z/m) }
134
-
135
- stdin.write "\nworld\n"
136
- stdin.flush
137
- wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\r?\nworld\r?\n\z/m) }
138
-
139
- stdin.close
140
- process.poll_for_exit(exit_timeout)
141
- ensure
142
- out_receiver.close
143
- out.close
144
- end
145
- end
146
-
147
- #
148
- # this works on JRuby 1.6.5 on my Mac, but for some reason
149
- # hangs on Travis (running 1.6.5.1 + OpenJDK).
150
- #
151
- # http://travis-ci.org/#!/enkessler/childprocess/jobs/487331
152
- #
153
-
154
- it "works with pipes", :process_builder => false do
155
- process = ruby(<<-CODE)
156
- STDOUT.print "stdout"
157
- STDERR.print "stderr"
158
- CODE
159
-
160
- stdout, stdout_w = IO.pipe
161
- stderr, stderr_w = IO.pipe
162
-
163
- process.io.stdout = stdout_w
164
- process.io.stderr = stderr_w
165
-
166
- process.duplex = true
167
-
168
- process.start
169
- process.wait
170
-
171
- # write streams are closed *after* the process
172
- # has exited - otherwise it won't work on JRuby
173
- # with the current Process implementation
174
-
175
- stdout_w.close
176
- stderr_w.close
177
-
178
- out = stdout.read
179
- err = stderr.read
180
-
181
- expect([out, err]).to eq %w[stdout stderr]
182
- end
183
-
184
- it "can set close-on-exec when IO is inherited" do
185
- port = random_free_port
186
- server = TCPServer.new("127.0.0.1", port)
187
- ChildProcess.close_on_exec server
188
-
189
- process = sleeping_ruby
190
- process.io.inherit!
191
-
192
- process.start
193
- server.close
194
-
195
- wait_until { can_bind? "127.0.0.1", port }
196
- end
197
-
198
- it "handles long output" do
199
- process = ruby <<-CODE
200
- print 'a'*3000
201
- CODE
202
-
203
- out = Tempfile.new("long-output")
204
- out.sync = true
205
-
206
- begin
207
- process.io.stdout = out
208
-
209
- process.start
210
- process.wait
211
-
212
- expect(rewind_and_read(out).size).to eq 3000
213
- ensure
214
- out.close
215
- end
216
- end
217
-
218
- it 'should not inherit stdout and stderr by default' do
219
- cap = capture_std do
220
- process = echo
221
- process.start
222
- process.wait
223
- end
224
-
225
- expect(cap.stdout).to eq ''
226
- expect(cap.stderr).to eq ''
227
- end
228
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe ChildProcess do
4
+ it "can run even when $stdout is a StringIO" do
5
+ begin
6
+ stdout = $stdout
7
+ $stdout = StringIO.new
8
+ expect { sleeping_ruby.start }.to_not raise_error
9
+ ensure
10
+ $stdout = stdout
11
+ end
12
+ end
13
+
14
+ it "can redirect stdout, stderr" do
15
+ process = ruby(<<-CODE)
16
+ [STDOUT, STDERR].each_with_index do |io, idx|
17
+ io.sync = true
18
+ io.puts idx
19
+ end
20
+ CODE
21
+
22
+ out = Tempfile.new("stdout-spec")
23
+ err = Tempfile.new("stderr-spec")
24
+
25
+ begin
26
+ process.io.stdout = out
27
+ process.io.stderr = err
28
+
29
+ process.start
30
+ expect(process.io.stdin).to be_nil
31
+ process.wait
32
+
33
+ expect(rewind_and_read(out)).to eq "0\n"
34
+ expect(rewind_and_read(err)).to eq "1\n"
35
+ ensure
36
+ out.close
37
+ err.close
38
+ end
39
+ end
40
+
41
+ it "can redirect stdout only" do
42
+ process = ruby(<<-CODE)
43
+ [STDOUT, STDERR].each_with_index do |io, idx|
44
+ io.sync = true
45
+ io.puts idx
46
+ end
47
+ CODE
48
+
49
+ out = Tempfile.new("stdout-spec")
50
+
51
+ begin
52
+ process.io.stdout = out
53
+
54
+ process.start
55
+ process.wait
56
+
57
+ expect(rewind_and_read(out)).to eq "0\n"
58
+ ensure
59
+ out.close
60
+ end
61
+ end
62
+
63
+ it "pumps all output" do
64
+ process = echo
65
+
66
+ out = Tempfile.new("pump")
67
+
68
+ begin
69
+ process.io.stdout = out
70
+
71
+ process.start
72
+ process.wait
73
+
74
+ expect(rewind_and_read(out)).to eq "hello\n"
75
+ ensure
76
+ out.close
77
+ end
78
+ end
79
+
80
+ it "can write to stdin if duplex = true" do
81
+ process = cat
82
+
83
+ out = Tempfile.new("duplex")
84
+ out.sync = true
85
+
86
+ begin
87
+ process.io.stdout = out
88
+ process.io.stderr = out
89
+ process.duplex = true
90
+
91
+ process.start
92
+ process.io.stdin.puts "hello world"
93
+ process.io.stdin.close
94
+
95
+ process.poll_for_exit(exit_timeout)
96
+
97
+ expect(rewind_and_read(out)).to eq "hello world\n"
98
+ ensure
99
+ out.close
100
+ end
101
+ end
102
+
103
+ it "can write to stdin interactively if duplex = true" do
104
+ process = cat
105
+
106
+ out = Tempfile.new("duplex")
107
+ out.sync = true
108
+
109
+ out_receiver = File.open(out.path, "rb")
110
+ begin
111
+ process.io.stdout = out
112
+ process.io.stderr = out
113
+ process.duplex = true
114
+
115
+ process.start
116
+
117
+ stdin = process.io.stdin
118
+
119
+ stdin.puts "hello"
120
+ stdin.flush
121
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\n\z/m) }
122
+
123
+ stdin.putc "n"
124
+ stdin.flush
125
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nn\z/m) }
126
+
127
+ stdin.print "e"
128
+ stdin.flush
129
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nne\z/m) }
130
+
131
+ stdin.printf "w"
132
+ stdin.flush
133
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\z/m) }
134
+
135
+ stdin.write "\nworld\n"
136
+ stdin.flush
137
+ wait_until { expect(rewind_and_read(out_receiver)).to match(/\Ahello\r?\nnew\r?\nworld\r?\n\z/m) }
138
+
139
+ stdin.close
140
+ process.poll_for_exit(exit_timeout)
141
+ ensure
142
+ out_receiver.close
143
+ out.close
144
+ end
145
+ end
146
+
147
+ #
148
+ # this works on JRuby 1.6.5 on my Mac, but for some reason
149
+ # hangs on Travis (running 1.6.5.1 + OpenJDK).
150
+ #
151
+ # http://travis-ci.org/#!/enkessler/childprocess/jobs/487331
152
+ #
153
+
154
+ it "works with pipes", :process_builder => false do
155
+ process = ruby(<<-CODE)
156
+ STDOUT.print "stdout"
157
+ STDERR.print "stderr"
158
+ CODE
159
+
160
+ stdout, stdout_w = IO.pipe
161
+ stderr, stderr_w = IO.pipe
162
+
163
+ process.io.stdout = stdout_w
164
+ process.io.stderr = stderr_w
165
+
166
+ process.duplex = true
167
+
168
+ process.start
169
+ process.wait
170
+
171
+ # write streams are closed *after* the process
172
+ # has exited - otherwise it won't work on JRuby
173
+ # with the current Process implementation
174
+
175
+ stdout_w.close
176
+ stderr_w.close
177
+
178
+ out = stdout.read
179
+ err = stderr.read
180
+
181
+ expect([out, err]).to eq %w[stdout stderr]
182
+ end
183
+
184
+ it "can set close-on-exec when IO is inherited" do
185
+ port = random_free_port
186
+ server = TCPServer.new("127.0.0.1", port)
187
+ ChildProcess.close_on_exec server
188
+
189
+ process = sleeping_ruby
190
+ process.io.inherit!
191
+
192
+ process.start
193
+ server.close
194
+
195
+ wait_until { can_bind? "127.0.0.1", port }
196
+ end
197
+
198
+ it "handles long output" do
199
+ process = ruby <<-CODE
200
+ print 'a'*3000
201
+ CODE
202
+
203
+ out = Tempfile.new("long-output")
204
+ out.sync = true
205
+
206
+ begin
207
+ process.io.stdout = out
208
+
209
+ process.start
210
+ process.wait
211
+
212
+ expect(rewind_and_read(out).size).to eq 3000
213
+ ensure
214
+ out.close
215
+ end
216
+ end
217
+
218
+ it 'should not inherit stdout and stderr by default' do
219
+ cap = capture_std do
220
+ process = echo
221
+ process.start
222
+ process.wait
223
+ end
224
+
225
+ expect(cap.stdout).to eq ''
226
+ expect(cap.stderr).to eq ''
227
+ end
228
+ end
data/spec/jruby_spec.rb CHANGED
@@ -1,24 +1,24 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
- require "pid_behavior"
3
-
4
- if ChildProcess.jruby? && !ChildProcess.windows?
5
- describe ChildProcess::JRuby::IO do
6
- let(:io) { ChildProcess::JRuby::IO.new }
7
-
8
- it "raises an ArgumentError if given IO does not respond to :to_outputstream" do
9
- expect { io.stdout = nil }.to raise_error(ArgumentError)
10
- end
11
- end
12
-
13
- describe ChildProcess::JRuby::Process do
14
- if ChildProcess.unix?
15
- it_behaves_like "a platform that provides the child's pid"
16
- else
17
- it "raises an error when trying to access the child's pid" do
18
- process = exit_with(0)
19
- process.start
20
- expect { process.pid }.to raise_error(NotImplementedError)
21
- end
22
- end
23
- end
24
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+ require "pid_behavior"
3
+
4
+ if ChildProcess.jruby? && !ChildProcess.windows?
5
+ describe ChildProcess::JRuby::IO do
6
+ let(:io) { ChildProcess::JRuby::IO.new }
7
+
8
+ it "raises an ArgumentError if given IO does not respond to :to_outputstream" do
9
+ expect { io.stdout = nil }.to raise_error(ArgumentError)
10
+ end
11
+ end
12
+
13
+ describe ChildProcess::JRuby::Process do
14
+ if ChildProcess.unix?
15
+ it_behaves_like "a platform that provides the child's pid"
16
+ else
17
+ it "raises an error when trying to access the child's pid" do
18
+ process = exit_with(0)
19
+ process.start
20
+ expect { process.pid }.to raise_error(NotImplementedError)
21
+ end
22
+ end
23
+ end
24
+ end
data/spec/pid_behavior.rb CHANGED
@@ -1,12 +1,12 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
-
3
- shared_examples_for "a platform that provides the child's pid" do
4
- it "knows the child's pid" do
5
- Tempfile.open("pid-spec") do |file|
6
- process = write_pid(file.path).start
7
- process.wait
8
-
9
- expect(process.pid).to eq rewind_and_read(file).chomp.to_i
10
- end
11
- end
12
- end
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ shared_examples_for "a platform that provides the child's pid" do
4
+ it "knows the child's pid" do
5
+ Tempfile.open("pid-spec") do |file|
6
+ process = write_pid(file.path).start
7
+ process.wait
8
+
9
+ expect(process.pid).to eq rewind_and_read(file).chomp.to_i
10
+ end
11
+ end
12
+ end