Hello community,

here is the log from the commit of package rubygem-mixlib-shellout for 
openSUSE:Factory checked in at 2015-10-25 19:13:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/rubygem-mixlib-shellout (Old)
 and      /work/SRC/openSUSE:Factory/.rubygem-mixlib-shellout.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "rubygem-mixlib-shellout"

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/rubygem-mixlib-shellout/rubygem-mixlib-shellout.changes
  2015-09-27 08:38:53.000000000 +0200
+++ 
/work/SRC/openSUSE:Factory/.rubygem-mixlib-shellout.new/rubygem-mixlib-shellout.changes
     2015-10-25 19:13:30.000000000 +0100
@@ -1,0 +2,12 @@
+Sat Oct 24 04:30:04 UTC 2015 - co...@suse.com
+
+- updated to version 2.2.3
+  no changelog found
+
+-------------------------------------------------------------------
+Tue Oct 20 04:29:49 UTC 2015 - co...@suse.com
+
+- updated to version 2.2.2
+  no changelog found
+
+-------------------------------------------------------------------

Old:
----
  mixlib-shellout-2.2.1.gem

New:
----
  mixlib-shellout-2.2.3.gem

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ rubygem-mixlib-shellout.spec ++++++
--- /var/tmp/diff_new_pack.zYzOOp/_old  2015-10-25 19:13:31.000000000 +0100
+++ /var/tmp/diff_new_pack.zYzOOp/_new  2015-10-25 19:13:31.000000000 +0100
@@ -24,7 +24,7 @@
 #
 
 Name:           rubygem-mixlib-shellout
-Version:        2.2.1
+Version:        2.2.3
 Release:        0
 %define mod_name mixlib-shellout
 %define mod_full_name %{mod_name}-%{version}

++++++ mixlib-shellout-2.2.1.gem -> mixlib-shellout-2.2.3.gem ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Gemfile new/Gemfile
--- old/Gemfile 1970-01-01 01:00:00.000000000 +0100
+++ new/Gemfile 2015-10-23 01:48:41.000000000 +0200
@@ -0,0 +1,12 @@
+source 'https://rubygems.org'
+
+gemspec :name => "mixlib-shellout"
+
+group(:test) do
+  gem "rspec_junit_formatter"
+  gem 'rake'
+end
+
+group(:development) do
+  gem 'pry'
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Rakefile new/Rakefile
--- old/Rakefile        1970-01-01 01:00:00.000000000 +0100
+++ new/Rakefile        2015-10-23 01:48:41.000000000 +0200
@@ -0,0 +1,24 @@
+require 'rspec/core/rake_task'
+require 'rubygems/package_task'
+require 'mixlib/shellout/version'
+
+Dir[File.expand_path("../*gemspec", __FILE__)].reverse.each do |gemspec_path|
+  gemspec = eval(IO.read(gemspec_path))
+  Gem::PackageTask.new(gemspec).define
+end
+
+desc "Run all specs in spec directory"
+RSpec::Core::RakeTask.new(:spec) do |t|
+  t.pattern = FileList['spec/**/*_spec.rb']
+end
+
+desc "Build it and ship it"
+task ship: [:clobber_package, :gem] do
+  sh("git tag #{Mixlib::ShellOut::VERSION}")
+  sh("git push opscode --tags")
+  Dir[File.expand_path("../pkg/*.gem", __FILE__)].reverse.each do |built_gem|
+    sh("gem push #{built_gem}")
+  end
+end
+
+task default: :spec
Files old/checksums.yaml.gz and new/checksums.yaml.gz differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/mixlib/shellout/version.rb 
new/lib/mixlib/shellout/version.rb
--- old/lib/mixlib/shellout/version.rb  2015-09-12 00:55:24.000000000 +0200
+++ new/lib/mixlib/shellout/version.rb  2015-10-23 01:48:41.000000000 +0200
@@ -1,5 +1,5 @@
 module Mixlib
   class ShellOut
