fd.go 1.4 KB

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