fd.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package proc
  2. import (
  3. "os"
  4. "path"
  5. "strconv"
  6. "strings"
  7. klog "github.com/sirupsen/logrus"
  8. )
  9. type Fd struct {
  10. Fd uint64
  11. Dest string
  12. SocketInode string
  13. }
  14. func ReadFds(pid uint32) ([]Fd, error) {
  15. fdDir := Path(pid, "fd")
  16. entries, err := os.ReadDir(fdDir)
  17. if err != nil {
  18. if os.IsNotExist(err) {
  19. return nil, nil
  20. }
  21. return nil, err
  22. }
  23. res := make([]Fd, 0, len(entries))
  24. for _, entry := range entries {
  25. fd, err := strconv.ParseUint(entry.Name(), 10, 64)
  26. if err != nil {
  27. klog.Warningf("failed to parse fd '%s': %s", entry.Name(), err)
  28. continue
  29. }
  30. dest, err := os.Readlink(path.Join(fdDir, entry.Name()))
  31. if err != nil {
  32. if os.IsNotExist(err) {
  33. klog.Warningf("failed to read link '%s': %s", entry.Name(), err)
  34. }
  35. continue
  36. }
  37. var socketInode string
  38. if strings.HasPrefix(dest, "socket:[") && strings.HasSuffix(dest, "]") {
  39. socketInode = dest[len("socket:[") : len(dest)-1]
  40. }
  41. res = append(res, Fd{Fd: fd, Dest: dest, SocketInode: socketInode})
  42. }
  43. return res, nil
  44. }
  45. type FdInfo struct {
  46. MntId string
  47. Flags int
  48. Dest string
  49. }
  50. func GetFdInfo(pid uint32, fd uint64) *FdInfo {
  51. fds := strconv.FormatUint(fd, 10)
  52. data, err := os.ReadFile(Path(pid, "fdinfo", fds))
  53. if err != nil {
  54. return nil
  55. }
  56. dest, err := os.Readlink(Path(pid, "fd", fds))
  57. if err != nil {
  58. return nil
  59. }
  60. res := FdInfo{Dest: dest}
  61. for _, line := range strings.Split(string(data), "\n") {
  62. if strings.HasPrefix(line, "mnt_id:") {
  63. res.MntId = strings.TrimSpace(strings.TrimPrefix(line, "mnt_id:"))
  64. continue
  65. }
  66. if strings.HasPrefix(line, "flags:") {
  67. flags, _ := strconv.ParseInt(strings.TrimSpace(strings.TrimPrefix(line, "flags:")), 8, 32)
  68. res.Flags = int(flags)
  69. continue
  70. }
  71. }
  72. return &res
  73. }