ping.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. // defines basic mechanics for pingstats
  2. package ping
  3. import (
  4. "os/exec"
  5. "strings"
  6. "strconv"
  7. "errors"
  8. )
  9. // runPing returns the byte array as returned by [exec.Command]
  10. //
  11. // NOTE(os): this function may fail on non-unix compliant implementations of the Ping spec.
  12. func runPing(address string) (delay *[]byte, err error){
  13. out, err := exec.Command("ping", address, "-c 1").Output()
  14. if err != nil {
  15. return nil, err
  16. }
  17. return &out, err
  18. }
  19. // splitBytesToLines splits bytes as returned by [pingstats.runPing] into an
  20. // array of strings by newline
  21. func splitBytesToLines(bytes *[]byte) (lines []string) {
  22. return strings.Split(strings.ReplaceAll(string(*bytes), "\r\n", "\n"), "\n")
  23. }
  24. // Ping returns the delay of a single Ping as reported by the system Ping binary.
  25. //
  26. // If the function is unable to resolve the system binary output or fails to
  27. // successfully resolve a Ping, it will always return -1.
  28. //
  29. // NOTE(os): this function may fail on non-unix compliant implementations of the Ping spec.
  30. func Ping(address string) (delay float64, err error) {
  31. out, err := runPing(address)
  32. if err != nil {
  33. return -1, err
  34. }
  35. lines := splitBytesToLines(out)
  36. for i:=0;i<len(lines);i++ {
  37. if strings.Contains(lines[i], "bytes from") {
  38. position := strings.Index(lines[i], "time=")
  39. before, _, success := strings.Cut(lines[i][position:], " ")
  40. if ! success {
  41. return -1, errors.New("Line does not match pattern!")
  42. }
  43. _, after, success := strings.Cut(before, "=")
  44. if ! success {
  45. return -1, errors.New("Line does not match pattern!")
  46. }
  47. delay, _ := strconv.ParseFloat(after, 64)
  48. return delay, nil
  49. }
  50. }
  51. return -1, errors.New("could not resolve host: " + address)
  52. }