mixlib-shellout 2.2.1 → 2.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eca5bf754443b12631182fd658d3a20adcc5b942
4
- data.tar.gz: ffba5fcf6b2bcc41eb1e900f4eab536cb2ebbc8b
3
+ metadata.gz: 304f772cea76b9913e4354ee216f9171d89df4b0
4
+ data.tar.gz: a6d5cf525447578c32e64aaed36d64a322e103e4
5
5
  SHA512:
6
- metadata.gz: d8925389dc01bacd0d9fcd64f2f2fb601b675b76323806051af49fe9bb947f7c4e77bc9f183dc00b3b5061d9ac7ad26a3423de47b6d6f6c9b25228604d7be46e
7
- data.tar.gz: 4236a888d3a673fde3e9b6d0a8ce5550b52ef32beb1aff77154e6e3d934de5eda2b2ff120c92a9d3980b45d02734290387b23d292f0773abb5f348ff76386537
6
+ metadata.gz: 69933eb3b6dbb1f9877e1b1c7eacd3062426d30482917217b597584241e2c0582cbc3822a3e35e81248ab2b1c2ec1c492bdc72fe6724a98f43ed6d68d33d8f3e
7
+ data.tar.gz: 2333d801858fa0a2dffca808a900ca7d0570dfeb5acc889914eb91f03c4f3a9d7b5d1dba31456b904d1d37570e1e2bf3cecb3fecdd1fb8c4f6c64e798f1209fc
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec :name => "mixlib-shellout"
4
+
5
+ group(:test) do
6
+ gem "rspec_junit_formatter"
7
+ gem 'rake'
8
+ end
9
+
10
+ group(:development) do
11
+ gem 'pry'
12
+ end
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'rubygems/package_task'
3
+ require 'mixlib/shellout/version'
4
+
5
+ Dir[File.expand_path("../*gemspec", __FILE__)].reverse.each do |gemspec_path|
6
+ gemspec = eval(IO.read(gemspec_path))
7
+ Gem::PackageTask.new(gemspec).define
8
+ end
9
+
10
+ desc "Run all specs in spec directory"
11
+ RSpec::Core::RakeTask.new(:spec) do |t|
12
+ t.pattern = FileList['spec/**/*_spec.rb']
13
+ end
14
+
15
+ desc "Build it and ship it"
16
+ task ship: [:clobber_package, :gem] do
17
+ sh("git tag #{Mixlib::ShellOut::VERSION}")
18
+ sh("git push opscode --tags")
19
+ Dir[File.expand_path("../pkg/*.gem", __FILE__)].reverse.each do |built_gem|
20
+ sh("gem push #{built_gem}")
21
+ end
22
+ end
23
+
24
+ task default: :spec
@@ -1,5 +1,5 @@
1
1
  module Mixlib
2
2
  class ShellOut
3
- VERSION = "2.2.1"
3
+ VERSION = "2.2.2"
4
4
  end
5
5
  end
@@ -21,6 +21,8 @@ require 'win32/process'
21
21
 
22
22
  # Add new constants for Logon
23
23
  module Process::Constants
24
+ private
25
+
24
26
  LOGON32_LOGON_INTERACTIVE = 0x00000002
25
27
  LOGON32_PROVIDER_DEFAULT = 0x00000000
26
28
  UOI_NAME = 0x00000002
@@ -34,16 +36,6 @@ end
34
36
 
35
37
  # Define the functions needed to check with Service windows station
36
38
  module Process::Functions
37
- module FFI::Library
38
- # Wrapper method for attach_function + private
39
- def attach_pfunc(*args)
40
- attach_function(*args)
41
- private args[0]
42
- end
43
- end
44
-
45
- extend FFI::Library
46
-
47
39
  ffi_lib :advapi32
48
40
 
49
41
  attach_pfunc :LogonUserW,
@@ -64,315 +56,316 @@ end
64
56
 
65
57
  # Override Process.create to check for running in the Service window station and doing
66
58
  # a full logon with LogonUser, instead of a CreateProcessWithLogon
59
+ # Cloned from https://github.com/djberg96/win32-process/blob/ffi/lib/win32/process.rb
60
+ # as of 2015-10-15 from commit cc066e5df25048f9806a610f54bf5f7f253e86f7
67
61
  module Process
