childprocess 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
data/spec/jruby_spec.rb CHANGED
File without changes
data/spec/spec_helper.rb CHANGED
@@ -111,13 +111,21 @@ module ChildProcessSpecHelper
111
111
  ruby_process(tmp_script(code))
112
112
  end
113
113
 
114
+ def exit_timeout
115
+ 10
116
+ end
117
+
114
118
  end # ChildProcessSpecHelper
115
119
 
116
120
  Thread.abort_on_exception = true
117
121
 
118
- RSpec.configure do |config|
119
- config.include(ChildProcessSpecHelper)
120
- config.after(:each) {
122
+ RSpec.configure do |c|
123
+ c.include(ChildProcessSpecHelper)
124
+ c.after(:each) {
121
125
  @process && @process.alive? && @process.stop
122
126
  }
127
+
128
+ if defined?(JRUBY_VERSION)
129
+ c.filter_run_excluding :jruby => false
130
+ end
123
131
  end
data/spec/windows_spec.rb CHANGED
File without changes
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: childprocess
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 5
10
- version: 0.2.5
9
+ - 6
10
+ version: 0.2.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Jari Bakken
@@ -15,11 +15,10 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-01-04 00:00:00 Z
18
+ date: 2012-01-07 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: rspec
22
- prerelease: false
21
+ type: :development
23
22
  requirement: &id001 !ruby/object:Gem::Requirement
24
23
  none: false
25
24
  requirements:
@@ -31,11 +30,11 @@ dependencies:
31
30
  - 0
32
31
  - 0
33
32
  version: 2.0.0
34
- type: :development
33
+ prerelease: false
34
+ name: rspec
35
35
  version_requirements: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- name: yard
38
- prerelease: false
37
+ type: :development
39
38
  requirement: &id002 !ruby/object:Gem::Requirement
40
39
  none: false
41
40
  requirements:
@@ -45,11 +44,11 @@ dependencies:
45
44
  segments:
46
45
  - 0
47
46
  version: "0"
48
- type: :development
47
+ prerelease: false
48
+ name: yard
49
49
  version_requirements: *id002
50
50
  - !ruby/object:Gem::Dependency
51
- name: rake
52
- prerelease: false
51
+ type: :development
53
52
  requirement: &id003 !ruby/object:Gem::Requirement
54
53
  none: false
55
54
  requirements:
@@ -61,11 +60,11 @@ dependencies:
61
60
  - 9
62
61
  - 2
63
62
  version: 0.9.2
64
- type: :development
63
+ prerelease: false
64
+ name: rake
65
65
  version_requirements: *id003
66
66
  - !ruby/object:Gem::Dependency
67
- name: ffi
68
- prerelease: false
67
+ type: :runtime
69
68
  requirement: &id004 !ruby/object:Gem::Requirement
70
69
  none: false
71
70
  requirements:
@@ -77,7 +76,8 @@ dependencies:
77
76
  - 0
78
77
  - 6
79
78
  version: 1.0.6
80
- type: :runtime
79
+ prerelease: false
80
+ name: ffi
81
81
  version_requirements: *id004
82
82
  description: This gem aims at being a simple and reliable solution for controlling external programs running in the background on any Ruby / OS combination.
83
83
  email:
@@ -111,15 +111,15 @@ files:
111
111
  - lib/childprocess/unix/process.rb
112
112
  - lib/childprocess/version.rb
113
113
  - lib/childprocess/windows.rb
114
- - lib/childprocess/windows/api.rb
115
- - lib/childprocess/windows/constants.rb
116
- - lib/childprocess/windows/functions.rb
117
114
  - lib/childprocess/windows/handle.rb
118
115
  - lib/childprocess/windows/io.rb
116
+ - lib/childprocess/windows/lib.rb
119
117
  - lib/childprocess/windows/process.rb
118
+ - lib/childprocess/windows/process_builder.rb
120
119
  - lib/childprocess/windows/structs.rb
121
120
  - spec/abstract_io_spec.rb
122
121
  - spec/childprocess_spec.rb
122
+ - spec/io_spec.rb
123
123
  - spec/jruby_spec.rb
124
124
  - spec/pid_behavior.rb
125
125
  - spec/spec_helper.rb
@@ -154,15 +154,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  requirements: []
155
155
 
156
156
  rubyforge_project: childprocess
157
- rubygems_version: 1.8.9
157
+ rubygems_version: 1.8.10
158
158
  signing_key:
159
159
  specification_version: 3
160
160
  summary: This gem aims at being a simple and reliable solution for controlling external programs running in the background on any Ruby / OS combination.
161
161
  test_files:
162
162
  - spec/abstract_io_spec.rb
163
163
  - spec/childprocess_spec.rb
164
+ - spec/io_spec.rb
164
165
  - spec/jruby_spec.rb
165
166
  - spec/pid_behavior.rb
166
167
  - spec/spec_helper.rb
167
168
  - spec/unix_spec.rb
168
169
  - spec/windows_spec.rb
170
+ has_rdoc:
@@ -1,59 +0,0 @@
1
- module ChildProcess
2
- module Windows
3
- class << self
4
- def kill(signal, *pids)
5
- case signal
6
- when 'SIGINT', 'INT', :SIGINT, :INT
7
- signal = WIN_SIGINT
8
- when 'SIGBRK', 'BRK', :SIGBREAK, :BRK
9
- signal = WIN_SIGBREAK
10
- when 'SIGKILL', 'KILL', :SIGKILL, :KILL
11
- signal = WIN_SIGKILL
12
- when 0..9
13
- # Do nothing
14
- else
15
- raise Error, "invalid signal #{signal.inspect}"
16
- end
17
-
18
- pids.map { |pid| pid if send_signal(signal, pid) }.compact
19
- end
20
-
21
- def waitpid(pid, flags = 0)
22
- wait_for_pid(pid, no_hang?(flags))
23
- end
24
-
25
- def waitpid2(pid, flags = 0)
26
- code = wait_for_pid(pid, no_hang?(flags))
27
-
28
- [pid, code] if code
29
- end
30
-
31
- def dont_inherit(file)
32
- unless file.respond_to?(:fileno)
33
- raise ArgumentError, "expected #{file.inspect} to respond to :fileno"
34
- end
35
-
36
- handle = Lib.handle_for(file.fileno)
37
-
38
- ok = Lib.set_handle_information(handle, HANDLE_FLAG_INHERIT, 0)
39
- ok or raise Error, Lib.last_error_message
40
- end
41
-
42
- private
43
-
44
- def no_hang?(flags)
45
- (flags & Process::WNOHANG) == Process::WNOHANG
46
- end
47
-
48
- def wait_for_pid(pid, no_hang)
49
- code = Handle.open(pid) { |handle|
50
- handle.wait unless no_hang
51
- handle.exit_code
52
- }
53
-
54
- code if code != PROCESS_STILL_ACTIVE
55
- end
56
-
57
- end # class << self
58
- end # Windows
59
- end # ChildProcess
@@ -1,36 +0,0 @@
1
- module ChildProcess::Windows
2
-
3
- FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
4
- FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000
5
-
6
- PROCESS_ALL_ACCESS = 0x1F0FFF
7
- PROCESS_QUERY_INFORMATION = 0x0400
8
- PROCESS_VM_READ = 0x0010
9
- PROCESS_STILL_ACTIVE = 259
10
-
11
- INFINITE = 0xFFFFFFFF
12
-
13
- WIN_SIGINT = 2
14
- WIN_SIGBREAK = 3
15
- WIN_SIGKILL = 9
16
-
17
- CTRL_C_EVENT = 0
18
- CTRL_BREAK_EVENT = 1
19
-
20
- DETACHED_PROCESS = 0x00000008
21
-
22
- STARTF_USESTDHANDLES = 0x00000100
23
- INVALID_HANDLE_VALUE = 0xFFFFFFFF
24
- HANDLE_FLAG_INHERIT = 0x00000001
25
-
26
- DUPLICATE_SAME_ACCESS = 0x00000002
27
-
28
- CREATE_UNICODE_ENVIRONMENT = 0x00000400
29
-
30
- module Lib
31
- enum :wait_status, [ :wait_object_0, 0,
32
- :wait_timeout, 0x102,
33
- :wait_abandoned, 0x80,
34
- :wait_failed, 0xFFFFFFFF ]
35
- end # Lib
36
- end # ChildProcess::Windows
@@ -1,322 +0,0 @@
1
- module ChildProcess
2
- module Windows
3
- module Lib
4
-
5
- def self.create_proc(cmd, opts = {})
6
- cmd_ptr = FFI::MemoryPointer.from_string cmd
7
- env_ptr = environment_pointer_for(opts[:environment])
8
-
9
- flags = 0
10
- inherit = !!opts[:inherit]
11
-
12
- flags |= DETACHED_PROCESS if opts[:detach]
13
-
14
- si = StartupInfo.new
15
- pi = ProcessInfo.new
16
-
17
- if opts[:stdout] || opts[:stderr]
18
- si[:dwFlags] ||= 0
19
- si[:dwFlags] |= STARTF_USESTDHANDLES
20
- inherit = true
21
-
22
- si[:hStdOutput] = handle_for(opts[:stdout].fileno) if opts[:stdout]
23
- si[:hStdError] = handle_for(opts[:stderr].fileno) if opts[:stderr]
24
- end
25
-
26
- if opts[:duplex]
27
- read_pipe_ptr = FFI::MemoryPointer.new(:pointer)
28
- write_pipe_ptr = FFI::MemoryPointer.new(:pointer)
29
- sa = SecurityAttributes.new(:inherit => true)
30
-
31
- ok = create_pipe(read_pipe_ptr, write_pipe_ptr, sa, 0)
32
- ok or raise Error, last_error_message
33
-
34
- read_pipe = read_pipe_ptr.read_pointer
35
- write_pipe = write_pipe_ptr.read_pointer
36
-
37
- ok = set_handle_information(write_pipe.address, HANDLE_FLAG_INHERIT, 0)
38
- ok or raise Error, last_error_message
39
-
40
- si[:hStdInput] = read_pipe
41
- end
42
-
43
- ok = create_process(
44
- nil, # application name
45
- cmd_ptr, # command line
46
- nil, # process attributes
47
- nil, # thread attributes
48
- inherit, # inherit handles
49
- flags, # creation flags
50
- env_ptr, # environment
51
- nil, # current directory
52
- si, # startup info
53
- pi # process info
54
- )
55
-
56
- ok or raise LaunchError, last_error_message
57
-
58
- close_handle pi[:hProcess]
59
- close_handle pi[:hThread]
60
-
61
- if opts[:duplex]
62
- opts[:stdin] = io_for(duplicate_handle(write_pipe), File::WRONLY)
63
- close_handle read_pipe
64
- close_handle write_pipe
65
- end
66
-
67
- pi[:dwProcessId]
68
- end
69
-
70
- def self.last_error_message
71
- errnum = get_last_error
72
- buf = FFI::MemoryPointer.new :char, 512
73
-
74
- size = format_message(
75
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
76
- nil, errnum, 0, buf, buf.size, nil
77
- )
78
-
79
- str = buf.read_string(size).strip
80
- "#{str} (#{errnum})"
81
- end
82
-
83
- def self.handle_for(fd_or_io)
84
- case fd_or_io
85
- when IO
86
- handle = get_osfhandle(fd_or_io.fileno)
87
- when Fixnum
88
- handle = get_osfhandle(fd_or_io)
89
- else
90
- if fd_or_io.respond_to?(:to_io)
91
- io = fd_or_io.to_io
92
-
93
- unless io.kind_of?(IO)
94
- raise TypeError, "expected #to_io to return an instance of IO"
95
- end
96
-
97
- handle = get_osfhandle(io.fileno)
98
- else
99
- raise TypeError, "invalid type: #{fd_or_io.inspect}"
100
- end
101
- end
102
-
103
- if handle == INVALID_HANDLE_VALUE
104
- raise Error, last_error_message
105
- end
106
-
107
- handle
108
- end
109
-
110
- def self.io_for(handle, flags = File::RDONLY)
111
- fd = open_osfhandle(handle, flags)
112
- if fd == -1
113
- raise Error, last_error_message
114
- end
115
-
116
- ::IO.for_fd fd, flags
117
- end
118
-
119
- def self.duplicate_handle(handle)
120
- dup = FFI::MemoryPointer.new(:pointer)
121
- proc = current_process
122
-
123
- ok = _duplicate_handle(
124
- proc, handle, proc, dup, 0, false, DUPLICATE_SAME_ACCESS)
125
-
126
- ok or raise Error, last_error_message
127
-
128
- dup.read_pointer
129
- ensure
130
- close_handle proc
131
- end
132
-
133
- def self.environment_pointer_for(env)
134
- return unless env.kind_of?(Hash) && env.any?
135
-
136
- strings = ENV.map { |k,v| "#{k}=#{v}\0" }
137
- env.each do |key, value|
138
- if key.include?("=")
139
- raise InvalidEnvironmentVariableName, key
140
- end
141
-
142
- strings << "#{key}=#{value}\0"
143
- end
144
-
145
- strings << "\0" # terminate the env block
146
- env_str = strings.join
147
-
148
- ptr = FFI::MemoryPointer.new(:long, env_str.bytesize)
149
- ptr.write_bytes env_str, 0, env_str.bytesize
150
-
151
- ptr
152
- end
153
-
154
- #
155
- # BOOL WINAPI CreateProcess(
156
- # __in_opt LPCTSTR lpApplicationName,
157
- # __inout_opt LPTSTR lpCommandLine,
158
- # __in_opt LPSECURITY_ATTRIBUTES lpProcessAttributes,
159
- # __in_opt LPSECURITY_ATTRIBUTES lpThreadAttributes,
160
- # __in BOOL bInheritHandles,
161
- # __in DWORD dwCreationFlags,
162
- # __in_opt LPVOID lpEnvironment,
163
- # __in_opt LPCTSTR lpCurrentDirectory,
164
- # __in LPSTARTUPINFO lpStartupInfo,
165
- # __out LPPROCESS_INFORMATION lpProcessInformation
166
- # );
167
- #
168
-
169
- attach_function :create_process, :CreateProcessA, [
170
- :pointer,
171
- :pointer,
172
- :pointer,
173
- :pointer,
174
- :bool,
175
- :ulong,
176
- :pointer,
177
- :pointer,
178
- :pointer,
179
- :pointer],
180
- :bool
181
-
182
- #
183
- # DWORD WINAPI GetLastError(void);
184
- #
185
-
186
- attach_function :get_last_error, :GetLastError, [], :ulong
187
-
188
- #
189
- # DWORD WINAPI FormatMessage(
190
- # __in DWORD dwFlags,
191
- # __in_opt LPCVOID lpSource,
192
- # __in DWORD dwMessageId,
193
- # __in DWORD dwLanguageId,
194
- # __out LPTSTR lpBuffer,
195
- # __in DWORD nSize,
196
- # __in_opt va_list *Arguments
197
- # );
198
- #
199
-
200
- attach_function :format_message, :FormatMessageA, [
201
- :ulong,
202
- :pointer,
203
- :ulong,
204
- :ulong,
205
- :pointer,
206
- :ulong,
207
- :pointer],
208
- :ulong
209
-
210
-
211
- attach_function :close_handle, :CloseHandle, [:pointer], :bool
212
-
213
- #
214
- # HANDLE WINAPI OpenProcess(
215
- # __in DWORD dwDesiredAccess,
216
- # __in BOOL bInheritHandle,
217
- # __in DWORD dwProcessId
218
- # );
219
- #
220
-
221
- attach_function :open_process, :OpenProcess, [:ulong, :bool, :ulong], :pointer
222
-
223
- #
224
- # DWORD WINAPI WaitForSingleObject(
225
- # __in HANDLE hHandle,
226
- # __in DWORD dwMilliseconds
227
- # );
228
- #
229
-
230
- attach_function :wait_for_single_object, :WaitForSingleObject, [:pointer, :ulong], :wait_status
231
-
232
- #
233
- # BOOL WINAPI GetExitCodeProcess(
234
- # __in HANDLE hProcess,
235
- # __out LPDWORD lpExitCode
236
- # );
237
- #
238
-
239
- attach_function :get_exit_code, :GetExitCodeProcess, [:pointer, :pointer], :bool
240
-
241
- #
242
- # BOOL WINAPI GenerateConsoleCtrlEvent(
243
- # __in DWORD dwCtrlEvent,
244
- # __in DWORD dwProcessGroupId
245
- # );
246
- #
247
-
248
- attach_function :generate_console_ctrl_event, :GenerateConsoleCtrlEvent, [:ulong, :ulong], :bool
249
-
250
- #
251
- # BOOL WINAPI TerminateProcess(
252
- # __in HANDLE hProcess,
253
- # __in UINT uExitCode
254
- # );
255
- #
256
-
257
- attach_function :terminate_process, :TerminateProcess, [:pointer, :uint], :bool
258
-
259
- #
260
- # long _get_osfhandle(
261
- # int fd
262
- # );
263
- #
264
-
265
- attach_function :get_osfhandle, :_get_osfhandle, [:int], :long
266
-
267
- #
268
- # int _open_osfhandle (
269
- # intptr_t osfhandle,
270
- # int flags
271
- # );
272
- #
273
-
274
- attach_function :open_osfhandle, :_open_osfhandle, [:pointer, :int], :int
275
-
276
- # BOOL WINAPI SetHandleInformation(
277
- # __in HANDLE hObject,
278
- # __in DWORD dwMask,
279
- # __in DWORD dwFlags
280
- # );
281
-
282
- attach_function :set_handle_information, :SetHandleInformation, [:long, :ulong, :ulong], :bool
283
-
284
- # BOOL WINAPI CreatePipe(
285
- # __out PHANDLE hReadPipe,
286
- # __out PHANDLE hWritePipe,
287
- # __in_opt LPSECURITY_ATTRIBUTES lpPipeAttributes,
288
- # __in DWORD nSize
289
- # );
290
-
291
- attach_function :create_pipe, :CreatePipe, [:pointer, :pointer, :pointer, :ulong], :bool
292
-
293
- #
294
- # HANDLE WINAPI GetCurrentProcess(void);
295
- #
296
-
297
- attach_function :current_process, :GetCurrentProcess, [], :pointer
298
-
299
- #
300
- # BOOL WINAPI DuplicateHandle(
301
- # __in HANDLE hSourceProcessHandle,
302
- # __in HANDLE hSourceHandle,
303
- # __in HANDLE hTargetProcessHandle,
304
- # __out LPHANDLE lpTargetHandle,
305
- # __in DWORD dwDesiredAccess,
306
- # __in BOOL bInheritHandle,
307
- # __in DWORD dwOptions
308
- # );
309
- #
310
-
311
- attach_function :_duplicate_handle, :DuplicateHandle, [
312
- :pointer,
313
- :pointer,
314
- :pointer,
315
- :pointer,
316
- :ulong,
317
- :bool,
318
- :ulong
319
- ], :bool
320
- end # Lib
321
- end # Windows
322
- end # ChildProcess