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.



143
144
145
146
147
# File 'lib/down/wget.rb', line 143

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



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/down/wget.rb', line 127

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



192
193
194
195
# File 'lib/down/wget.rb', line 192

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

#outputObject



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/down/wget.rb', line 149

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



182
183
184
185
186
187
188
189
190
# File 'lib/down/wget.rb', line 182

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

  close
end