Class: Net::Ping::External

Inherits:
Net::Ping show all
Extended by:
FFI::Library
Defined in:
lib/net/ping/external.rb

Overview

The Ping::External class encapsulates methods for external (system) pings.

Constant Summary

Constants inherited from Net::Ping

VERSION

Instance Attribute Summary

Attributes inherited from Net::Ping

#duration, #exception, #host, #port, #timeout, #warning

Instance Method Summary collapse

Methods inherited from Net::Ping

#initialize

Constructor Details

This class inherits a constructor from Net::Ping

Instance Method Details

#ping(host = @host) ⇒ Object Also known as: ping?, pingecho

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.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
# File 'lib/net/ping/external.rb', line 33

def ping(host = @host)
  super(host)

  stdin = stdout = stderr = nil
  pstring = "ping "
  bool    = false
  orig_cp = nil

  case RbConfig::CONFIG['host_os']
    when /linux|bsd|osx|mach|darwin/i
      pstring += "-c 1 #{host}"
    when /solaris|sunos/i
      pstring += "#{host} 1"
    when /hpux/i
      pstring += "#{host} -n 1"
    when /win32|windows|msdos|mswin|cygwin|mingw/i
      orig_cp = GetConsoleCP()
      SetConsoleCP(437) if orig_cp != 437 # United States
      pstring += "-n 1 #{host}"
    else
      pstring += "#{host}"
  end

  start_time = Time.now

  begin
    err = nil

    Timeout.timeout(@timeout){
      stdin, stdout, stderr = Open3.popen3(pstring)
      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