mixlib-shellout 2.2.1-universal-mingw32 → 2.2.2-universal-mingw32
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.
- checksums.yaml +4 -4
- data/Gemfile +12 -0
- data/Rakefile +24 -0
- data/lib/mixlib/shellout/version.rb +1 -1
- data/lib/mixlib/shellout/windows/core_ext.rb +243 -250
- data/mixlib-shellout-windows.gemspec +7 -0
- data/mixlib-shellout.gemspec +24 -0
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cadbef0918a7fec08ca405f56a5cd329f54660ca
|
4
|
+
data.tar.gz: baf26f7055af2c88854e9ea08f903cba4b433181
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0b1948708503dd9d9d78eaee8ef82482a13460f6f4af30dd533fa861c6e3d8af0f387df7e70d3eb7eeab3f6eda81121aac7c2bf0c9b0695b0a1a71d53be820b
|
7
|
+
data.tar.gz: aaf5ba1761ff3fe90afbd6f2b40fae823fff038dded0648b36269c7225f140355b15eb7cc72235d047879e156e72ab32225182af7e9881f127d54a7435c17a9c
|
data/Gemfile
ADDED
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
|
@@ -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
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
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
|
-
|
106
|
-
|
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
|
110
|
-
raise ArgumentError, "invalid
|
92
|
+
unless valid_keys.include?(key)
|
93
|
+
raise ArgumentError, "invalid key '#{key}'"
|
111
94
|
end
|
112
|
-
|
95
|
+
hash[key] = val
|
113
96
|
}
|
114
|
-
end
|
115
97
|
|
116
|
-
|
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
|
-
|
130
|
-
|
131
|
-
|
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
|
134
|
-
|
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 =
|
138
|
-
env.to_wide_string! if hash['with_logon']
|
139
|
-
end
|
122
|
+
env = nil
|
140
123
|
|
141
|
-
|
142
|
-
|
124
|
+
# The env string should be passed as a string of ';' separated paths.
|
125
|
+
if hash['environment']
|
126
|
+
env = hash['environment']
|
143
127
|
|
144
|
-
|
145
|
-
|
146
|
-
|
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
|
-
|
151
|
-
|
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
|
-
|
154
|
-
|
155
|
-
thread_security[:nLength] = 12
|
156
|
-
thread_security[:bInheritHandle] = true
|
157
|
-
end
|
136
|
+
# Process SECURITY_ATTRIBUTE structure
|
137
|
+
process_security = nil
|
158
138
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
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
|
-
|
173
|
-
|
145
|
+
# Thread SECURITY_ATTRIBUTE structure
|
146
|
+
thread_security = nil
|
174
147
|
|
175
|
-
|
176
|
-
|
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
|
-
|
164
|
+
handle = get_osfhandle(si_hash[io])
|
179
165
|
end
|
180
166
|
|
181
|
-
|
182
|
-
|
167
|
+
if handle == INVALID_HANDLE_VALUE
|
168
|
+
ptr = FFI::MemoryPointer.new(:int)
|
183
169
|
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
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
|
-
|
176
|
+
raise SystemCallError.new("get_osfhandle", errno)
|
177
|
+
end
|
193
178
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
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
|
-
|
224
|
-
cmd = nil
|
187
|
+
raise SystemCallError.new("SetHandleInformation", FFI.errno) unless bool
|
225
188
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
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
|
-
|
236
|
-
|
237
|
-
|
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
|
-
|
218
|
+
app = nil
|
219
|
+
cmd = nil
|
240
220
|
|
241
|
-
|
242
|
-
|
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['
|
245
|
-
|
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['
|
251
|
-
|
230
|
+
if hash['cwd']
|
231
|
+
cwd = hash['cwd'].to_wide_string
|
252
232
|
end
|
253
233
|
|
254
|
-
hash['
|
234
|
+
inherit = hash['inherit'] ? 1 : 0
|
255
235
|
|
256
|
-
|
257
|
-
|
236
|
+
if hash['with_logon']
|
237
|
+
logon = hash['with_logon'].to_wide_string
|
258
238
|
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
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
|
-
|
268
|
-
|
269
|
-
|
245
|
+
if hash['domain']
|
246
|
+
domain = hash['domain'].to_wide_string
|
247
|
+
end
|
248
|
+
|
249
|
+
hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
|
270
250
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
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("
|
263
|
+
raise SystemCallError.new("GetUserObjectInformationA", FFI.errno)
|
293
264
|
end
|
294
265
|
|
295
|
-
|
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
|
-
|
298
|
-
|
299
|
-
|
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
|
-
|
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
|
-
|
316
|
-
|
328
|
+
unless bool
|
329
|
+
raise SystemCallError.new("CreateProcessWithLogonW", FFI.errno)
|
330
|
+
end
|
317
331
|
end
|
318
332
|
else
|
319
|
-
bool =
|
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
|
-
|
335
|
-
|
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
|
-
|
352
|
-
|
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
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
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,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.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: universal-mingw32
|
6
6
|
authors:
|
7
7
|
- Opscode
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.8.2
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.8.2
|
41
41
|
description: Run external commands on Unix or Windows
|
42
42
|
email: info@opscode.com
|
43
43
|
executables: []
|
@@ -46,14 +46,18 @@ extra_rdoc_files:
|
|
46
46
|
- README.md
|
47
47
|
- LICENSE
|
48
48
|
files:
|
49
|
+
- Gemfile
|
49
50
|
- LICENSE
|
50
51
|
- README.md
|
52
|
+
- Rakefile
|
51
53
|
- lib/mixlib/shellout.rb
|
52
54
|
- lib/mixlib/shellout/exceptions.rb
|
53
55
|
- lib/mixlib/shellout/unix.rb
|
54
56
|
- lib/mixlib/shellout/version.rb
|
55
57
|
- lib/mixlib/shellout/windows.rb
|
56
58
|
- lib/mixlib/shellout/windows/core_ext.rb
|
59
|
+
- mixlib-shellout-windows.gemspec
|
60
|
+
- mixlib-shellout.gemspec
|
57
61
|
homepage: http://wiki.opscode.com/
|
58
62
|
licenses: []
|
59
63
|
metadata: {}
|
@@ -73,7 +77,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
73
77
|
version: '0'
|
74
78
|
requirements: []
|
75
79
|
rubyforge_project:
|
76
|
-
rubygems_version: 2.4.
|
80
|
+
rubygems_version: 2.4.6
|
77
81
|
signing_key:
|
78
82
|
specification_version: 4
|
79
83
|
summary: Run external commands on Unix or Windows
|