childprocess 0.5.9 → 0.6.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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.document +6 -6
  3. data/.gitignore +25 -25
  4. data/.rspec +1 -1
  5. data/.travis.yml +20 -18
  6. data/CHANGELOG.md +8 -0
  7. data/Gemfile +11 -4
  8. data/LICENSE +20 -20
  9. data/README.md +178 -178
  10. data/Rakefile +61 -61
  11. data/childprocess.gemspec +30 -29
  12. data/lib/childprocess.rb +184 -177
  13. data/lib/childprocess/abstract_io.rb +36 -36
  14. data/lib/childprocess/abstract_process.rb +187 -187
  15. data/lib/childprocess/errors.rb +26 -26
  16. data/lib/childprocess/jruby.rb +56 -56
  17. data/lib/childprocess/jruby/io.rb +16 -16
  18. data/lib/childprocess/jruby/process.rb +159 -159
  19. data/lib/childprocess/jruby/pump.rb +52 -52
  20. data/lib/childprocess/tools/generator.rb +145 -145
  21. data/lib/childprocess/unix.rb +9 -9
  22. data/lib/childprocess/unix/fork_exec_process.rb +70 -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 +89 -89
  31. data/lib/childprocess/version.rb +3 -3
  32. data/lib/childprocess/windows.rb +33 -33
  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 +415 -415
  36. data/lib/childprocess/windows/process.rb +129 -129
  37. data/lib/childprocess/windows/process_builder.rb +174 -174
  38. data/lib/childprocess/windows/structs.rb +148 -148
  39. data/spec/abstract_io_spec.rb +12 -12
  40. data/spec/childprocess_spec.rb +291 -256
  41. data/spec/io_spec.rb +228 -228
  42. data/spec/jruby_spec.rb +24 -24
  43. data/spec/pid_behavior.rb +12 -12
  44. data/spec/spec_helper.rb +253 -253
  45. data/spec/unix_spec.rb +57 -57
  46. data/spec/windows_spec.rb +23 -23
  47. metadata +47 -45