68
- include Process::Constants
69
- include Process::Structs
70
62
 
71
- def create(args)
72
- unless args.kind_of?(Hash)
73
- raise TypeError, 'hash keyword arguments expected'
74
- end
75
-
76
- valid_keys = %w[
77
- app_name command_line inherit creation_flags cwd environment
78
- startup_info thread_inherit process_inherit close_handles with_logon
79
- domain password
80
- ]
81
-
82
- valid_si_keys = %w[
83
- startf_flags desktop title x y x_size y_size x_count_chars
84
- y_count_chars fill_attribute sw_flags stdin stdout stderr
85
- ]
86
-
87
- # Set default values
88
- hash = {
89
- 'app_name' => nil,
90
- 'creation_flags' => 0,
91
- 'close_handles' => true
92
- }
93
-
94
- # Validate the keys, and convert symbols and case to lowercase strings.
95
- args.each{ |key, val|
96
- key = key.to_s.downcase
97
- unless valid_keys.include?(key)
98
- raise ArgumentError, "invalid key '#{key}'"
63
+ # Explicitly reopen singleton class so that class/constant declarations from
64
+ # extensions are visible in Modules.nesting.
65
+ class << self
66
+ def create(args)
67
+ unless args.kind_of?(Hash)
68
+ raise TypeError, 'hash keyword arguments expected'
99
69
  end
100
- hash[key] = val
101
- }
102
70
 
103
- si_hash = {}
71
+ valid_keys = %w[
72
+ app_name command_line inherit creation_flags cwd environment
73
+ startup_info thread_inherit process_inherit close_handles with_logon
74
+ domain password
75
+ ]
76
+
77
+ valid_si_keys = %w[
78
+ startf_flags desktop title x y x_size y_size x_count_chars
79
+ y_count_chars fill_attribute sw_flags stdin stdout stderr
80
+ ]
81
+
82
+ # Set default values
83
+ hash = {
84
+ 'app_name' => nil,
85
+ 'creation_flags' => 0,
86
+ 'close_handles' => true
87
+ }
104
88
 
