sys-proctable 1.2.6 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/{CHANGES.rdoc → CHANGES.md} +69 -49
  4. data/Gemfile +2 -0
  5. data/{MANIFEST.rdoc → MANIFEST.md} +9 -1
  6. data/README.md +9 -3
  7. data/Rakefile +10 -7
  8. data/certs/djberg96_pub.pem +26 -0
  9. data/lib/bsd/sys/dragonfly/sys/proctable/constants.rb +11 -0
  10. data/lib/bsd/sys/dragonfly/sys/proctable/functions.rb +14 -0
  11. data/lib/bsd/sys/dragonfly/sys/proctable/structs.rb +298 -0
  12. data/lib/bsd/sys/dragonfly/sys/proctable.rb +175 -0
  13. data/lib/bsd/sys/freebsd/sys/proctable/constants.rb +0 -0
  14. data/lib/bsd/sys/freebsd/sys/proctable/functions.rb +0 -0
  15. data/lib/bsd/sys/freebsd/sys/proctable/structs.rb +0 -0
  16. data/lib/{freebsd → bsd/sys/freebsd}/sys/proctable.rb +1 -1
  17. data/lib/bsd/sys/proctable.rb +8 -0
  18. data/lib/darwin/sys/proctable.rb +53 -20
  19. data/lib/linux/sys/proctable/cgroup_entry.rb +4 -2
  20. data/lib/linux/sys/proctable/smaps.rb +29 -17
  21. data/lib/linux/sys/proctable.rb +41 -35
  22. data/lib/sunos/sys/proctable.rb +2 -2
  23. data/lib/sys/proctable/version.rb +1 -1
  24. data/lib/sys/proctable.rb +2 -2
  25. data/lib/sys/top.rb +7 -2
  26. data/lib/windows/sys/proctable.rb +36 -32
  27. data/spec/spec_helper.rb +15 -0
  28. data/spec/sys_proctable_aix_spec.rb +74 -76
  29. data/spec/sys_proctable_all_spec.rb +45 -45
  30. data/spec/sys_proctable_bsd_spec.rb +244 -0
  31. data/spec/sys_proctable_darwin_spec.rb +85 -58
  32. data/spec/sys_proctable_linux_spec.rb +196 -195
  33. data/spec/sys_proctable_sunos_spec.rb +190 -192
  34. data/spec/sys_proctable_windows_spec.rb +153 -153
  35. data/spec/sys_top_spec.rb +20 -21
  36. data/sys-proctable.gemspec +16 -24
  37. data.tar.gz.sig +0 -0
  38. metadata +78 -18
  39. metadata.gz.sig +0 -0
  40. data/spec/sys_proctable_freebsd_spec.rb +0 -210
