conncheck.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2019 The Go-MySQL-Driver Authors. All rights reserved.
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public
  6. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  7. // You can obtain one at http://mozilla.org/MPL/2.0/.
  8. //go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || illumos
  9. // +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos
  10. package mysql
  11. import (
  12. "errors"
  13. "io"
  14. "net"
  15. "syscall"
  16. )
  17. var errUnexpectedRead = errors.New("unexpected read from socket")
  18. func connCheck(conn net.Conn) error {
  19. var sysErr error
  20. sysConn, ok := conn.(syscall.Conn)
  21. if !ok {
  22. return nil
  23. }
  24. rawConn, err := sysConn.SyscallConn()
  25. if err != nil {
  26. return err
  27. }
  28. err = rawConn.Read(func(fd uintptr) bool {
  29. var buf [1]byte
  30. n, err := syscall.Read(int(fd), buf[:])
  31. switch {
  32. case n == 0 && err == nil:
  33. sysErr = io.EOF
  34. case n > 0:
  35. sysErr = errUnexpectedRead
  36. case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK:
  37. sysErr = nil
  38. default:
  39. sysErr = err
  40. }
  41. return true
  42. })
  43. if err != nil {
  44. return err
  45. }
  46. return sysErr
  47. }