@@ -1,56 +1,56 @@
1
- require 'java'
2
- require 'jruby'
3
-
4
- class Java::SunNioCh::FileChannelImpl
5
- field_reader :fd
6
- end
7
-
8
- class Java::JavaIo::FileDescriptor
9
- if ChildProcess.os == :windows
10
- field_reader :handle
11
- end
12
-
13
- field_reader :fd
14
- end
15
-
16
- module ChildProcess
17
- module JRuby
18
- def self.posix_fileno_for(obj)
19
- channel = ::JRuby.reference(obj).channel
20
- begin
21
- channel.getFDVal
22
- rescue NoMethodError
23
- fileno = channel.fd
24
- if fileno.kind_of?(Java::JavaIo::FileDescriptor)
25
- fileno = fileno.fd
26
- end
27
-
28
- fileno == -1 ? obj.fileno : fileno
29
- end
30
- rescue
31
- # fall back
32
- obj.fileno
33
- end
34
-
35
- def self.windows_handle_for(obj)
36
- channel = ::JRuby.reference(obj).channel
37
- fileno = obj.fileno
38
-
39
- begin
40
- fileno = channel.getFDVal
41
- rescue NoMethodError
42
- fileno = channel.fd if channel.respond_to?(:fd)
43
- end
44
-
45
- if fileno.kind_of? Java::JavaIo::FileDescriptor
46
- fileno.handle
47
- else
48
- Windows::Lib.handle_for fileno
49
- end
50
- end
51
- end
52
- end
53
-
54
- require "childprocess/jruby/pump"
55
- require "childprocess/jruby/io"
56
- require "childprocess/jruby/process"
1
+ require 'java'
2
+ require 'jruby'
3
+
4
+ class Java::SunNioCh::FileChannelImpl
5
+ field_reader :fd
6
+ end
7
+
8
+ class Java::JavaIo::FileDescriptor
9
+ if ChildProcess.os == :windows
10
+ field_reader :handle
11
+ end
12
+
13
+ field_reader :fd
14
+ end
15
+
16
+ module ChildProcess
17
+ module JRuby
18
+ def self.posix_fileno_for(obj)
19
+ channel = ::JRuby.reference(obj).channel
20
+ begin
21
+ channel.getFDVal
22
+ rescue NoMethodError
23
+ fileno = channel.fd
24
+ if fileno.kind_of?(Java::JavaIo::FileDescriptor)
25
+ fileno = fileno.fd
26
+ end
27
+
28
+ fileno == -1 ? obj.fileno : fileno
29
+ end
30
+ rescue
31
+ # fall back
32
+ obj.fileno
33
+ end
34
+
35
+ def self.windows_handle_for(obj)
36
+ channel = ::JRuby.reference(obj).channel
37
+ fileno = obj.fileno
38
+
39
+ begin
40
+ fileno = channel.getFDVal
41
+ rescue NoMethodError
42
+ fileno = channel.fd if channel.respond_to?(:fd)
43
+ end
44
+
45
+ if fileno.kind_of? Java::JavaIo::FileDescriptor
46
+ fileno.handle
47
+ else
48
+ Windows::Lib.handle_for fileno
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ require "childprocess/jruby/pump"
55
+ require "childprocess/jruby/io"
56
+ require "childprocess/jruby/process"
@@ -1,16 +1,16 @@
1
- module ChildProcess
2
- module JRuby
3
- class IO < AbstractIO
4
- private
5
-
6
- def check_type(output)
7
- unless output.respond_to?(:to_outputstream) && output.respond_to?(:write)
8
- raise ArgumentError, "expected #{output.inspect} to respond to :to_outputstream"
9
- end
10
- end
11
-
12
- end # IO
13
- end # Unix
14
- end # ChildProcess
15
-
16
-
1
+ module ChildProcess
2
+ module JRuby
3
+ class IO < AbstractIO
4
+ private
5
+
6
+ def check_type(output)
7
+ unless output.respond_to?(:to_outputstream) && output.respond_to?(:write)
8
+ raise ArgumentError, "expected #{output.inspect} to respond to :to_outputstream"
9
+ end
10
+ end
11
+
12
+ end # IO
13
+ end # Unix
14
+ end # ChildProcess
15
+
16
+
@@ -1,159 +1,159 @@
1
- require "java"
2
-
3
- module ChildProcess
4
- module JRuby
5
- class Process < AbstractProcess
6
- def initialize(args)
7
- super(args)
8
-
9
- @pumps = []
10
- end
11
-
12
- def io
13
- @io ||= JRuby::IO.new
14
- end
15
-
16
- def exited?
17
- return true if @exit_code
18
-
19
- assert_started
20
- @exit_code = @process.exitValue
21
- stop_pumps
22
-
23
- true
24
- rescue java.lang.IllegalThreadStateException => ex
25
- log(ex.class => ex.message)
26
- false
27
- ensure
28
- log(:exit_code => @exit_code)
29
- end
30
-
31
- def stop(timeout = nil)
32
- assert_started
33
-
34
- @process.destroy
35
- wait # no way to actually use the timeout here..
36
- end
37
-
38
- def wait
39
- if exited?
40
- exit_code
41
- else
42
- @process.waitFor
43
-
44
- stop_pumps
45
- @exit_code = @process.exitValue
46
- end
47
- end
48
-
49
- #
50
- # Only supported in JRuby on a Unix operating system, thanks to limitations
51
- # in Java's classes
52
- #
53
- # @return [Fixnum] the pid of the process after it has started
54
- # @raise [NotImplementedError] when trying to access pid on non-Unix platform
55
- #
56
- def pid
57
- if @process.getClass.getName != "java.lang.UNIXProcess"
58
- raise NotImplementedError, "pid is only supported by JRuby child processes on Unix"
59
- end
60
-
61
- # About the best way we can do this is with a nasty reflection-based impl
62
- # Thanks to Martijn Courteaux
63
- # http://stackoverflow.com/questions/2950338/how-can-i-kill-a-linux-process-in-java-with-sigkill-process-destroy-does-sigter/2951193#2951193
64
- field = @process.getClass.getDeclaredField("pid")
65
- field.accessible = true
66
- field.get(@process)
67
- end
68
-
69
- private
70
-
71
- def launch_process(&blk)
72
- pb = java.lang.ProcessBuilder.new(@args)
73
-
74
- pb.directory java.io.File.new(@cwd || Dir.pwd)
75
- set_env pb.environment
76
-
77
- begin
78
- @process = pb.start
79
- rescue java.io.IOException => ex
80
- raise LaunchError, ex.message
81
- end
82
-
83
- setup_io
84
- end
85
-
86
- def setup_io
87
- if @io
88
- redirect(@process.getErrorStream, @io.stderr)
89
- redirect(@process.getInputStream, @io.stdout)
90
- else
91
- @process.getErrorStream.close
92
- @process.getInputStream.close
93
- end
94
-
95
- if duplex?
96
- io._stdin = create_stdin
97
- else
98
- @process.getOutputStream.close
99
- end
100
- end
101
-
102
- def redirect(input, output)
103
- if output.nil?
104
- input.close
105
- return
106
- end
107
-
108
- @pumps << Pump.new(input, output.to_outputstream).run
109
- end
110
-
111
- def stop_pumps
112
- @pumps.each { |pump| pump.stop }
113
- end
114
-
115
- def set_env(env)
116
- merged = ENV.to_hash
117
-
118
- @environment.each { |k, v| merged[k.to_s] = v }
119
-
120
- merged.each do |k, v|
121
- if v
122
- env.put(k, v.to_s)
123
- elsif env.has_key? k
124
- env.remove(k)
125
- end
126
- end
127
-
128
- removed_keys = env.key_set.to_a - merged.keys
129
- removed_keys.each { |k| env.remove(k) }
130
- end
131
-
132
- def create_stdin
133
- output_stream = @process.getOutputStream
134
-
135
- stdin = output_stream.to_io
136
- stdin.sync = true
137
- stdin.instance_variable_set(:@childprocess_java_stream, output_stream)
138
-
139
- class << stdin
140
- # The stream provided is a BufferedeOutputStream, so we
141
- # have to flush it to make the bytes flow to the process
142
- def __childprocess_flush__
143
- @childprocess_java_stream.flush
144
- end
145
-
146
- [:flush, :print, :printf, :putc, :puts, :write, :write_nonblock].each do |m|
147
- define_method(m) do |*args|
148
- super(*args)
149
- self.__childprocess_flush__
150
- end
151
- end
152
- end
153
-
154
- stdin
155
- end
156
-
157
- end # Process
158
- end # JRuby
159
- end # ChildProcess
1
+ require "java"
2
+
3
+ module ChildProcess
4
+ module JRuby
5
+ class Process < AbstractProcess
6
+ def initialize(args)
7
+ super(args)
8
+
9
+ @pumps = []
10
+ end
11
+
12
+ def io
13
+ @io ||= JRuby::IO.new
14
+ end
15
+
16
+ def exited?
17
+ return true if @exit_code
18
+
19
+ assert_started
20
+ @exit_code = @process.exitValue
21
+ stop_pumps
22
+
23
+ true
24
+ rescue java.lang.IllegalThreadStateException => ex
25
+ log(ex.class => ex.message)
26
+ false
27
+ ensure
28
+ log(:exit_code => @exit_code)
29
+ end
30
+
31
+ def stop(timeout = nil)
32
+ assert_started
33
+
34
+ @process.destroy
35
+ wait # no way to actually use the timeout here..
36
+ end
37
+
38
+ def wait
39
+ if exited?
40
+ exit_code
41
+ else
42
+ @process.waitFor
43
+
44
+ stop_pumps
45
+ @exit_code = @process.exitValue
46
+ end
47
+ end
48
+
49
+ #
50
+ # Only supported in JRuby on a Unix operating system, thanks to limitations
51
+ # in Java's classes
52
+ #
53
+ # @return [Integer] the pid of the process after it has started
54
+ # @raise [NotImplementedError] when trying to access pid on non-Unix platform
55
+ #
56
+ def pid
57
+ if @process.getClass.getName != "java.lang.UNIXProcess"
58
+ raise NotImplementedError, "pid is only supported by JRuby child processes on Unix"
59
+ end
60
+
61
+ # About the best way we can do this is with a nasty reflection-based impl
62
+ # Thanks to Martijn Courteaux
63
+ # http://stackoverflow.com/questions/2950338/how-can-i-kill-a-linux-process-in-java-with-sigkill-process-destroy-does-sigter/2951193#2951193
64
+ field = @process.getClass.getDeclaredField("pid")
65
+ field.accessible = true
66
+ field.get(@process)
67
+ end
68
+
69
+ private
70
+
71
+ def launch_process(&blk)
72
+ pb = java.lang.ProcessBuilder.new(@args)
73
+
74
+ pb.directory java.io.File.new(@cwd || Dir.pwd)
75
+ set_env pb.environment
76
+
77
+ begin
78
+ @process = pb.start
79
+ rescue java.io.IOException => ex
80
+ raise LaunchError, ex.message
81
+ end
82
+
83
+ setup_io
84
+ end
85
+
86
+ def setup_io
87
+ if @io
88
+ redirect(@process.getErrorStream, @io.stderr)
89
+ redirect(@process.getInputStream, @io.stdout)
90
+ else
91
+ @process.getErrorStream.close
92
+ @process.getInputStream.close
93
+ end
94
+
95
+ if duplex?
96
+ io._stdin = create_stdin
97
+ else
98
+ @process.getOutputStream.close
99
+ end
100
+ end
101
+
102
+ def redirect(input, output)
103
+ if output.nil?
104
+ input.close
105
+ return
106
+ end
107
+
108
+ @pumps << Pump.new(input, output.to_outputstream).run
109
+ end
110
+
111
+ def stop_pumps
112
+ @pumps.each { |pump| pump.stop }
113
+ end
114
+
115
+ def set_env(env)
116
+ merged = ENV.to_hash
117
+
118
+ @environment.each { |k, v| merged[k.to_s] = v }
119
+
120
+ merged.each do |k, v|
121
+ if v
122
+ env.put(k, v.to_s)
123
+ elsif env.has_key? k
124
+ env.remove(k)
125
+ end
126
+ end
127
+
128
+ removed_keys = env.key_set.to_a - merged.keys
129
+ removed_keys.each { |k| env.remove(k) }
130
+ end
131
+
132
+ def create_stdin
133
+ output_stream = @process.getOutputStream
134
+
135
+ stdin = output_stream.to_io
136
+ stdin.sync = true
137
+ stdin.instance_variable_set(:@childprocess_java_stream, output_stream)
138
+
139
+ class << stdin
140
+ # The stream provided is a BufferedeOutputStream, so we
141
+ # have to flush it to make the bytes flow to the process
142
+ def __childprocess_flush__
143
+ @childprocess_java_stream.flush
144
+ end
145
+
146
+ [:flush, :print, :printf, :putc, :puts, :write, :write_nonblock].each do |m|
147
+ define_method(m) do |*args|
148
+ super(*args)
149
+ self.__childprocess_flush__
150
+ end
151
+ end
152
+ end
153
+
154
+ stdin
155
+ end
156
+
157
+ end # Process
158
+ end # JRuby
159
+ end # ChildProcess