-    VERSION = "2.2.1"
+    VERSION = "2.2.3"
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/mixlib/shellout/windows/core_ext.rb 
new/lib/mixlib/shellout/windows/core_ext.rb
--- old/lib/mixlib/shellout/windows/core_ext.rb 2015-09-12 00:55:24.000000000 
+0200
+++ new/lib/mixlib/shellout/windows/core_ext.rb 2015-10-23 01:48:41.000000000 
+0200
@@ -21,6 +21,8 @@
 
 # Add new constants for Logon
 module Process::Constants
+  private
+
   LOGON32_LOGON_INTERACTIVE = 0x00000002
   LOGON32_PROVIDER_DEFAULT  = 0x00000000
   UOI_NAME = 0x00000002
@@ -34,16 +36,6 @@
 
 # Define the functions needed to check with Service windows station
 module Process::Functions
-  module FFI::Library
-    # Wrapper method for attach_function + private
-    def attach_pfunc(*args)
-      attach_function(*args)
-      private args[0]
-    end
-  end
-
-  extend FFI::Library
-
   ffi_lib :advapi32
 
   attach_pfunc :LogonUserW,
@@ -64,315 +56,316 @@
 
 # Override Process.create to check for running in the Service window station 
and doing
 # a full logon with LogonUser, instead of a CreateProcessWithLogon
+# Cloned from 
https://github.com/djberg96/win32-process/blob/ffi/lib/win32/process.rb
+# as of 2015-10-15 from commit cc066e5df25048f9806a610f54bf5f7f253e86f7
 module Process
-  include Process::Constants
-  include Process::Structs
 
-  def create(args)
-    unless args.kind_of?(Hash)
-      raise TypeError, 'hash keyword arguments expected'
-    end
+  # Explicitly reopen singleton class so that class/constant declarations from
+  # extensions are visible in Modules.nesting.
+  class << self
+    def create(args)
+      unless args.kind_of?(Hash)
+        raise TypeError, 'hash keyword arguments expected'
+      end
+
+      valid_keys = %w[
+        app_name command_line inherit creation_flags cwd environment
+        startup_info thread_inherit process_inherit close_handles with_logon
+        domain password
+      ]
+
+      valid_si_keys = %w[
+        startf_flags desktop title x y x_size y_size x_count_chars
+        y_count_chars fill_attribute sw_flags stdin stdout stderr
+      ]
+
+      # Set default values
+      hash = {
+        'app_name'       => nil,
+        'creation_flags' => 0,
+        'close_handles'  => true
+      }
 
