Class: Down::Wget::Command

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

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.



153
154
155
156
157
# File 'lib/down/wget.rb', line 153

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



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/down/wget.rb', line 137

def self.execute(arguments)
  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



202
203
204
205
# File 'lib/down/wget.rb', line 202

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

#outputObject



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/down/wget.rb', line 159

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

  case status.exitstatus
  when 0  # No problems occurred
    # success
  when 1, # Generic error code
       2, # Parse error---for instance, when parsing command-line options, the .wgetrc or .netrc...
       3  # File I/O error
    raise Down::Error, stderr
  when 4  # Network failure
    raise Down::TimeoutError, stderr if stderr.include?("timed out")
    raise Down::ConnectionError, stderr
  when 5  # SSL verification failure
    raise Down::SSLError, stderr
  when 6  # Username/password authentication failure
    raise Down::ClientError, stderr
  when 7  # Protocol errors
    raise Down::Error, stderr
  when 8  # Server issued an error response
    raise Down::TooManyRedirects, stderr if stderr.include?("redirections exceeded")
    raise Down::ResponseError, stderr
  end
end

#terminateObject



192
193
194
195
196
197
198
199
200
# File 'lib/down/wget.rb', line 192

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

  close
end