105
- # If the startup_info key is present, validate its subkeys
106
- if hash['startup_info']
107
- hash['startup_info'].each{ |key, val|
89
+ # Validate the keys, and convert symbols and case to lowercase strings.
90
+ args.each{ |key, val|
108
91
  key = key.to_s.downcase
109
- unless valid_si_keys.include?(key)
110
- raise ArgumentError, "invalid startup_info key '#{key}'"
92
+ unless valid_keys.include?(key)
93
+ raise ArgumentError, "invalid key '#{key}'"
111
94
  end
112
- si_hash[key] = val
95
+ hash[key] = val
113
96
  }
114
- end
115
97
 
116
- # The +command_line+ key is mandatory unless the +app_name+ key
117
- # is specified.
118
- unless hash['command_line']
119
- if hash['app_name']
120
- hash['command_line'] = hash['app_name']
121
- hash['app_name'] = nil
122
- else
123
- raise ArgumentError, 'command_line or app_name must be specified'
124
- end
125
- end
126
-
127
- env = nil
98
+ si_hash = {}
128
99
 
129
- # The env string should be passed as a string of ';' separated paths.
130
- if hash['environment']
131
- env = hash['environment']
100
+ # If the startup_info key is present, validate its subkeys
101
+ if hash['startup_info']
102
+ hash['startup_info'].each{ |key, val|
103
+ key = key.to_s.downcase
104
+ unless valid_si_keys.include?(key)
105
+ raise ArgumentError, "invalid startup_info key '#{key}'"
106
+ end
107
+ si_hash[key] = val
108
+ }
109
+ end
132
110
 
133
- unless env.respond_to?(:join)
134
- env = hash['environment'].split(File::PATH_SEPARATOR)
111
+ # The +command_line+ key is mandatory unless the +app_name+ key
112
+ # is specified.
113
+ unless hash['command_line']
114
+ if hash['app_name']
115
+ hash['command_line'] = hash['app_name']
116
+ hash['app_name'] = nil
117
+ else
118
+ raise ArgumentError, 'command_line or app_name must be specified'
119
+ end
135
120
  end
136
121
 
137
- env = env.map{ |e| e + 0.chr }.join('') + 0.chr
138
- env.to_wide_string! if hash['with_logon']
139
- end
122
+ env = nil
140
123
 
141
- # Process SECURITY_ATTRIBUTE structure
142
- process_security = nil
124
+ # The env string should be passed as a string of ';' separated paths.
125
+ if hash['environment']
126
+ env = hash['environment']
143
127
 
144
- if hash['process_inherit']
145
- process_security = SECURITY_ATTRIBUTES.new
146
- process_security[:nLength] = 12
147
- process_security[:bInheritHandle] = true
148
- end
128
+ unless env.respond_to?(:join)
129
+ env = hash['environment'].split(File::PATH_SEPARATOR)
130
+ end
149
131
 
150
- # Thread SECURITY_ATTRIBUTE structure
151
- thread_security = nil
132
+ env = env.map{ |e| e + 0.chr }.join('') + 0.chr
133
+ env.to_wide_string! if hash['with_logon']
134
+ end
152
135
 
153
- if hash['thread_inherit']
154
- thread_security = SECURITY_ATTRIBUTES.new
155
- thread_security[:nLength] = 12
156
- thread_security[:bInheritHandle] = true
157
- end
136
+ # Process SECURITY_ATTRIBUTE structure
137
+ process_security = nil
158
138
 
159
- # Automatically handle stdin, stdout and stderr as either IO objects
160
- # or file descriptors. This won't work for StringIO, however. It also
161
- # will not work on JRuby because of the way it handles internal file
162
- # descriptors.
163
- #
164
- ['stdin', 'stdout', 'stderr'].each{ |io|
165
- if si_hash[io]
166
- if si_hash[io].respond_to?(:fileno)
167
- handle = get_osfhandle(si_hash[io].fileno)
168
- else
169
- handle = get_osfhandle(si_hash[io])
170
- end
139
+ if hash['process_inherit']
140
+ process_security = SECURITY_ATTRIBUTES.new
141
+ process_security[:nLength] = 12
142
+ process_security[:bInheritHandle] = 1
143
+ end
171
144
 
172
- if handle == INVALID_HANDLE_VALUE
173
- ptr = FFI::MemoryPointer.new(:int)
145
+ # Thread SECURITY_ATTRIBUTE structure
146
+ thread_security = nil
174
147
 
175
- if windows_version >= 6 && get_errno(ptr) == 0
176
- errno = ptr.read_int
148
+ if hash['thread_inherit']
149
+ thread_security = SECURITY_ATTRIBUTES.new
150
+ thread_security[:nLength] = 12
151
+ thread_security[:bInheritHandle] = 1
152
+ end
153
+
154
+ # Automatically handle stdin, stdout and stderr as either IO objects
155
+ # or file descriptors. This won't work for StringIO, however. It also
156
+ # will not work on JRuby because of the way it handles internal file
157
+ # descriptors.
158
+ #
159
+ ['stdin', 'stdout', 'stderr'].each{ |io|
160
+ if si_hash[io]
161
+ if si_hash[io].respond_to?(:fileno)
162
+ handle = get_osfhandle(si_hash[io].fileno)
177
163
  else
178
- errno = FFI.errno
164
+ handle = get_osfhandle(si_hash[io])
179
165
  end
180
166
 
181
- raise SystemCallError.new("get_osfhandle", errno)
182
- end
167
+ if handle == INVALID_HANDLE_VALUE
168
+ ptr = FFI::MemoryPointer.new(:int)
183
169
 
184
- # Most implementations of Ruby on Windows create inheritable
185
- # handles by default, but some do not. RF bug #26988.
186
- bool = SetHandleInformation(
187
- handle,
188
- HANDLE_FLAG_INHERIT,
189
- HANDLE_FLAG_INHERIT
190
- )
170
+ if windows_version >= 6 && get_errno(ptr) == 0
171
+ errno = ptr.read_int
172
+ else
173
+ errno = FFI.errno
174
+ end
191
175
 
192
- raise SystemCallError.new("SetHandleInformation", FFI.errno) unless bool
176
+ raise SystemCallError.new("get_osfhandle", errno)
177
+ end
193
178
 
194
- si_hash[io] = handle
195
- si_hash['startf_flags'] ||= 0
196
- si_hash['startf_flags'] |= STARTF_USESTDHANDLES
197
- hash['inherit'] = true
198
- end
199
- }
200
-
201
- procinfo = PROCESS_INFORMATION.new
202
- startinfo = STARTUPINFO.new
203
-
204
- unless si_hash.empty?
205
- startinfo[:cb] = startinfo.size
206
- startinfo[:lpDesktop] = si_hash['desktop'] if si_hash['desktop']
207
- startinfo[:lpTitle] = si_hash['title'] if si_hash['title']
208
- startinfo[:dwX] = si_hash['x'] if si_hash['x']
209
- startinfo[:dwY] = si_hash['y'] if si_hash['y']
210
- startinfo[:dwXSize] = si_hash['x_size'] if si_hash['x_size']
211
- startinfo[:dwYSize] = si_hash['y_size'] if si_hash['y_size']
212
- startinfo[:dwXCountChars] = si_hash['x_count_chars'] if si_hash['x_count_chars']
213
- startinfo[:dwYCountChars] = si_hash['y_count_chars'] if si_hash['y_count_chars']
214
- startinfo[:dwFillAttribute] = si_hash['fill_attribute'] if si_hash['fill_attribute']
215
- startinfo[:dwFlags] = si_hash['startf_flags'] if si_hash['startf_flags']
216
- startinfo[:wShowWindow] = si_hash['sw_flags'] if si_hash['sw_flags']
217
- startinfo[:cbReserved2] = 0
218
- startinfo[:hStdInput] = si_hash['stdin'] if si_hash['stdin']
219
- startinfo[:hStdOutput] = si_hash['stdout'] if si_hash['stdout']
220
- startinfo[:hStdError] = si_hash['stderr'] if si_hash['stderr']
221
- end
179
+ # Most implementations of Ruby on Windows create inheritable
180
+ # handles by default, but some do not. RF bug #26988.
181
+ bool = SetHandleInformation(
182
+ handle,
183
+ HANDLE_FLAG_INHERIT,
184
+ HANDLE_FLAG_INHERIT
185
+ )
222
186
 
223
- app = nil
224
- cmd = nil
187
+ raise SystemCallError.new("SetHandleInformation", FFI.errno) unless bool
225
188
 
226
- # Convert strings to wide character strings if present
227
- if hash['app_name']
228
- app = hash['app_name'].to_wide_string
229
- end
230
-
231
- if hash['command_line']
232
- cmd = hash['command_line'].to_wide_string
233
- end
189
+ si_hash[io] = handle
190
+ si_hash['startf_flags'] ||= 0
191
+ si_hash['startf_flags'] |= STARTF_USESTDHANDLES
192
+ hash['inherit'] = true
193
+ end
194
+ }
234
195
 
235
- if hash['cwd']
236
- cwd = hash['cwd'].to_wide_string
237
- end
196
+ procinfo = PROCESS_INFORMATION.new
197
+ startinfo = STARTUPINFO.new
198
+
199
+ unless si_hash.empty?
200
+ startinfo[:cb] = startinfo.size
201
+ startinfo[:lpDesktop] = si_hash['desktop'] if si_hash['desktop']
202
+ startinfo[:lpTitle] = si_hash['title'] if si_hash['title']
203
+ startinfo[:dwX] = si_hash['x'] if si_hash['x']
204
+ startinfo[:dwY] = si_hash['y'] if si_hash['y']
205
+ startinfo[:dwXSize] = si_hash['x_size'] if si_hash['x_size']
206
+ startinfo[:dwYSize] = si_hash['y_size'] if si_hash['y_size']
207
+ startinfo[:dwXCountChars] = si_hash['x_count_chars'] if si_hash['x_count_chars']
208
+ startinfo[:dwYCountChars] = si_hash['y_count_chars'] if si_hash['y_count_chars']
209
+ startinfo[:dwFillAttribute] = si_hash['fill_attribute'] if si_hash['fill_attribute']
210
+ startinfo[:dwFlags] = si_hash['startf_flags'] if si_hash['startf_flags']
211
+ startinfo[:wShowWindow] = si_hash['sw_flags'] if si_hash['sw_flags']
212
+ startinfo[:cbReserved2] = 0
213
+ startinfo[:hStdInput] = si_hash['stdin'] if si_hash['stdin']
214
+ startinfo[:hStdOutput] = si_hash['stdout'] if si_hash['stdout']
215
+ startinfo[:hStdError] = si_hash['stderr'] if si_hash['stderr']
216
+ end
238
217
 
239
- inherit = hash['inherit'] || false
218
+ app = nil
219
+ cmd = nil
240
220
 
241
- if hash['with_logon']
242
- logon = hash['with_logon'].to_wide_string
221
+ # Convert strings to wide character strings if present
222
+ if hash['app_name']
223
+ app = hash['app_name'].to_wide_string
224
+ end
243
225
 
244
- if hash['password']
245
- passwd = hash['password'].to_wide_string
246
- else
247
- raise ArgumentError, 'password must be specified if with_logon is used'
226
+ if hash['command_line']
227
+ cmd = hash['command_line'].to_wide_string
248
228
  end
249
229
 
250
- if hash['domain']
251
- domain = hash['domain'].to_wide_string
230
+ if hash['cwd']
231
+ cwd = hash['cwd'].to_wide_string
252
232
  end
253
233
 
254
- hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
234
+ inherit = hash['inherit'] ? 1 : 0
255
235
 
256
- winsta_name = FFI::MemoryPointer.new(:char, 256)
257
- return_size = FFI::MemoryPointer.new(:ulong)
236
+ if hash['with_logon']
237
+ logon = hash['with_logon'].to_wide_string
258
238
 
259
- bool = GetUserObjectInformationA(
260
- GetProcessWindowStation(), # Window station handle
261
- UOI_NAME, # Information to get
262
- winsta_name, # Buffer to receive information
263
- winsta_name.size, # Size of buffer
264
- return_size # Size filled into buffer
265
- )
239
+ if hash['password']
240
+ passwd = hash['password'].to_wide_string
241
+ else
242
+ raise ArgumentError, 'password must be specified if with_logon is used'
243
+ end
266
244
 
267
- unless bool
268
- raise SystemCallError.new("GetUserObjectInformationA", FFI.errno)
269
- end
245
+ if hash['domain']
246
+ domain = hash['domain'].to_wide_string
247
+ end
248
+
249
+ hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
270
250
 
271
- winsta_name = winsta_name.read_string(return_size.read_ulong)
272
-
273
- # If running in the service windows station must do a log on to get
274
- # to the interactive desktop. Running process user account must have
275
- # the 'Replace a process level token' permission. This is necessary as
276
- # the logon (which happens with CreateProcessWithLogon) must have an
277
- # interactive windows station to attach to, which is created with the
278
- # LogonUser cann with the LOGON32_LOGON_INTERACTIVE flag.
279
- if winsta_name =~ /^Service-0x0-.*$/i
280
- token = FFI::MemoryPointer.new(:ulong)
281
-
282
- bool = LogonUserW(
283
- logon, # User
284
- domain, # Domain
285
- passwd, # Password
286
- LOGON32_LOGON_INTERACTIVE, # Logon Type
287
- LOGON32_PROVIDER_DEFAULT, # Logon Provider
288
- token # User token handle
251
+ winsta_name = FFI::MemoryPointer.new(:char, 256)
252
+ return_size = FFI::MemoryPointer.new(:ulong)
253
+
254
+ bool = GetUserObjectInformationA(
255
+ GetProcessWindowStation(), # Window station handle
256
+ UOI_NAME, # Information to get
257
+ winsta_name, # Buffer to receive information
258
+ winsta_name.size, # Size of buffer
259
+ return_size # Size filled into buffer
289
260
  )
290
261
 
291
262
  unless bool
292
- raise SystemCallError.new("LogonUserW", FFI.errno)
263
+ raise SystemCallError.new("GetUserObjectInformationA", FFI.errno)
293
264
  end
294
265
 
295
- token = token.read_ulong
266
+ winsta_name = winsta_name.read_string(return_size.read_ulong)
267
+
268
+ # If running in the service windows station must do a log on to get
269
+ # to the interactive desktop. Running process user account must have
270
+ # the 'Replace a process level token' permission. This is necessary as
271
+ # the logon (which happens with CreateProcessWithLogon) must have an
272
+ # interactive windows station to attach to, which is created with the
273
+ # LogonUser cann with the LOGON32_LOGON_INTERACTIVE flag.
274
+ if winsta_name =~ /^Service-0x0-.*$/i
275
+ token = FFI::MemoryPointer.new(:ulong)
276
+
277
+ bool = LogonUserW(
278
+ logon, # User
279
+ domain, # Domain
280
+ passwd, # Password
281
+ LOGON32_LOGON_INTERACTIVE, # Logon Type
282
+ LOGON32_PROVIDER_DEFAULT, # Logon Provider
283
+ token # User token handle
284
+ )
285
+
286
+ unless bool
287
+ raise SystemCallError.new("LogonUserW", FFI.errno)
288
+ end
296
289
 
297
- begin
298
- bool = CreateProcessAsUserW(
299
- token, # User token handle
290
+ token = token.read_ulong
291
+
292
+ begin
293
+ bool = CreateProcessAsUserW(
294
+ token, # User token handle
295
+ app, # App name
296
+ cmd, # Command line
297
+ process_security, # Process attributes
298
+ thread_security, # Thread attributes
299
+ inherit, # Inherit handles
300
+ hash['creation_flags'], # Creation Flags
301
+ env, # Environment
302
+ cwd, # Working directory
303
+ startinfo, # Startup Info
304
+ procinfo # Process Info
305
+ )
306
+ ensure
307
+ CloseHandle(token)
308
+ end
309
+
310
+ unless bool
311
+ raise SystemCallError.new("CreateProcessAsUserW (You must hold the 'Replace a process level token' permission)", FFI.errno)
312
+ end
313
+ else
314
+ bool = CreateProcessWithLogonW(
315
+ logon, # User
316
+ domain, # Domain
317
+ passwd, # Password
318
+ LOGON_WITH_PROFILE, # Logon flags
300
319
  app, # App name
301
320
  cmd, # Command line
302
- process_security, # Process attributes
303
- thread_security, # Thread attributes
304
- inherit, # Inherit handles
305
- hash['creation_flags'], # Creation Flags
321
+ hash['creation_flags'], # Creation flags
306
322
  env, # Environment
307
323
  cwd, # Working directory
308
324
  startinfo, # Startup Info
309
325
  procinfo # Process Info
310
326
  )
311
- ensure
312
- CloseHandle(token)
313
- end
314
327
 
315
- unless bool
316
- raise SystemCallError.new("CreateProcessAsUserW (You must hold the 'Replace a process level token' permission)", FFI.errno)
328
+ unless bool
329
+ raise SystemCallError.new("CreateProcessWithLogonW", FFI.errno)
330
+ end
317
331
  end
318
332
  else
319
- bool = CreateProcessWithLogonW(
320
- logon, # User
321
- domain, # Domain
322
- passwd, # Password
323
- LOGON_WITH_PROFILE, # Logon flags
333
+ bool = CreateProcessW(
324
334
  app, # App name
325
335
  cmd, # Command line
336
+ process_security, # Process attributes
337
+ thread_security, # Thread attributes
338
+ inherit, # Inherit handles?
326
339
  hash['creation_flags'], # Creation flags
327
340
  env, # Environment
328
341
  cwd, # Working directory
329
342
  startinfo, # Startup Info
330
343
  procinfo # Process Info
331
344
  )
332
- end
333
345
 
334
- unless bool
335
- raise SystemCallError.new("CreateProcessWithLogonW", FFI.errno)
346
+ unless bool
347
+ raise SystemCallError.new("CreateProcessW", FFI.errno)
348
+ end
336
349
  end
337
- else
338
- bool = CreateProcessW(
339
- app, # App name
340
- cmd, # Command line
341
- process_security, # Process attributes
342
- thread_security, # Thread attributes
343
- inherit, # Inherit handles?
344
- hash['creation_flags'], # Creation flags
345
- env, # Environment
346
- cwd, # Working directory
347
- startinfo, # Startup Info
348
- procinfo # Process Info
349
- )
350
350
 
351
- unless bool
352
- raise SystemCallError.new("CreateProcessW", FFI.errno)
351
+ # Automatically close the process and thread handles in the
352
+ # PROCESS_INFORMATION struct unless explicitly told not to.
353
+ if hash['close_handles']
354
+ CloseHandle(procinfo[:hProcess])
355
+ CloseHandle(procinfo[:hThread])
356
+ # Clear these fields so callers don't attempt to close the handle
357
+ # which can result in the wrong handle being closed or an
358
+ # exception in some circumstances.
359
+ procinfo[:hProcess] = 0
360
+ procinfo[:hThread] = 0
353
361
  end
354
- end
355
362
 
356
- # Automatically close the process and thread handles in the
357
- # PROCESS_INFORMATION struct unless explicitly told not to.
358
- if hash['close_handles']
359
- CloseHandle(procinfo[:hProcess]) if procinfo[:hProcess]
360
- CloseHandle(procinfo[:hThread]) if procinfo[:hThread]
361
-
362
- # Set fields to nil so callers don't attempt to close the handle
363
- # which can result in the wrong handle being closed or an
364
- # exception in some circumstances
365
- procinfo[:hProcess] = nil
366
- procinfo[:hThread] = nil
363
+ ProcessInfo.new(
364
+ procinfo[:hProcess],
365
+ procinfo[:hThread],
366
+ procinfo[:dwProcessId],
367
+ procinfo[:dwThreadId]
368
+ )
367
369
  end
368
-
369
- ProcessInfo.new(
370
- procinfo[:hProcess],
371
- procinfo[:hThread],
372
- procinfo[:dwProcessId],
373
- procinfo[:dwThreadId]
374
- )
375
370
  end
376
-
377
- module_function :create
378
371
  end
@@ -0,0 +1,7 @@
1
+ gemspec = eval(File.read(File.expand_path("../mixlib-shellout.gemspec", __FILE__)))
2
+
3
+ gemspec.platform = Gem::Platform.new(["universal", "mingw32"])
4
+
5
+ gemspec.add_dependency "win32-process", "~> 0.8.2"
6
+
7
+ gemspec
@@ -0,0 +1,24 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/lib')
2
+ require 'mixlib/shellout/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'mixlib-shellout'
6
+ s.version = Mixlib::ShellOut::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.extra_rdoc_files = ["README.md", "LICENSE" ]
9
+ s.summary = "Run external commands on Unix or Windows"
10
+ s.description = s.summary
11
+ s.author = "Opscode"
12
+ s.email = "info@opscode.com"
13
+ s.homepage = "http://wiki.opscode.com/"
14
+
15
+ s.required_ruby_version = ">= 1.9.3"
16
+
17
+ s.add_development_dependency "rspec", "~> 3.0"
18
+
19
+ s.bindir = "bin"
20
+ s.executables = []
21
+ s.require_path = 'lib'
22
+ s.files = %w(Gemfile Rakefile LICENSE README.md) + Dir.glob("*.gemspec") +
23
+ Dir.glob("lib/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
24
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-shellout
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Opscode
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-11 00:00:00.000000000 Z
11
+ date: 2015-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -32,14 +32,18 @@ extra_rdoc_files:
32
32
  - README.md
33
33
  - LICENSE
34
34
  files:
35
+ - Gemfile
35
36
  - LICENSE
36
37
  - README.md
38
+ - Rakefile
37
39
  - lib/mixlib/shellout.rb
38
40
  - lib/mixlib/shellout/exceptions.rb
39
41
  - lib/mixlib/shellout/unix.rb
40
42
  - lib/mixlib/shellout/version.rb
41
43
  - lib/mixlib/shellout/windows.rb
42
44
  - lib/mixlib/shellout/windows/core_ext.rb
45
+ - mixlib-shellout-windows.gemspec
46
+ - mixlib-shellout.gemspec
43
47
  homepage: http://wiki.opscode.com/
44
48
  licenses: []
45
49
  metadata: {}
@@ -59,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
63
  version: '0'
60
64
  requirements: []
61
65
  rubyforge_project:
62
- rubygems_version: 2.4.4
66
+ rubygems_version: 2.4.6
63
67
  signing_key:
64
68
  specification_version: 4
65
69
  summary: Run external commands on Unix or Windows