Module: Mixlib::ShellOut::Windows
- Includes:
- Windows::Handle, Windows::Process, Windows::Synchronize
- Included in:
- Mixlib::ShellOut
- Defined in:
- lib/mixlib/shellout/windows.rb
Defined Under Namespace
Modules: Utils Classes: ThingThatLooksSortOfLikeAProcessStatus
Constant Summary collapse
- TIME_SLICE =
0.05
Instance Method Summary collapse
-
#run_command ⇒ Object
– Missing lots of features from the UNIX version, such as uid, etc.
-
#validate_options(opts) ⇒ Object
Option validation that is windows specific.
Instance Method Details
#run_command ⇒ Object
– Missing lots of features from the UNIX version, such as uid, etc.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/mixlib/shellout/windows.rb', line 50 def run_command # # Create pipes to capture stdout and stderr, # stdout_read, stdout_write = IO.pipe stderr_read, stderr_write = IO.pipe stdin_read, stdin_write = IO.pipe open_streams = [ stdout_read, stderr_read ] begin # # Set cwd, environment, appname, etc. # app_name, command_line = command_to_run(self.command) create_process_args = { :app_name => app_name, :command_line => command_line, :startup_info => { :stdout => stdout_write, :stderr => stderr_write, :stdin => stdin_read }, :environment => inherit_environment.map { |k,v| "#{k}=#{v}" }, :close_handles => false } create_process_args[:cwd] = cwd if cwd # default to local account database if domain is not specified create_process_args[:domain] = domain.nil? ? "." : domain create_process_args[:with_logon] = with_logon if with_logon create_process_args[:password] = password if password # # Start the process # process = Process.create(create_process_args) begin # Start pushing data into input stdin_write << input if input # Close pipe to kick things off stdin_write.close # # Wait for the process to finish, consuming output as we go # start_wait = Time.now while true wait_status = WaitForSingleObject(process.process_handle, 0) case wait_status when WAIT_OBJECT_0 # Get process exit code exit_code = [0].pack('l') unless GetExitCodeProcess(process.process_handle, exit_code) raise get_last_error end @status = ThingThatLooksSortOfLikeAProcessStatus.new @status.exitstatus = exit_code.unpack('l').first return self when WAIT_TIMEOUT # Kill the process if (Time.now - start_wait) > timeout begin Process.kill(:KILL, process.process_id) rescue Errno::EIO 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}" end consume_output(open_streams, stdout_read, stderr_read) else raise "Unknown response from WaitForSingleObject(#{process.process_handle}, #{timeout*1000}): #{wait_status}" end end ensure CloseHandle(process.thread_handle) if process.thread_handle CloseHandle(process.process_handle) if process.process_handle end ensure # # Consume all remaining data from the pipes until they are closed # stdout_write.close stderr_write.close while consume_output(open_streams, stdout_read, stderr_read) end end end |
#validate_options(opts) ⇒ Object
Option validation that is windows specific
39 40 41 42 43 44 45 |
# File 'lib/mixlib/shellout/windows.rb', line 39 def (opts) if opts[:user] unless opts[:password] raise InvalidCommandOption, "You must supply both a username and password when supplying a user in windows" end end end |