Module: Brush::Pipeline::Win32

Included in:
Brush::Pipeline
Defined in:
lib/brush/pipeline.rb

Instance Method Summary collapse

Instance Method Details

#create_process(argv, options, close_pipes) ⇒ Object



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/brush/pipeline.rb', line 448

def create_process (argv, options, close_pipes)
  close_pipes.each do |io|
    make_handle_inheritable(io, false)
  end

  Brush::Pipeline::PARENT_PIPES.each_key do |io|
    make_handle_inheritable(io, false)
  end

  [:stdin, :stdout, :stderr].each do |io_sym|
    make_handle_inheritable(options[io_sym]) if options[io_sym]
  end

  Dir.chdir(options[:cd]) do
    return Process.create(
        :app_name => options[:executable],
        :command_line => win_quote(argv),
        :inherit => true,
        :close_handles => false,
        :startup_info => {
            :startf_flags => Process::STARTF_USESTDHANDLES,
            :stdin => options[:stdin],
            :stdout => options[:stdout],
            :stderr => options[:stderr]
        })
  end
end

#each_pathext_elementObject



511
512
513
# File 'lib/brush/pipeline.rb', line 511

def each_pathext_element
  ENV['PATHEXT'].split(File::PATH_SEPARATOR).each { |ext| yield ext }
end

#find_in_path(name) ⇒ Object



477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
# File 'lib/brush/pipeline.rb', line 477

def find_in_path (name)
  chkname = nil

  if name =~ %r"[:/\\]"     # Path is absolute or relative.
    basename = File.basename(name)
    fullname = File.expand_path(name)

    if basename =~ /\./     # Path comes with extension.
      return fullname
    else                    # Need to find extension.
      each_pathext_element do |ext|
        return chkname if File.exists?(chkname = [fullname, ext].join)
      end
    end

  elsif name =~ /\./        # Given extension.
    each_path_element do |dir|
      return chkname if File.exists?(chkname = File.join(dir, name))
    end

  else                      # Just a name—no path or extension.
    each_path_element do |dir|
      each_pathext_element do |ext|
        if File.exists?(chkname = File.join(dir, [name, ext].join))
          return chkname
        end
      end
    end
  end

  nil                       # Didn't find a match. :(
end

#make_handle_inheritable(io, inheritable = true) ⇒ Object



412
413
414
415
416
417
418
419
# File 'lib/brush/pipeline.rb', line 412

def make_handle_inheritable (io, inheritable = true)
  if not SetHandleInformation(
      get_osfhandle(io.fileno), Windows::Handle::HANDLE_FLAG_INHERIT,
      inheritable ? Windows::Handle::HANDLE_FLAG_INHERIT : 0) \
  then
    raise Error, get_last_error
  end 
end

#sys_wait(process_info) ⇒ Object



404
405
406
407
408
409
# File 'lib/brush/pipeline.rb', line 404

def sys_wait (process_info)
  numeric_status = Process.waitpid2(process_info.process_id)[1]
  Process.CloseHandle(process_info.process_handle)
  Process.CloseHandle(process_info.thread_handle)
  duck_type_status_object(Object.new, process_info.process_id, numeric_status)
end

#win_quote(argv) ⇒ Object



422
423
424
# File 'lib/brush/pipeline.rb', line 422

def win_quote (argv)
  argv.collect { |arg| win_quote_word(arg) }.join(' ')
end

#win_quote_word(arg) ⇒ Object



426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
# File 'lib/brush/pipeline.rb', line 426

def win_quote_word (arg)
  # Rules
  # (1) Surround in d-quotes if arg contains space, tab, d-quote, or is empty.
  # (2) Backslashes preceding d-quotes are doubled.
  # (3) d-quotes are escaped with a backslash (so d-quotes always are preceded
  # by an odd number of backslashes).
  # (4) Backslashes at the end of the string, if escaped in d-quotes, are
  # doubled (creating the situation where a d-quote—termination character—is
  # preceded by an even number of backslashes).

  if arg.empty?
    '""'
  elsif arg =~ /[ \t"]/
    ['"',
      arg.gsub(/(\\)*("|\Z)/) { $1.to_s * 2 + ($2 == '"' ? '\\"' : '') },
      '"'].join
  else
    arg
  end
end