@@ -0,0 +1,298 @@
1
+ require 'ffi'
2
+ require_relative 'constants'
3
+
4
+ module Sys
5
+ module ProcTableStructs
6
+ extend FFI::Library
7
+
8
+ class Timeval < FFI::Struct
9
+ layout(:tv_sec, :time_t, :tv_usec, :suseconds_t)
10
+ end
11
+
12
+ class RTPrio < FFI::Struct
13
+ layout(:type, :ushort, :prio, :ushort)
14
+ end
15
+
16
+ class Rusage < FFI::Struct
17
+ layout(
18
+ :ru_utime, Timeval,
19
+ :ru_stime, Timeval,
20
+ :ru_maxrss, :long,
21
+ :ru_ixrss, :long,
22
+ :ru_idrss, :long,
23
+ :ru_isrss, :long,
24
+ :ru_minflt, :long,
25
+ :ru_majflt, :long,
26
+ :ru_nswap, :long,
27
+ :ru_inblock, :long,
28
+ :ru_oublock, :long,
29
+ :ru_msgsnd, :long,
30
+ :ru_msgrcv, :long,
31
+ :ru_nsignals, :long,
32
+ :ru_nvcsw, :long,
33
+ :ru_nivcsw, :long
34
+ )
35
+
36
+ def utime
37
+ Time.at(self[:ru_utime][:tv_sec])
38
+ end
39
+
40
+ def stime
41
+ Time.at(self[:ru_stime][:tv_sec])
42
+ end
43
+
44
+ def maxrss
45
+ self[:ru_maxrss]
46
+ end
47
+
48
+ def ixrss
49
+ self[:ru_ixrss]
50
+ end
51
+
52
+ def idrss
53
+ self[:ru_idrss]
54
+ end
55
+
56
+ def isrss
57
+ self[:ru_isrss]
58
+ end
59
+
60
+ def minflt
61
+ self[:ru_minflt]
62
+ end
63
+
64
+ def majflt
65
+ self[:ru_majflt]
66
+ end
67
+
68
+ def nswap
69
+ self[:ru_nswap]
70
+ end
71
+
72
+ def inblock
73
+ self[:ru_inblock]
74
+ end
75
+
76
+ def oublock
77
+ self[:ru_oublock]
78
+ end
79
+
80
+ def msgsnd
81
+ self[:ru_msgsnd]
82
+ end
83
+
84
+ def msgrcv
85
+ self[:ru_msgrcv]
86
+ end
87
+
88
+ def nsignals
89
+ self[:ru_nsignals]
90
+ end
91
+
92
+ def nvcsw
93
+ self[:ru_nivcsw]
94
+ end
95
+
96
+ def nivcsw
97
+ self[:ru_nivcsw]
98
+ end
99
+ end
100
+
101
+ enum :lwpstat, [:LSRUN, 1, :LSSTOP, :LSSLEEP]
102
+ enum :procstat, [:SIDL, 1, :SACTIVE, :SSTOP, :SZOMB, :SCORE]
103
+
104
+ class Sigset < FFI::Struct
105
+ layout(:__bits, [:uint, 4])
106
+
107
+ def bits
108
+ self[:__bits].to_a
109
+ end
110
+ end
111
+
112
+ class KInfoLWP < FFI::Struct
113
+ include Sys::ProcTableConstants
114
+
115
+ layout(
116
+ :kl_pid, :pid_t,
117
+ :kl_tid, :lwpid_t,
118
+ :kl_flags, :int,
119
+ :kl_stat, :lwpstat,
120
+ :kl_lock, :int,
121
+ :kl_tdflags, :int,
122
+ :kl_mpcount, :int,
123
+ :kl_prio, :int,
124
+ :kl_tdprio, :int,
125
+ :kl_rtprio, RTPrio,
126
+ :kl_uticks, :uint64_t,
127
+ :kl_sticks, :uint64_t,
128
+ :kl_iticks, :uint64_t,
129
+ :kl_cpticks, :uint64_t,
130
+ :kl_pctcpu, :uint,
131
+ :kl_slptime, :uint,
132
+ :kl_origcpu, :int,
133
+ :kl_estcpu, :int,
134
+ :kl_cpuid, :int,
135
+ :kl_ru, Rusage,
136
+ :kl_siglist, Sigset,
137
+ :kl_sigmask, Sigset,
138
+ :kl_wchan, :uintptr_t,
139
+ :kl_wmesg, [:char, WMESGLEN+1],
140
+ :kl_comm, [:char, MAXCOMLEN+1]
141
+ )
142
+
143
+ def pid
144
+ self[:kl_pid]
145
+ end
146
+
147
+ def tid
148
+ self[:kl_tid]
149
+ end
150
+
151
+ def flags
152
+ self[:kl_flags]
153
+ end
154
+
155
+ def stat
156
+ self[:kl_stat]
157
+ end
158
+
159
+ def lock
160
+ self[:kl_lock]
161
+ end
162
+
163
+ def tdflags
164
+ self[:kl_tdflags]
165
+ end
166
+
167
+ def prio
168
+ self[:kl_prio]
169
+ end
170
+
171
+ def tdprio
172
+ self[:kl_tdprio]
173
+ end
174
+
175
+ def rtprio
176
+ self[:kl_rtprio]
177
+ end
178
+
179
+ def uticks
180
+ self[:kl_uticks]
181
+ end
182
+
183
+ def sticks
184
+ self[:kl_sticks]
185
+ end
186
+
187
+ def iticks
188
+ self[:kl_iticks]
189
+ end
190
+
191
+ def cpticks
192
+ self[:kl_cpticks]
193
+ end
194
+
195
+ def pctcpu
196
+ self[:kl_pctcpu]
197
+ end
198
+
199
+ def slptime
200
+ self[:kl_slptime]
201
+ end
202
+
203
+ def origcpu
204
+ self[:kl_origcpu]
205
+ end
206
+
207
+ def estcpu
208
+ self[:kl_estcpu]
209
+ end
210
+
211
+ def cpuid
212
+ self[:kl_cpuid]
213
+ end
214
+
215
+ def ru
216
+ self[:kl_ru]
217
+ end
218
+
219
+ def siglist
220
+ self[:kl_siglist]
221
+ end
222
+
223
+ def sigmask
224
+ self[:kl_sigmask]
225
+ end
226
+
227
+ def wchan
228
+ self[:kl_wchan]
229
+ end
230
+
231
+ def wmesg
232
+ self[:kl_wmesg].to_s
233
+ end
234
+
235
+ def comm
236
+ self[:kl_comm].to_s
237
+ end
238
+ end
239
+
240
+ class KInfoProc < FFI::Struct
241
+ include Sys::ProcTableConstants
242
+
243
+ def self.roundup(x, y)
244
+ ((x + y-1) / y) * y
245
+ end
246
+
247
+ layout(
248
+ :kp_paddr, :uintptr_t,
249
+ :kp_flags, :int,
250
+ :kp_stat, :procstat,
251
+ :kp_lock, :int,
252
+ :kp_acflag, :int,
253
+ :kp_traceflag, :int,
254
+ :kp_fd, :uintptr_t,
255
+ :kp_siglist, Sigset,
256
+ :kp_sigignore, Sigset,
257
+ :kp_sigcatch, Sigset,
258
+ :kp_sigflag, :int,
259
+ :kp_start, Timeval,
260
+ :kp_comm, [:char, MAXCOMLEN+1],
261
+ :kp_uid, :uid_t,
262
+ :kp_ngroups, :short,
263
+ :kp_groups, [:gid_t, NGROUPS],
264
+ :kp_ruid, :uid_t,
265
+ :kp_svuid, :uid_t,
266
+ :kp_rgid, :gid_t,
267
+ :kp_svgid, :gid_t,
268
+ :kp_pid, :pid_t,
269
+ :kp_ppid, :pid_t,
270
+ :kp_pgid, :pid_t,
271
+ :kp_jobc, :int,
272
+ :kp_sid, :pid_t,
273
+ :kp_login, [:char, roundup(MAXLOGNAME, FFI::Type::LONG.size)],
274
+ :kp_tdev, :dev_t,
275
+ :kp_tpgid, :pid_t,
276
+ :kp_tsid, :pid_t,
277
+ :kp_exitstat, :ushort,
278
+ :kp_nthreads, :int,
279
+ :kp_nice, :int,
280
+ :kp_swtime, :uint,
281
+ :kp_vm_map_size, :size_t,
282
+ :kp_vm_rssize, :segsz_t,
283
+ :kp_vm_swrss, :segsz_t,
284
+ :kp_vm_tsize, :segsz_t,
285
+ :kp_vm_dsize, :segsz_t,
286
+ :kp_vm_ssize, :segsz_t,
287
+ :kp_vm_prssize, :uint,
288
+ :kp_jailid, :int,
289
+ :kp_ru, Rusage,
290
+ :kp_cru, Rusage,
291
+ :kp_auxflags, :int,
292
+ :kp_lwp, KInfoLWP,
293
+ :kp_ktaddr, :uintptr_t,
294
+ :kp_spare, [:int, 2]
295
+ )
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,175 @@
1
+ require_relative 'proctable/constants'
2
+ require_relative 'proctable/structs'
3
+ require_relative 'proctable/functions'
4
+ require 'sys/proctable/version'
5
+
6
+ module Sys
7
+ class ProcTable
8
+ include Sys::ProcTableConstants
9
+ include Sys::ProcTableStructs
10
+ extend Sys::ProcTableFunctions
11
+
12
+ # Error typically raised if the ProcTable.ps method fails.
13
+ class Error < StandardError; end
14
+
15
+ # There is no constructor
16
+ private_class_method :new
17
+
18
+ @fields = %w[
19
+ paddr flags stat lock acflag traceflag fd siglist sigignore
20
+ sigcatch sigflag start comm uid ngroups groups ruid svuid
21
+ rgid svgid pid ppid pgid jobc sid login tdev tpgid tsid exitstat
22
+ nthreads nice swtime vm_map_size vm_rssize vm_swrss vm_tsize
23
+ vm_dsize vm_ssize vm_prssize jailid ru cru auxflags lwp ktaddr
24
+ ]
25
+
26
+ ProcTableStruct = Struct.new('ProcTableStruct', *@fields) do
27
+ alias cmdline comm
28
+ end
29
+
30
+ # In block form, yields a ProcTableStruct for each process entry that you
31
+ # have rights to. This method returns an array of ProcTableStruct's in
32
+ # non-block form.
33
+ #
34
+ # If a +pid+ is provided, then only a single ProcTableStruct is yielded or
35
+ # returned, or nil if no process information is found for that +pid+.
36
+ #
37
+ # Example:
38
+ #
39
+ # # Iterate over all processes
40
+ # ProcTable.ps do |proc_info|
41
+ # p proc_info
42
+ # end
43
+ #
44
+ # # Print process table information for only pid 1001
45
+ # p ProcTable.ps(pid: 1001)
46
+ #
47
+ def self.ps(**kwargs)
48
+ pid = kwargs[:pid]
49
+
50
+ begin
51
+ kd = kvm_open(nil, nil, nil, 0, nil)
52
+
53
+ if kd.null?
54
+ raise SystemCallError.new('kvm_open', FFI.errno)
55
+ end
56
+
57
+ ptr = FFI::MemoryPointer.new(:int) # count
58
+
59
+ if pid
60
+ procs = kvm_getprocs(kd, KERN_PROC_PID, pid, ptr)
61
+ else
62
+ procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, ptr)
63
+ end
64
+
65
+ if procs.null?
66
+ if pid && FFI.errno == Errno::ESRCH::Errno
67
+ return nil
68
+ else
69
+ raise SystemCallError.new('kvm_getprocs', FFI.errno)
70
+ end
71
+ end
72
+
73
+ count = ptr.read_int
74
+ array = []
75
+
76
+ 0.upto(count-1){ |i|
77
+ cmd = nil
78
+ kinfo = KInfoProc.new(procs[i * KInfoProc.size])
79
+
80
+ args = kvm_getargv(kd, kinfo, 0)
81
+
82
+ unless args.null?
83
+ cmd = []
84
+
85
+ until ((ptr = args.read_pointer).null?)
86
+ cmd << ptr.read_string
87
+ args += FFI::Type::POINTER.size
88
+ end
89
+
90
+ cmd = cmd.join(' ')
91
+ end
92
+
93
+ struct = ProcTableStruct.new(
94
+ kinfo[:kp_paddr],
95
+ kinfo[:kp_flags],
96
+ kinfo[:kp_stat],
97
+ kinfo[:kp_lock],
98
+ kinfo[:kp_acflag],
99
+ kinfo[:kp_traceflag],
100
+ kinfo[:kp_fd],
101
+ kinfo[:kp_siglist].bits,
102
+ kinfo[:kp_sigignore].bits,
103
+ kinfo[:kp_sigcatch].bits,
104
+ kinfo[:kp_sigflag],
105
+ Time.at(kinfo[:kp_start][:tv_sec]),
106
+ kinfo[:kp_comm].to_s,
107
+ kinfo[:kp_uid],
108
+ kinfo[:kp_ngroups],
109
+ kinfo[:kp_groups].to_a[0..kinfo[:kp_ngroups]-1],
110
+ kinfo[:kp_ruid],
111
+ kinfo[:kp_svuid],
112
+ kinfo[:kp_rgid],
113
+ kinfo[:kp_svgid],
114
+ kinfo[:kp_pid],
115
+ kinfo[:kp_ppid],
116
+ kinfo[:kp_pgid],
117
+ kinfo[:kp_jobc],
118
+ kinfo[:kp_sid],
119
+ kinfo[:kp_login].to_s,
120
+ kinfo[:kp_tdev],
121
+ kinfo[:kp_tpgid],
122
+ kinfo[:kp_tsid],
123
+ kinfo[:kp_exitstat],
124
+ kinfo[:kp_nthreads],
125
+ kinfo[:kp_nice],
126
+ kinfo[:kp_swtime],
127
+ kinfo[:kp_vm_map_size],
128
+ kinfo[:kp_vm_rssize],
129
+ kinfo[:kp_vm_swrss],
130
+ kinfo[:kp_vm_tsize],
131
+ kinfo[:kp_vm_dsize],
132
+ kinfo[:kp_vm_ssize],
133
+ kinfo[:kp_vm_prssize],
134
+ kinfo[:kp_jailid],
135
+ kinfo[:kp_ru],
136
+ kinfo[:kp_cru],
137
+ kinfo[:kp_auxflags],
138
+ kinfo[:kp_lwp],
139
+ kinfo[:kp_ktaddr],
140
+ )
141
+
142
+ struct.freeze # This is readonly data
143
+
144
+ if block_given?
145
+ yield struct
146
+ else
147
+ array << struct
148
+ end
149
+ }
150
+ ensure
151
+ kvm_close(kd) unless kd.null?
152
+ end
153
+
154
+ if block_given?
155
+ nil
156
+ else
157
+ pid ? array.first : array
158
+ end
159
+ end
160
+
161
+ # Returns an array of fields that each ProcTableStruct will contain. This
162
+ # may be useful if you want to know in advance what fields are available
163
+ # without having to perform at least one read of the /proc table.
164
+ #
165
+ # Example:
166
+ #
167
+ # Sys::ProcTable.fields.each{ |field|
168
+ # puts "Field: #{field}"
169
+ # }
170
+ #
171
+ def self.fields
172
+ @fields
173
+ end
174
+ end
175
+ end
File without changes
File without changes
File without changes
@@ -77,7 +77,7 @@ module Sys
77
77
  layout(
78
78
  :ar_ref, :uint,
79
79
  :ar_length, :uint,
80
- :ar_args, [:uchar,1]
80
+ :ar_args, [:uchar, 1]
81
81
  )
