| 296 |
296 |
@@os ||= Facter.value(:operatingsystem)
|
| 297 |
297 |
output = nil
|
| 298 |
298 |
child_pid, child_status = nil
|
| 299 |
|
# There are problems with read blocking with badly behaved children
|
| 300 |
|
# read.partialread doesn't seem to capture either stdout or stderr
|
| 301 |
|
# We hack around this using a temporary file
|
| 302 |
|
|
| 303 |
|
# The idea here is to avoid IO#read whenever possible.
|
| 304 |
|
output_file="/dev/null"
|
| 305 |
|
if ! arguments[:squelch]
|
| 306 |
|
require "tempfile"
|
| 307 |
|
output_file = Tempfile.new("puppet")
|
| 308 |
|
end
|
| 309 |
299 |
|
| 310 |
300 |
oldverb = $VERBOSE
|
| 311 |
301 |
$VERBOSE = false
|
|
302 |
|
|
303 |
poutput = IO::pipe
|
|
304 |
|
| 312 |
305 |
child_pid = Kernel.fork
|
| 313 |
306 |
$VERBOSE = oldverb
|
| 314 |
307 |
if child_pid
|
| 315 |
308 |
# Parent process executes this
|
|
309 |
poutput[1].close
|
| 316 |
310 |
child_status = (Process.waitpid2(child_pid)[1]).to_i >> 8
|
| 317 |
311 |
else
|
| 318 |
312 |
# Child process executes this
|
| 319 |
313 |
Process.setsid
|
| 320 |
314 |
begin
|
| 321 |
315 |
$stdin.reopen("/dev/null")
|
| 322 |
|
$stdout.reopen(output_file)
|
| 323 |
|
$stderr.reopen(output_file)
|
|
316 |
|
|
317 |
poutput[0].close
|
|
318 |
$stdout.reopen(poutput[1])
|
|
319 |
$stderr.reopen(poutput[1])
|
|
320 |
poutput[1].close
|
|
321 |
|
| 324 |
322 |
if arguments[:gid]
|
| 325 |
323 |
Process.egid = arguments[:gid]
|
| 326 |
324 |
Process.gid = arguments[:gid] unless @@os == "Darwin"
|
| ... | ... | |
| 330 |
328 |
Process.uid = arguments[:uid] unless @@os == "Darwin"
|
| 331 |
329 |
end
|
| 332 |
330 |
ENV['LANG'] = ENV['LC_ALL'] = ENV['LC_MESSAGES'] = ENV['LANGUAGE'] = 'C'
|
|
331 |
Dir.chdir("/")
|
| 333 |
332 |
if command.is_a?(Array)
|
| 334 |
333 |
Kernel.exec(*command)
|
| 335 |
334 |
else
|
| ... | ... | |
| 340 |
339 |
exit!(1)
|
| 341 |
340 |
end # begin; rescue
|
| 342 |
341 |
end # if child_pid
|
| 343 |
|
|
| 344 |
|
# read output in if required
|
| 345 |
|
if ! arguments[:squelch]
|
| 346 |
342 |
|
| 347 |
|
# Make sure the file's actually there. This is
|
| 348 |
|
# basically a race condition, and is probably a horrible
|
| 349 |
|
# way to handle it, but, well, oh well.
|
| 350 |
|
unless FileTest.exists?(output_file.path)
|
| 351 |
|
Puppet.warning "sleeping"
|
| 352 |
|
sleep 0.5
|
| 353 |
|
unless FileTest.exists?(output_file.path)
|
| 354 |
|
Puppet.warning "sleeping 2"
|
| 355 |
|
sleep 1
|
| 356 |
|
unless FileTest.exists?(output_file.path)
|
| 357 |
|
Puppet.warning "Could not get output"
|
| 358 |
|
output = ""
|
| 359 |
|
end
|
| 360 |
|
end
|
| 361 |
|
end
|
| 362 |
|
unless output
|
| 363 |
|
# We have to explicitly open here, so that it reopens
|
| 364 |
|
# after the child writes.
|
| 365 |
|
output = output_file.open.read
|
| 366 |
|
|
| 367 |
|
# The 'true' causes the file to get unlinked right away.
|
| 368 |
|
output_file.close(true)
|
| 369 |
|
end
|
|
343 |
# read output in if required
|
|
344 |
if ! arguments[:squelch]
|
|
345 |
output = poutput[0].read
|
|
346 |
else
|
|
347 |
output = ""
|
| 370 |
348 |
end
|
|
349 |
poutput[0].close
|
| 371 |
350 |
|
| 372 |
351 |
if arguments[:failonfail]
|
| 373 |
352 |
unless child_status == 0
|
| 374 |
|
-
|