proc_limits.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package procfs
  2. import (
  3. "bufio"
  4. "fmt"
  5. "regexp"
  6. "strconv"
  7. )
  8. // ProcLimits represents the soft limits for each of the process's resource
  9. // limits.
  10. type ProcLimits struct {
  11. CPUTime int
  12. FileSize int
  13. DataSize int
  14. StackSize int
  15. CoreFileSize int
  16. ResidentSet int
  17. Processes int
  18. OpenFiles int
  19. LockedMemory int
  20. AddressSpace int
  21. FileLocks int
  22. PendingSignals int
  23. MsqqueueSize int
  24. NicePriority int
  25. RealtimePriority int
  26. RealtimeTimeout int
  27. }
  28. const (
  29. limitsFields = 3
  30. limitsUnlimited = "unlimited"
  31. )
  32. var (
  33. limitsDelimiter = regexp.MustCompile(" +")
  34. )
  35. // NewLimits returns the current soft limits of the process.
  36. func (p Proc) NewLimits() (ProcLimits, error) {
  37. f, err := p.open("limits")
  38. if err != nil {
  39. return ProcLimits{}, err
  40. }
  41. defer f.Close()
  42. var (
  43. l = ProcLimits{}
  44. s = bufio.NewScanner(f)
  45. )
  46. for s.Scan() {
  47. fields := limitsDelimiter.Split(s.Text(), limitsFields)
  48. if len(fields) != limitsFields {
  49. return ProcLimits{}, fmt.Errorf(
  50. "couldn't parse %s line %s", f.Name(), s.Text())
  51. }
  52. switch fields[0] {
  53. case "Max cpu time":
  54. l.CPUTime, err = parseInt(fields[1])
  55. case "Max file size":
  56. l.FileLocks, err = parseInt(fields[1])
  57. case "Max data size":
  58. l.DataSize, err = parseInt(fields[1])
  59. case "Max stack size":
  60. l.StackSize, err = parseInt(fields[1])
  61. case "Max core file size":
  62. l.CoreFileSize, err = parseInt(fields[1])
  63. case "Max resident set":
  64. l.ResidentSet, err = parseInt(fields[1])
  65. case "Max processes":
  66. l.Processes, err = parseInt(fields[1])
  67. case "Max open files":
  68. l.OpenFiles, err = parseInt(fields[1])
  69. case "Max locked memory":
  70. l.LockedMemory, err = parseInt(fields[1])
  71. case "Max address space":
  72. l.AddressSpace, err = parseInt(fields[1])
  73. case "Max file locks":
  74. l.FileLocks, err = parseInt(fields[1])
  75. case "Max pending signals":
  76. l.PendingSignals, err = parseInt(fields[1])
  77. case "Max msgqueue size":
  78. l.MsqqueueSize, err = parseInt(fields[1])
  79. case "Max nice priority":
  80. l.NicePriority, err = parseInt(fields[1])
  81. case "Max realtime priority":
  82. l.RealtimePriority, err = parseInt(fields[1])
  83. case "Max realtime timeout":
  84. l.RealtimeTimeout, err = parseInt(fields[1])
  85. }
  86. if err != nil {
  87. return ProcLimits{}, err
  88. }
  89. }
  90. return l, s.Err()
  91. }
  92. func parseInt(s string) (int, error) {
  93. if s == limitsUnlimited {
  94. return -1, nil
  95. }
  96. i, err := strconv.ParseInt(s, 10, 32)
  97. if err != nil {
  98. return 0, fmt.Errorf("couldn't parse value %s: %s", s, err)
  99. }
  100. return int(i), nil
  101. }