82
82
  end
83
83
 
@@ -0,0 +1,8 @@
1
+ case RbConfig::CONFIG['host_os']
2
+ when /freebsd/i
3
+ require_relative 'freebsd/sys/proctable'
4
+ when /dragonfly/i
5
+ require_relative 'dragonfly/sys/proctable'
6
+ else
7
+ raise "Unsupported version of BSD"
8
+ end
@@ -11,21 +11,32 @@ module Sys
11
11
  # There is no constructor
12
12
  private_class_method :new
13
13
 
14
- private
15
-
16
14
  PROC_PIDTASKALLINFO = 2
17
15
  PROC_PIDTHREADINFO = 5
18
16
  PROC_PIDLISTTHREADS = 6
19
17
 
18
+ private_constant :PROC_PIDTASKALLINFO
19
+ private_constant :PROC_PIDTHREADINFO
20
+ private_constant :PROC_PIDLISTTHREADS
21
+
20
22
  CTL_KERN = 1
21
23
  KERN_PROCARGS = 38
22
24
  KERN_PROCARGS2 = 49
23
25
  MAXCOMLEN = 16
24
26
  MAXPATHLEN = 256
25
27
 
28
+ private_constant :CTL_KERN
29
+ private_constant :KERN_PROCARGS
30
+ private_constant :KERN_PROCARGS2
31
+ private_constant :MAXCOMLEN
32
+ private_constant :MAXPATHLEN
33
+
26
34
  MAXTHREADNAMESIZE = 64
