Class: Down::Wget::Command

Inherits:
Object
  • Object
show all
Defined in:
lib/down/wget.rb

Overview

Handles executing the wget command.

Constant Summary collapse

PIPE_BUFFER_SIZE =
64*1024

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdout_pipe, stderr_pipe, status_reaper) ⇒ Command

Returns a new instance of Command.



165
166
167
168
169
# File 'lib/down/wget.rb', line 165

def initialize(stdout_pipe, stderr_pipe, status_reaper)
  @status_reaper = status_reaper
  @stdout_pipe   = stdout_pipe
  @stderr_pipe   = stderr_pipe
end

Class Method Details

.execute(arguments) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/down/wget.rb', line 148

def self.execute(arguments)
  # posix-spawn gem has better performance, so we use it if it's available
  if defined?(POSIX::Spawn)
    pid, stdin_pipe, stdout_pipe, stderr_pipe = POSIX::Spawn.popen4(*arguments)
    status_reaper = Process.detach(pid)
  else
    stdin_pipe, stdout_pipe, stderr_pipe, status_reaper = Open3.popen3(*arguments)
  end

  stdin_pipe.close
  [stdout_pipe, stderr_pipe].each(&:binmode)

  new(stdout_pipe, stderr_pipe, status_reaper)
rescue Errno::ENOENT
  raise Down::Error, "wget is not installed"
end

Instance Method Details

#closeObject



198
199
200
201
# File 'lib/down/wget.rb', line 198

def close
  @stdout_pipe.close unless @stdout_pipe.closed?
  @stderr_pipe.close unless @stderr_pipe.closed?
end

#outputObject

Yields chunks of stdout. At the end handles the exit status.



172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/down/wget.rb', line 172

def output
  # Keep emptying the stderr buffer, to allow the subprocess to send more
  # than 64KB if it wants to.
  stderr_reader = Thread.new { @stderr_pipe.read }

  yield @stdout_pipe.readpartial(PIPE_BUFFER_SIZE) until @stdout_pipe.eof?

  status = @status_reaper.value
  stderr = stderr_reader.value

  close

  handle_status(status, stderr)
end

#terminateObject



187
188
189
190
191
192
193
194
195
196
# File 'lib/down/wget.rb', line 187

def terminate
  begin
    Process.kill("TERM", @status_reaper[:pid])
    Process.waitpid(@status_reaper[:pid])
  rescue Errno::ESRCH
    # process has already terminated
  end

  close
end