-    valid_keys = %w[
-      app_name command_line inherit creation_flags cwd environment
-      startup_info thread_inherit process_inherit close_handles with_logon
-      domain password
-    ]
-
-    valid_si_keys = %w[
-      startf_flags desktop title x y x_size y_size x_count_chars
-      y_count_chars fill_attribute sw_flags stdin stdout stderr
-    ]
-
-    # Set default values
-    hash = {
-      'app_name'       => nil,
-      'creation_flags' => 0,
-      'close_handles'  => true
-    }
-
-    # Validate the keys, and convert symbols and case to lowercase strings.
-    args.each{ |key, val|
-      key = key.to_s.downcase
-      unless valid_keys.include?(key)
-        raise ArgumentError, "invalid key '#{key}'"
-      end
-      hash[key] = val
-    }
-
-    si_hash = {}
-
-    # If the startup_info key is present, validate its subkeys
-    if hash['startup_info']
-      hash['startup_info'].each{ |key, val|
+      # Validate the keys, and convert symbols and case to lowercase strings.
+      args.each{ |key, val|
         key = key.to_s.downcase
-        unless valid_si_keys.include?(key)
-          raise ArgumentError, "invalid startup_info key '#{key}'"
+        unless valid_keys.include?(key)
+          raise ArgumentError, "invalid key '#{key}'"
         end
-        si_hash[key] = val
+        hash[key] = val
       }
-    end
 
-    # The +command_line+ key is mandatory unless the +app_name+ key
-    # is specified.
-    unless hash['command_line']
-      if hash['app_name']
-        hash['command_line'] = hash['app_name']
-        hash['app_name'] = nil
-      else
-        raise ArgumentError, 'command_line or app_name must be specified'
-      end
-    end
+      si_hash = {}
 
-    env = nil
-
-    # The env string should be passed as a string of ';' separated paths.
-    if hash['environment']
-      env = hash['environment']
+      # If the startup_info key is present, validate its subkeys
+      if hash['startup_info']
+        hash['startup_info'].each{ |key, val|
+          key = key.to_s.downcase
+          unless valid_si_keys.include?(key)
+            raise ArgumentError, "invalid startup_info key '#{key}'"
+          end
+          si_hash[key] = val
+        }
+      end
 
-      unless env.respond_to?(:join)
-        env = hash['environment'].split(File::PATH_SEPARATOR)
+      # The +command_line+ key is mandatory unless the +app_name+ key
+      # is specified.
+      unless hash['command_line']
+        if hash['app_name']
+          hash['command_line'] = hash['app_name']
+          hash['app_name'] = nil
+        else
+          raise ArgumentError, 'command_line or app_name must be specified'
+        end
       end
 
-      env = env.map{ |e| e + 0.chr }.join('') + 0.chr
-      env.to_wide_string! if hash['with_logon']
-    end
+      env = nil
 
-    # Process SECURITY_ATTRIBUTE structure
-    process_security = nil
+      # The env string should be passed as a string of ';' separated paths.
+      if hash['environment']
+        env = hash['environment']
 
-    if hash['process_inherit']
-      process_security = SECURITY_ATTRIBUTES.new
-      process_security[:nLength] = 12
-      process_security[:bInheritHandle] = true
-    end
+        unless env.respond_to?(:join)
+          env = hash['environment'].split(File::PATH_SEPARATOR)
+        end
 
-    # Thread SECURITY_ATTRIBUTE structure
-    thread_security = nil
+        env = env.map{ |e| e + 0.chr }.join('') + 0.chr
+        env.to_wide_string! if hash['with_logon']
+      end
 
-    if hash['thread_inherit']
-      thread_security = SECURITY_ATTRIBUTES.new
-      thread_security[:nLength] = 12
-      thread_security[:bInheritHandle] = true
-    end
+      # Process SECURITY_ATTRIBUTE structure
+      process_security = nil
 
-    # Automatically handle stdin, stdout and stderr as either IO objects
-    # or file descriptors. This won't work for StringIO, however. It also
-    # will not work on JRuby because of the way it handles internal file
-    # descriptors.
-    #
-    ['stdin', 'stdout', 'stderr'].each{ |io|
-      if si_hash[io]
-        if si_hash[io].respond_to?(:fileno)
-          handle = get_osfhandle(si_hash[io].fileno)
-        else
-          handle = get_osfhandle(si_hash[io])
-        end
+      if hash['process_inherit']
+        process_security = SECURITY_ATTRIBUTES.new
+        process_security[:nLength] = 12
+        process_security[:bInheritHandle] = 1
+      end
 
-        if handle == INVALID_HANDLE_VALUE
-          ptr = FFI::MemoryPointer.new(:int)
+      # Thread SECURITY_ATTRIBUTE structure
+      thread_security = nil
 
-          if windows_version >= 6 && get_errno(ptr) == 0
-            errno = ptr.read_int
+      if hash['thread_inherit']
+        thread_security = SECURITY_ATTRIBUTES.new
+        thread_security[:nLength] = 12
+        thread_security[:bInheritHandle] = 1
+      end
+
+      # Automatically handle stdin, stdout and stderr as either IO objects
+      # or file descriptors. This won't work for StringIO, however. It also
+      # will not work on JRuby because of the way it handles internal file
+      # descriptors.
+      #
+      ['stdin', 'stdout', 'stderr'].each{ |io|
+        if si_hash[io]
+          if si_hash[io].respond_to?(:fileno)
+            handle = get_osfhandle(si_hash[io].fileno)
           else
-            errno = FFI.errno
+            handle = get_osfhandle(si_hash[io])
           end
 
-          raise SystemCallError.new("get_osfhandle", errno)
-        end
+          if handle == INVALID_HANDLE_VALUE
+            ptr = FFI::MemoryPointer.new(:int)
 
-        # Most implementations of Ruby on Windows create inheritable
-        # handles by default, but some do not. RF bug #26988.
-        bool = SetHandleInformation(
-          handle,
-          HANDLE_FLAG_INHERIT,
-          HANDLE_FLAG_INHERIT
-        )
+            if windows_version >= 6 && get_errno(ptr) == 0
+              errno = ptr.read_int
+            else
+              errno = FFI.errno
+            end
 
-        raise SystemCallError.new("SetHandleInformation", FFI.errno) unless 
bool
+            raise SystemCallError.new("get_osfhandle", errno)
+          end
 
-        si_hash[io] = handle
-        si_hash['startf_flags'] ||= 0
-        si_hash['startf_flags'] |= STARTF_USESTDHANDLES
-        hash['inherit'] = true
-      end
-    }
-
-    procinfo  = PROCESS_INFORMATION.new
-    startinfo = STARTUPINFO.new
-
-    unless si_hash.empty?
-      startinfo[:cb]              = startinfo.size
-      startinfo[:lpDesktop]       = si_hash['desktop'] if si_hash['desktop']
-      startinfo[:lpTitle]         = si_hash['title'] if si_hash['title']
-      startinfo[:dwX]             = si_hash['x'] if si_hash['x']
-      startinfo[:dwY]             = si_hash['y'] if si_hash['y']
-      startinfo[:dwXSize]         = si_hash['x_size'] if si_hash['x_size']
-      startinfo[:dwYSize]         = si_hash['y_size'] if si_hash['y_size']
-      startinfo[:dwXCountChars]   = si_hash['x_count_chars'] if 
si_hash['x_count_chars']
-      startinfo[:dwYCountChars]   = si_hash['y_count_chars'] if 
si_hash['y_count_chars']
-      startinfo[:dwFillAttribute] = si_hash['fill_attribute'] if 
si_hash['fill_attribute']
-      startinfo[:dwFlags]         = si_hash['startf_flags'] if 
si_hash['startf_flags']
-      startinfo[:wShowWindow]     = si_hash['sw_flags'] if si_hash['sw_flags']
-      startinfo[:cbReserved2]     = 0
-      startinfo[:hStdInput]       = si_hash['stdin'] if si_hash['stdin']
-      startinfo[:hStdOutput]      = si_hash['stdout'] if si_hash['stdout']
-      startinfo[:hStdError]       = si_hash['stderr'] if si_hash['stderr']
-    end
+          # Most implementations of Ruby on Windows create inheritable
+          # handles by default, but some do not. RF bug #26988.
+          bool = SetHandleInformation(
+            handle,
+            HANDLE_FLAG_INHERIT,
+            HANDLE_FLAG_INHERIT
+          )
 
-    app = nil
-    cmd = nil
+          raise SystemCallError.new("SetHandleInformation", FFI.errno) unless 
bool
 
-    # Convert strings to wide character strings if present
-    if hash['app_name']
-      app = hash['app_name'].to_wide_string
-    end
+          si_hash[io] = handle
+          si_hash['startf_flags'] ||= 0
+          si_hash['startf_flags'] |= STARTF_USESTDHANDLES
+          hash['inherit'] = true
+        end
+      }
 
-    if hash['command_line']
-      cmd = hash['command_line'].to_wide_string
-    end
+      procinfo  = PROCESS_INFORMATION.new
+      startinfo = STARTUPINFO.new
 
-    if hash['cwd']
-      cwd = hash['cwd'].to_wide_string
-    end
+      unless si_hash.empty?
+        startinfo[:cb]              = startinfo.size
+        startinfo[:lpDesktop]       = si_hash['desktop'] if si_hash['desktop']
+        startinfo[:lpTitle]         = si_hash['title'] if si_hash['title']
+        startinfo[:dwX]             = si_hash['x'] if si_hash['x']
+        startinfo[:dwY]             = si_hash['y'] if si_hash['y']
+        startinfo[:dwXSize]         = si_hash['x_size'] if si_hash['x_size']
+        startinfo[:dwYSize]         = si_hash['y_size'] if si_hash['y_size']
+        startinfo[:dwXCountChars]   = si_hash['x_count_chars'] if 
si_hash['x_count_chars']
+        startinfo[:dwYCountChars]   = si_hash['y_count_chars'] if 
si_hash['y_count_chars']
+        startinfo[:dwFillAttribute] = si_hash['fill_attribute'] if 
si_hash['fill_attribute']
+        startinfo[:dwFlags]         = si_hash['startf_flags'] if 
si_hash['startf_flags']
+        startinfo[:wShowWindow]     = si_hash['sw_flags'] if 
si_hash['sw_flags']
+        startinfo[:cbReserved2]     = 0
+        startinfo[:hStdInput]       = si_hash['stdin'] if si_hash['stdin']
+        startinfo[:hStdOutput]      = si_hash['stdout'] if si_hash['stdout']
+        startinfo[:hStdError]       = si_hash['stderr'] if si_hash['stderr']
+      end
 
-    inherit  = hash['inherit'] || false
+      app = nil
+      cmd = nil
 
-    if hash['with_logon']
-      logon = hash['with_logon'].to_wide_string
+      # Convert strings to wide character strings if present
+      if hash['app_name']
+        app = hash['app_name'].to_wide_string
+      end
 
-      if hash['password']
-        passwd = hash['password'].to_wide_string
-      else
-        raise ArgumentError, 'password must be specified if with_logon is used'
+      if hash['command_line']
+        cmd = hash['command_line'].to_wide_string
       end
 
-      if hash['domain']
-        domain = hash['domain'].to_wide_string
+      if hash['cwd']
+        cwd = hash['cwd'].to_wide_string
       end
 
-      hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
+      inherit = hash['inherit'] ? 1 : 0
 
-      winsta_name = FFI::MemoryPointer.new(:char, 256)
-      return_size = FFI::MemoryPointer.new(:ulong)
+      if hash['with_logon']
+        logon = hash['with_logon'].to_wide_string
 
-      bool = GetUserObjectInformationA(
-        GetProcessWindowStation(),  # Window station handle
-        UOI_NAME,                   # Information to get
-        winsta_name,                # Buffer to receive information
-        winsta_name.size,           # Size of buffer
-        return_size                 # Size filled into buffer
-      )
+        if hash['password']
+          passwd = hash['password'].to_wide_string
+        else
+          raise ArgumentError, 'password must be specified if with_logon is 
used'
+        end
 
-      unless bool
-        raise SystemCallError.new("GetUserObjectInformationA", FFI.errno)
-      end
+        if hash['domain']
+          domain = hash['domain'].to_wide_string
+        end
 
-      winsta_name = winsta_name.read_string(return_size.read_ulong)
+        hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT
 
-      # If running in the service windows station must do a log on to get
-      # to the interactive desktop.  Running process user account must have
-      # the 'Replace a process level token' permission.  This is necessary as
-      # the logon (which happens with CreateProcessWithLogon) must have an 
-      # interactive windows station to attach to, which is created with the 
-      # LogonUser cann with the LOGON32_LOGON_INTERACTIVE flag.
-      if winsta_name =~ /^Service-0x0-.*$/i
-        token = FFI::MemoryPointer.new(:ulong)
-
-        bool = LogonUserW(
-          logon,                      # User
-          domain,                     # Domain
-          passwd,                     # Password
-          LOGON32_LOGON_INTERACTIVE,  # Logon Type
-          LOGON32_PROVIDER_DEFAULT,   # Logon Provider
-          token                       # User token handle
+        winsta_name = FFI::MemoryPointer.new(:char, 256)
+        return_size = FFI::MemoryPointer.new(:ulong)
+
+        bool = GetUserObjectInformationA(
+          GetProcessWindowStation(),  # Window station handle
+          UOI_NAME,                   # Information to get
+          winsta_name,                # Buffer to receive information
+          winsta_name.size,           # Size of buffer
+          return_size                 # Size filled into buffer
         )
 
         unless bool
-          raise SystemCallError.new("LogonUserW", FFI.errno)
+          raise SystemCallError.new("GetUserObjectInformationA", FFI.errno)
         end
 
-        token = token.read_ulong
+        winsta_name = winsta_name.read_string(return_size.read_ulong)
+
+        # If running in the service windows station must do a log on to get
+        # to the interactive desktop.  Running process user account must have
+        # the 'Replace a process level token' permission.  This is necessary as
+        # the logon (which happens with CreateProcessWithLogon) must have an 
+        # interactive windows station to attach to, which is created with the 
+        # LogonUser cann with the LOGON32_LOGON_INTERACTIVE flag.
+        if winsta_name =~ /^Service-0x0-.*$/i
+          token = FFI::MemoryPointer.new(:ulong)
+
+          bool = LogonUserW(
+            logon,                      # User
+            domain,                     # Domain
+            passwd,                     # Password
+            LOGON32_LOGON_INTERACTIVE,  # Logon Type
+            LOGON32_PROVIDER_DEFAULT,   # Logon Provider
+            token                       # User token handle
+          )
+
+          unless bool
+            raise SystemCallError.new("LogonUserW", FFI.errno)
+          end
+
+          token = token.read_ulong
 
-        begin
-          bool = CreateProcessAsUserW(
-            token,                  # User token handle
+          begin
+            bool = CreateProcessAsUserW(
+              token,                  # User token handle
+              app,                    # App name
+              cmd,                    # Command line
+              process_security,       # Process attributes
+              thread_security,        # Thread attributes
+              inherit,                # Inherit handles
+              hash['creation_flags'], # Creation Flags
+              env,                    # Environment
+              cwd,                    # Working directory
+              startinfo,              # Startup Info
+              procinfo                # Process Info
+            )
+          ensure
+            CloseHandle(token)
+          end
+
+          unless bool
+            raise SystemCallError.new("CreateProcessAsUserW (You must hold the 
'Replace a process level token' permission)", FFI.errno)
+          end
+        else
+          bool = CreateProcessWithLogonW(
+            logon,                  # User
+            domain,                 # Domain
+            passwd,                 # Password
+            LOGON_WITH_PROFILE,     # Logon flags
             app,                    # App name
             cmd,                    # Command line
-            process_security,       # Process attributes
-            thread_security,        # Thread attributes
-            inherit,                # Inherit handles
-            hash['creation_flags'], # Creation Flags
+            hash['creation_flags'], # Creation flags
             env,                    # Environment
             cwd,                    # Working directory
             startinfo,              # Startup Info
             procinfo                # Process Info
           )
-        ensure
-          CloseHandle(token)
-        end
 
-        unless bool
-          raise SystemCallError.new("CreateProcessAsUserW (You must hold the 
'Replace a process level token' permission)", FFI.errno)
+          unless bool
+            raise SystemCallError.new("CreateProcessWithLogonW", FFI.errno)
+          end
         end
       else
-        bool = CreateProcessWithLogonW(
-          logon,                  # User
-          domain,                 # Domain
-          passwd,                 # Password
-          LOGON_WITH_PROFILE,     # Logon flags
+        bool = CreateProcessW(
           app,                    # App name
           cmd,                    # Command line
+          process_security,       # Process attributes
+          thread_security,        # Thread attributes
+          inherit,                # Inherit handles?
           hash['creation_flags'], # Creation flags
           env,                    # Environment
           cwd,                    # Working directory
           startinfo,              # Startup Info
           procinfo                # Process Info
         )
-      end
 
-      unless bool
-        raise SystemCallError.new("CreateProcessWithLogonW", FFI.errno)
+        unless bool
+          raise SystemCallError.new("CreateProcessW", FFI.errno)
+        end
       end
-    else
-      bool = CreateProcessW(
-        app,                    # App name
-        cmd,                    # Command line
-        process_security,       # Process attributes
-        thread_security,        # Thread attributes
-        inherit,                # Inherit handles?
-        hash['creation_flags'], # Creation flags
-        env,                    # Environment
-        cwd,                    # Working directory
-        startinfo,              # Startup Info
-        procinfo                # Process Info
-      )
 
-      unless bool
-        raise SystemCallError.new("CreateProcessW", FFI.errno)
+      # Automatically close the process and thread handles in the
+      # PROCESS_INFORMATION struct unless explicitly told not to.
+      if hash['close_handles']
+        CloseHandle(procinfo[:hProcess])
+        CloseHandle(procinfo[:hThread])
+        # Clear these fields so callers don't attempt to close the handle
+        # which can result in the wrong handle being closed or an
+        # exception in some circumstances.
+        procinfo[:hProcess] = 0
+        procinfo[:hThread] = 0
       end
-    end
 
-    # Automatically close the process and thread handles in the
-    # PROCESS_INFORMATION struct unless explicitly told not to.
-    if hash['close_handles']
-      CloseHandle(procinfo[:hProcess]) if procinfo[:hProcess]
-      CloseHandle(procinfo[:hThread]) if procinfo[:hThread]
-
-      # Set fields to nil so callers don't attempt to close the handle
-      # which can result in the wrong handle being closed or an
-      # exception in some circumstances
-      procinfo[:hProcess] = nil
-      procinfo[:hThread] = nil
+      ProcessInfo.new(
+        procinfo[:hProcess],
+        procinfo[:hThread],
+        procinfo[:dwProcessId],
+        procinfo[:dwThreadId]
+      )
     end
-
-    ProcessInfo.new(
-      procinfo[:hProcess],
-      procinfo[:hThread],
-      procinfo[:dwProcessId],
-      procinfo[:dwThreadId]
-    )
   end
-
-  module_function :create
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lib/mixlib/shellout/windows.rb 
new/lib/mixlib/shellout/windows.rb
--- old/lib/mixlib/shellout/windows.rb  2015-09-12 00:55:24.000000000 +0200
+++ new/lib/mixlib/shellout/windows.rb  2015-10-23 01:48:41.000000000 +0200
@@ -43,7 +43,6 @@
       # Missing lots of features from the UNIX version, such as
       # uid, etc.
       def run_command
-
         #
         # Create pipes to capture stdout and stderr,
         #
@@ -79,6 +78,7 @@
           # Start the process
           #
           process = Process.create(create_process_args)
+          logger.debug(Utils.format_process(process, app_name, command_line, 
timeout)) if logger
           begin
             # Start pushing data into input
             stdin_write << input if input
@@ -107,12 +107,19 @@
                 # Kill the process
                 if (Time.now - start_wait) > timeout
                   begin
+                    require 'wmi-lite/wmi'
+                    wmi = WmiLite::Wmi.new
+                    Utils.kill_process_tree(process.process_id, wmi, logger)
                     Process.kill(:KILL, process.process_id)
-                  rescue Errno::EIO
+                  rescue Errno::EIO, SystemCallError
                     logger.warn("Failed to kill timed out process 
#{process.process_id}") if logger
                   end
 
-                  raise Mixlib::ShellOut::CommandTimeout, "command timed 
out:\n#{format_for_exception}"
+                  raise Mixlib::ShellOut::CommandTimeout, [
+                    "command timed out:",
+                    format_for_exception,
+                    Utils.format_process(process, app_name, command_line, 
timeout)
+                  ].join("\n")
                 end
 
                 consume_output(open_streams, stdout_read, stderr_read)
@@ -313,6 +320,42 @@
         def self.executable?(path)
           File.executable?(path) && !File.directory?(path)
         end
+
+        # recursively kills all child processes of given pid
+        # calls itself querying for children child procs until
+        # none remain. Important that a single WmiLite instance
+        # is passed in since each creates its own WMI rpc process
+        def self.kill_process_tree(pid, wmi, logger)
+          wmi.query("select * from Win32_Process where 
ParentProcessID=#{pid}").each do |instance|
+            child_pid = instance.wmi_ole_object.processid
+            kill_process_tree(child_pid, wmi, logger)
+            begin
+              logger.debug([
+                "killing child process #{child_pid}::",
+                "#{instance.wmi_ole_object.Name} of parent #{pid}"
+                ].join) if logger
+              kill_process(instance)
+            rescue Errno::EIO, SystemCallError
+              logger.debug([
+                "Failed to kill child process #{child_pid}::",
+                "#{instance.wmi_ole_object.Name} of parent #{pid}"
+              ].join) if logger
+            end
+          end
+        end
+
+        def self.kill_process(instance)
+          Process.kill(:KILL, instance.wmi_ole_object.processid)
+        end
+
+        def self.format_process(process, app_name, command_line, timeout)
+          msg = []
+          msg << "ProcessId: #{process.process_id}"
+          msg << "app_name: #{app_name}"
+          msg << "command_line: #{command_line}"
+          msg << "timeout: #{timeout}"
+          msg.join("\n")
+        end
       end
     end # class
   end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metadata new/metadata
--- old/metadata        2015-09-12 00:55:24.000000000 +0200
+++ new/metadata        2015-10-23 01:48:41.000000000 +0200
@@ -1,14 +1,14 @@
 --- !ruby/object:Gem::Specification
 name: mixlib-shellout
 version: !ruby/object:Gem::Version
-  version: 2.2.1
+  version: 2.2.3
 platform: ruby
 authors:
 - Opscode
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2015-09-11 00:00:00.000000000 Z
+date: 2015-10-22 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: rspec
@@ -32,14 +32,18 @@
 - README.md
 - LICENSE
 files:
+- Gemfile
 - LICENSE
 - README.md
+- Rakefile
 - lib/mixlib/shellout.rb
 - lib/mixlib/shellout/exceptions.rb
 - lib/mixlib/shellout/unix.rb
 - lib/mixlib/shellout/version.rb
 - lib/mixlib/shellout/windows.rb
 - lib/mixlib/shellout/windows/core_ext.rb
+- mixlib-shellout-windows.gemspec
+- mixlib-shellout.gemspec
 homepage: http://wiki.opscode.com/
 licenses: []
 metadata: {}
@@ -59,8 +63,9 @@
       version: '0'
 requirements: []
 rubyforge_project: 
-rubygems_version: 2.4.4
+rubygems_version: 2.4.8
 signing_key: 
 specification_version: 4
 summary: Run external commands on Unix or Windows
 test_files: []
+has_rdoc: 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mixlib-shellout-windows.gemspec 
new/mixlib-shellout-windows.gemspec
--- old/mixlib-shellout-windows.gemspec 1970-01-01 01:00:00.000000000 +0100
+++ new/mixlib-shellout-windows.gemspec 2015-10-23 01:48:41.000000000 +0200
@@ -0,0 +1,8 @@
+gemspec = eval(File.read(File.expand_path("../mixlib-shellout.gemspec", 
__FILE__)))
+
+gemspec.platform = Gem::Platform.new(["universal", "mingw32"])
+
+gemspec.add_dependency "win32-process", "~> 0.8.2"
+gemspec.add_dependency "wmi-lite", "~> 1.0"
+
+gemspec
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mixlib-shellout.gemspec new/mixlib-shellout.gemspec
--- old/mixlib-shellout.gemspec 1970-01-01 01:00:00.000000000 +0100
+++ new/mixlib-shellout.gemspec 2015-10-23 01:48:41.000000000 +0200
@@ -0,0 +1,24 @@
+$:.unshift(File.dirname(__FILE__) + '/lib')
+require 'mixlib/shellout/version'
+
+Gem::Specification.new do |s|
+  s.name = 'mixlib-shellout'
+  s.version = Mixlib::ShellOut::VERSION
+  s.platform = Gem::Platform::RUBY
+  s.extra_rdoc_files = ["README.md", "LICENSE" ]
+  s.summary = "Run external commands on Unix or Windows"
+  s.description = s.summary
+  s.author = "Opscode"
+  s.email = "i...@opscode.com"
+  s.homepage = "http://wiki.opscode.com/";
+
+  s.required_ruby_version = ">= 1.9.3"
+
+  s.add_development_dependency "rspec", "~> 3.0"
+
+  s.bindir       = "bin"
+  s.executables  = []
+  s.require_path = 'lib'
+  s.files = %w(Gemfile Rakefile LICENSE README.md) + Dir.glob("*.gemspec") +
+      Dir.glob("lib/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) }
+end


Reply via email to