27
35
  PROC_PIDPATHINFO_MAXSIZE = MAXPATHLEN * 4
28
36
 
37
+ private_constant :MAXTHREADNAMESIZE
38
+ private_constant :PROC_PIDPATHINFO_MAXSIZE
39
+
29
40
  # JRuby/Truffleruby on Mac
30
41
  unless defined? FFI::StructLayout::CharArray
31
42
  if defined? FFI::StructLayout::CharArrayProxy
@@ -62,6 +73,8 @@ module Sys
62
73
  )
63
74
  end
64
75
 
76
+ private_constant :ProcBsdInfo
77
+
65
78
  class ProcTaskInfo < FFI::Struct
66
79
  layout(
67
80
  :pti_virtual_size, :uint64_t,
@@ -85,6 +98,8 @@ module Sys
85
98
  )
86
99
  end
87
100
 
101
+ private_constant :ProcTaskInfo
102
+
88
103
  class ProcThreadInfo < FFI::Struct
89
104
  layout(
90
105
  :pth_user_time, :uint64_t,
@@ -101,28 +116,37 @@ module Sys
101
116
  )
102
117
  end
103
118
 
119
+ private_constant :ProcThreadInfo
120
+
104
121
  # Map the fields from the FFI::Structs to the Sys::ProcTable struct on
