This repository has been archived on 2021-09-15. You can view files and clone it, but cannot push or open issues or pull requests.
DUT2Curling/lib/net/external.rb

118 lines
3.0 KiB
Ruby

require 'ffi'
require 'open3'
require 'rbconfig'
require File.join(File.dirname(__FILE__), 'ping')
# The Net module serves as a namespace only.
module Net
# The Ping::External class encapsulates methods for external (system) pings.
class Ping::External < Ping
if File::ALT_SEPARATOR
extend FFI::Library
ffi_lib 'kernel32'
attach_function :SetConsoleCP, [:uint], :bool
attach_function :GetConsoleCP, [], :uint
end
# Pings the host using your system's ping utility and checks for any
# errors or warnings. Returns true if successful, or false if not.
#
# If the ping failed then the Ping::External#exception method should
# contain a string indicating what went wrong. If the ping succeeded then
# the Ping::External#warning method may or may not contain a value.
#
def ping(host = @host)
super(host)
stdin = stdout = stderr = nil
pcmd = ["ping"]
bool = false
orig_cp = nil
case RbConfig::CONFIG['host_os']
when /linux|bsd|osx|mach|darwin/i
pcmd += ['-c1', host]
when /solaris|sunos/i
pcmd += [host, '1']
when /hpux/i
pcmd += [host, '-n1']
when /win32|windows|msdos|mswin|cygwin|mingw/i
orig_cp = GetConsoleCP()
SetConsoleCP(437) if orig_cp != 437 # United States
pcmd += ['-n', '1', host]
else
pcmd += [host]
end
start_time = Time.now
begin
err = nil
Timeout.timeout(@timeout){
stdin, stdout, stderr = Open3.popen3(*pcmd)
err = stderr.gets # Can't chomp yet, might be nil
}
stdin.close
stderr.close
if File::ALT_SEPARATOR && GetConsoleCP() != orig_cp
SetConsoleCP(orig_cp)
end
unless err.nil?
if err =~ /warning/i
@warning = err.chomp
bool = true
else
@exception = err.chomp
end
# The "no answer" response goes to stdout, not stderr, so check it
else
lines = stdout.readlines
stdout.close
if lines.nil? || lines.empty?
bool = true
else
regexp = /
no\ answer|
host\ unreachable|
could\ not\ find\ host|
request\ timed\ out|
100%\ packet\ loss
/ix
lines.each{ |line|
if regexp.match(line)
@exception = line.chomp
break
end
}
bool = true unless @exception
end
end
rescue Exception => error
@exception = error.message
ensure
stdin.close if stdin && !stdin.closed?
stdout.close if stdout && !stdout.closed?
stderr.close if stderr && !stderr.closed?
end
# There is no duration if the ping failed
@duration = Time.now - start_time if bool
bool
end
alias ping? ping
alias pingecho ping
end
end