childprocess 0.5.9 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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