105
122
  # class load to reduce the amount of objects needing to be generated for
106
123
  # each invocation of Sys::ProcTable.ps
107
- all_members = ProcBsdInfo.members + ProcTaskInfo.members + ProcThreadInfo.members
108
- PROC_STRUCT_FIELD_MAP = all_members.map { |member|
124
+ all_members = ProcBsdInfo.members + ProcTaskInfo.members + ProcThreadInfo.members
125
+
126
+ PROC_STRUCT_FIELD_MAP = all_members.map do |member|
109
127
  temp = member.to_s.split('_')
110
128
  sproperty = temp.size > 1 ? temp[1..-1].join('_') : temp.first
111
129
  [member, sproperty.to_sym]
112
- }.to_h
130
+ end.to_h
113
131
 
114
132
  class ProcTaskAllInfo < FFI::Struct
115
133
  layout(:pbsd, ProcBsdInfo, :ptinfo, ProcTaskInfo)
116
134
  end
117
135
 
136
+ private_constant :ProcTaskAllInfo
137
+
118
138
  ffi_lib 'proc'
119
139
 
120
- attach_function :proc_listallpids, [:pointer, :int], :int
121
- attach_function :proc_pidinfo, [:int, :int, :uint64_t, :pointer, :int], :int
140
+ attach_function :proc_listallpids, %i[pointer int], :int
141
+ attach_function :proc_pidinfo, %i[int int uint64_t pointer int], :int
122
142
 
123
143
  ffi_lib FFI::Library::LIBC
124
144
 
125
- attach_function :sysctl, [:pointer, :uint, :pointer, :pointer, :pointer, :size_t], :int
145
+ attach_function :sysctl, %i[pointer uint pointer pointer pointer size_t], :int
146
+
147
+ private_class_method :proc_listallpids
148
+ private_class_method :proc_pidinfo
149
+ private_class_method :sysctl
126
150
 
127
151
  # These mostly mimic the struct members, but we've added a few custom ones as well.
128
152
  @fields = %w[
@@ -136,16 +160,18 @@ module Sys
136
160
 
137
161
  # Add a couple aliases to make it similar to Linux
138
162
  ProcTableStruct = Struct.new("ProcTableStruct", *@fields) do
139
- alias vsize virtual_size
140
- alias rss resident_size
163
+ alias_method :vsize, :virtual_size
164
+ alias_method :rss, :resident_size
141
165
  end
142
166
 
167
+ private_constant :ProcTableStruct
168
+
143
169
  ThreadInfoStruct = Struct.new("ThreadInfo", :user_time, :system_time,
144
170
  :cpu_usage, :policy, :run_state, :flags, :sleep_time, :curpri,
145
171
  :priority, :maxpriority, :name
146
172
  )
147
173
 
148
- public
174
+ private_constant :ThreadInfoStruct
149
175
 
150
176
  # Returns an array of fields that each ProcTableStruct will contain. This
151
177
  # may be useful if you want to know in advance what fields are available
@@ -222,7 +248,7 @@ module Sys
222
248
  array = block_given? ? nil : []
223
249
 
224
250
  pids.each do |lpid|
225
- next unless pid == lpid if pid
251
+ next if pid && pid != lpid
226
252
  info = ProcTaskAllInfo.new
227
253
 
228
254
  nb = proc_pidinfo(lpid, PROC_PIDTASKALLINFO, 0, info, info.size)
@@ -258,8 +284,6 @@ module Sys
258
284
  end
259
285
  end
260
286
 
261
- private
262
-
263
287
  # Pass by reference method that updates the Ruby struct based on the FFI struct.
264
288
  #
265
289
  def self.apply_info_to_struct(info, struct)
@@ -275,6 +299,8 @@ module Sys
275
299
  end
276
300
  end
277
301
 
302
+ private_class_method :apply_info_to_struct
303
+
278
304
  # Returns an array of ThreadInfo objects for the given pid.
279
305
  #
280
306
  def self.get_thread_info(pid, struct, ptinfo)
@@ -292,7 +318,7 @@ module Sys
292
318
  max = ptinfo[:pti_threadnum]
293
319
  struct[:threadinfo] = []
294
320
 
295
- 0.upto(max-1) do |index|
321
+ 0.upto(max - 1) do |index|
296
322
  tinfo = ProcThreadInfo.new
297
323
 
298
324
  # Use read_array_of_uint64 for compatibility with JRuby if necessary.
@@ -304,7 +330,7 @@ module Sys
304
330
 
305
331
  if nb <= 0
306
332
  if [Errno::EPERM::Errno, Errno::ESRCH::Errno].include?(FFI.errno)
307
- return # Either we don't have permission, or the pid no longer exists
333
+ next # Either we don't have permission, or the pid no longer exists
308
334
  else
309
335
  raise SystemCallError.new('proc_pidinfo', FFI.errno)
310
336
  end
@@ -321,15 +347,21 @@ module Sys
321
347
  tinfo[:pth_curpri],
322
348
  tinfo[:pth_priority],
323
349
  tinfo[:pth_maxpriority],
324
- tinfo[:pth_name].to_s,
350
+ tinfo[:pth_name].to_s
325
351
  )
326
352
 
327
353
  struct[:threadinfo] << tinfo_struct
328
354
  end
329
355
  end
330
356
 
357
+ private_class_method :get_thread_info
358
+
331
359
  # Get the command line arguments, as well as the environment settings,
332
360
  # for the given PID.
361
+ #--
362
+ # Note that on Big Sur and later it seems that you cannot get environment
363
+ # variable information on spawned processes except in certain circumstances,
364
+ # e.g. SIP has been disabled, the kernel is in debug mode, etc.
333
365
  #
334
366
  def self.get_cmd_args_and_env(pid, struct)
335
367
  len = FFI::MemoryPointer.new(:size_t)
@@ -389,22 +421,23 @@ module Sys
389
421
 
390
422
  # Extract the full command line and its arguments from the array
391
423
  argc.times do
392
- cmdline << ' ' + array.shift
424
+ cmdline << ' ' << array.shift
393
425
  end
394
426
 
395
427
  struct[:cmdline] = cmdline.strip
396
428
 
397
429
  # Anything remaining at this point is a collection of key=value
398
430
  # pairs which we convert into a hash.
399
- environ = array.inject({}) do |hash, string|
431
+ environ = array.each_with_object({}) do |string, hash|
400
432
  if string && string.include?('=')
401
433
  key, value = string.split('=')
402
434
  hash[key] = value
403
435
  end
404
- hash
405
436
  end
406
437
 
407
438
  struct[:environ] = environ
408
439
  end
440
+
441
+ private_class_method :get_cmd_args_and_env
409
442
  end
410
443
  end