sys-proctable 1.2.6 → 1.2.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/{CHANGES.rdoc → CHANGES.md} +64 -49
- data/Gemfile +2 -0
- data/{MANIFEST.rdoc → MANIFEST.md} +1 -0
- data/README.md +8 -3
- data/Rakefile +7 -4
- data/certs/djberg96_pub.pem +26 -0
- data/lib/darwin/sys/proctable.rb +53 -20
- data/lib/freebsd/sys/proctable.rb +1 -1
- data/lib/linux/sys/proctable/cgroup_entry.rb +4 -2
- data/lib/linux/sys/proctable/smaps.rb +29 -17
- data/lib/linux/sys/proctable.rb +41 -35
- data/lib/sunos/sys/proctable.rb +2 -2
- data/lib/sys/proctable/version.rb +1 -1
- data/lib/sys/top.rb +1 -1
- data/lib/windows/sys/proctable.rb +36 -32
- data/spec/spec_helper.rb +13 -0
- data/spec/sys_proctable_aix_spec.rb +74 -76
- data/spec/sys_proctable_all_spec.rb +45 -45
- data/spec/sys_proctable_darwin_spec.rb +85 -58
- data/spec/sys_proctable_freebsd_spec.rb +111 -113
- data/spec/sys_proctable_linux_spec.rb +196 -195
- data/spec/sys_proctable_sunos_spec.rb +190 -192
- data/spec/sys_proctable_windows_spec.rb +153 -153
- data/spec/sys_top_spec.rb +20 -21
- data/sys-proctable.gemspec +15 -24
- data.tar.gz.sig +0 -0
- metadata +54 -16
- metadata.gz.sig +0 -0
data/lib/darwin/sys/proctable.rb
CHANGED
@@ -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
|
108
|
-
|
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
|
-
|
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, [
|
121
|
-
attach_function :proc_pidinfo, [
|
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, [
|
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
|
-
|
140
|
-
|
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
|
-
|
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
|
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
|
-
|
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 << ' '
|
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.
|
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
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sys
|
2
4
|
class ProcTable
|
3
5
|
# This represents a cgroup entry
|
@@ -20,7 +22,7 @@ module Sys
|
|
20
22
|
def initialize(string)
|
21
23
|
@string = string.chomp
|
22
24
|
@fields = @string.split(/:/)
|
23
|
-
rescue
|
25
|
+
rescue StandardError
|
24
26
|
@fields = []
|
25
27
|
end
|
26
28
|
|
@@ -32,7 +34,7 @@ module Sys
|
|
32
34
|
# Return sets of subsystems bound to the hierarchy
|
33
35
|
def subsystems
|
34
36
|
@fields[1].split(/,/)
|
35
|
-
rescue
|
37
|
+
rescue StandardError
|
36
38
|
[]
|
37
39
|
end
|
38
40
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Sys
|
2
4
|
class ProcTable
|
3
5
|
# Smaps represents a process' memory size for all mapped files
|
@@ -25,7 +27,18 @@ module Sys
|
|
25
27
|
# Example:
|
26
28
|
#
|
27
29
|
# smaps = Smaps.new(123, IO.read("/proc/1234/smaps")
|
28
|
-
#
|
30
|
+
#
|
31
|
+
# # result
|
32
|
+
#
|
33
|
+
# #<Sys::ProcTable::Smaps:0x007f8ac5930768
|
34
|
+
# @pid=123,
|
35
|
+
# @pss=107000,
|
36
|
+
# @rss=368000,
|
37
|
+
# @uss=96000,
|
38
|
+
# @swap=192000,
|
39
|
+
# @vss=136752000
|
40
|
+
# >
|
41
|
+
#
|
29
42
|
# smaps.pss # => 109568
|
30
43
|
# smaps.rss # => 376832
|
31
44
|
# smaps.uss # => 98304
|
@@ -33,7 +46,6 @@ module Sys
|
|
33
46
|
# smaps.vss # => 140034048
|
34
47
|
#
|
35
48
|
class Smaps
|
36
|
-
|
37
49
|
# Process ID for this smaps
|
38
50
|
attr_reader :pid
|
39
51
|
|
@@ -51,19 +63,19 @@ module Sys
|
|
51
63
|
# 4k + (4k / 2) + (3k / 3) = 7k
|
52
64
|
#
|
53
65
|
attr_reader :pss
|
54
|
-
|
66
|
+
alias proportional_set_size pss
|
55
67
|
|
56
68
|
# Resident set size
|
57
69
|
#
|
58
70
|
# RSS is the total size of all pages, shared or not, mapped to a process.
|
59
71
|
attr_reader :rss
|
60
|
-
|
72
|
+
alias resident_set_size rss
|
61
73
|
|
62
74
|
# Unique set size
|
63
75
|
#
|
64
76
|
# USS is the total size of all private pages mapped to a process.
|
65
77
|
attr_reader :uss
|
66
|
-
|
78
|
+
alias unique_set_size uss
|
67
79
|
|
68
80
|
# Swap
|
69
81
|
#
|
@@ -76,7 +88,7 @@ module Sys
|
|
76
88
|
# lazily loaded, this value represents the total size of all mapped files
|
77
89
|
# if they were all loaded.
|
78
90
|
attr_reader :vss
|
79
|
-
|
91
|
+
alias virtual_set_size vss
|
80
92
|
|
81
93
|
# Create a new smaps object
|
82
94
|
#
|
@@ -95,22 +107,22 @@ module Sys
|
|
95
107
|
smaps_contents.each_line { |line| parse_smaps_line(line) }
|
96
108
|
end
|
97
109
|
|
98
|
-
|
110
|
+
alias to_s inspect
|
99
111
|
|
100
112
|
private
|
101
113
|
|
102
114
|
def parse_smaps_line(line)
|
103
115
|
case line
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
116
|
+
when /^Pss:\s+?(\d+)/
|
117
|
+
@pss += Regexp.last_match[1].to_i * 1000
|
118
|
+
when /^Rss:\s+?(\d+)/
|
119
|
+
@rss += Regexp.last_match[1].to_i * 1000
|
120
|
+
when /^Size:\s+?(\d+)/
|
121
|
+
@vss += Regexp.last_match[1].to_i * 1000
|
122
|
+
when /^Swap:\s+?(\d+)/
|
123
|
+
@swap += Regexp.last_match[1].to_i * 1000
|
124
|
+
when /^Private_(Clean|Dirty):\s+?(\d+)/
|
125
|
+
@uss += Regexp.last_match[2].to_i * 1000
|
114
126
|
end
|
115
127
|
end
|
116
128
|
end
|
data/lib/linux/sys/proctable.rb
CHANGED
@@ -1,23 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'sys/proctable/version'
|
2
4
|
require_relative 'proctable/cgroup_entry'
|
3
5
|
require_relative 'proctable/smaps'
|
4
6
|
|
5
7
|
# The Sys module serves as a namespace only.
|
6
8
|
module Sys
|
7
|
-
|
8
9
|
# The ProcTable class encapsulates process table information.
|
9
10
|
class ProcTable
|
10
|
-
|
11
11
|
# Error typically raised if the ProcTable.ps method fails.
|
12
12
|
class Error < StandardError; end
|
13
13
|
|
14
14
|
# There is no constructor
|
15
15
|
private_class_method :new
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
@mem_total = IO.read("/proc/meminfo")[/MemTotal.*/].split[1].to_i * 1024 rescue nil
|
20
|
-
@boot_time = IO.read("/proc/stat")[/btime.*/].split.last.to_i rescue nil
|
17
|
+
@mem_total = File.read("/proc/meminfo")[/MemTotal.*/].split[1].to_i * 1024 rescue nil
|
18
|
+
@boot_time = File.read("/proc/stat")[/btime.*/].split.last.to_i rescue nil
|
21
19
|
|
22
20
|
@fields = [
|
23
21
|
'cmdline', # Complete command line
|
@@ -83,10 +81,10 @@ module Sys
|
|
83
81
|
'smaps' # Process memory size for all mapped files
|
84
82
|
]
|
85
83
|
|
86
|
-
public
|
87
|
-
|
88
84
|
ProcTableStruct = Struct.new('ProcTableStruct', *@fields)
|
89
85
|
|
86
|
+
private_constant :ProcTableStruct
|
87
|
+
|
90
88
|
# In block form, yields a ProcTableStruct for each process entry that you
|
91
89
|
# have rights to. This method returns an array of ProcTableStruct's in
|
92
90
|
# non-block form.
|
@@ -121,19 +119,19 @@ module Sys
|
|
121
119
|
array = block_given? ? nil : []
|
122
120
|
struct = nil
|
123
121
|
|
124
|
-
raise TypeError
|
122
|
+
raise TypeError if pid && !pid.is_a?(Numeric)
|
125
123
|
|
126
|
-
Dir.foreach("/proc")
|
124
|
+
Dir.foreach("/proc") do |file|
|
127
125
|
next if file =~ /\D/ # Skip non-numeric directories
|
128
|
-
next
|
126
|
+
next if pid && file.to_i != pid
|
129
127
|
|
130
128
|
struct = ProcTableStruct.new
|
131
129
|
|
132
130
|
# Get /proc/<pid>/cmdline information. Strip out embedded nulls.
|
133
131
|
begin
|
134
|
-
data =
|
132
|
+
data = File.read("/proc/#{file}/cmdline").tr("\000", ' ').strip
|
135
133
|
struct.cmdline = data
|
136
|
-
rescue
|
134
|
+
rescue StandardError
|
137
135
|
next # Process terminated, on to the next process
|
138
136
|
end
|
139
137
|
|
@@ -146,10 +144,10 @@ module Sys
|
|
146
144
|
struct.environ = {}
|
147
145
|
|
148
146
|
begin
|
149
|
-
|
147
|
+
File.read("/proc/#{file}/environ").force_encoding("UTF-8").split("\0").each do |str|
|
150
148
|
key, value = str.split('=')
|
151
149
|
struct.environ[key] = value
|
152
|
-
|
150
|
+
end
|
153
151
|
rescue Errno::EACCES, Errno::ESRCH, Errno::ENOENT
|
154
152
|
# Ignore and move on.
|
155
153
|
end
|
@@ -166,7 +164,7 @@ module Sys
|
|
166
164
|
Dir["/proc/#{file}/fd/*"].each do |fd|
|
167
165
|
struct.fd[File.basename(fd)] = File.readlink(fd) rescue nil
|
168
166
|
end
|
169
|
-
rescue
|
167
|
+
rescue StandardError
|
170
168
|
# Ignore and move on
|
171
169
|
end
|
172
170
|
|
@@ -174,7 +172,7 @@ module Sys
|
|
174
172
|
struct.root = File.readlink("/proc/#{file}/root") rescue nil
|
175
173
|
|
176
174
|
# Get /proc/<pid>/stat information
|
177
|
-
stat =
|
175
|
+
stat = File.read("/proc/#{file}/stat") rescue next
|
178
176
|
|
179
177
|
# Get number of LWP, one directory for each in /proc/<pid>/task/
|
180
178
|
# Every process has at least one thread, so if we fail to read the task directory, set nlwp to 1.
|
@@ -182,7 +180,7 @@ module Sys
|
|
182
180
|
|
183
181
|
# Get control groups to which the process belongs
|
184
182
|
unless cgroup == false
|
185
|
-
struct.cgroup =
|
183
|
+
struct.cgroup = File.readlines("/proc/#{file}/cgroup").map { |l| CgroupEntry.new(l) } rescue []
|
186
184
|
end
|
187
185
|
|
188
186
|
# Read smaps, returning a parsable string if we don't have permissions.
|
@@ -190,12 +188,18 @@ module Sys
|
|
190
188
|
# are true for a file in the /proc fileystem but raises a Errno:EACCESS
|
191
189
|
# when your try to read it without permissions.
|
192
190
|
unless smaps == false
|
193
|
-
smaps_contents =
|
191
|
+
smaps_contents = File.read("/proc/#{file}/smaps") rescue ""
|
194
192
|
struct.smaps = Smaps.new(file, smaps_contents)
|
195
193
|
end
|
196
194
|
|
197
|
-
# Deal with spaces in comm name.
|
198
|
-
|
195
|
+
# Deal with spaces in comm name. This isn't supposed to happen, but in
|
196
|
+
# rare cases - the original offending case was "(xzen thread)" - it can
|
197
|
+
# occur. So we parse it out, replace the spaces with hyphens, and
|
198
|
+
# re-insert it into the stat string so that it splits properly later on.
|
199
|
+
#
|
200
|
+
# Courtesy of Ara Howard.
|
201
|
+
#
|
202
|
+
re = /\([^)]+\)/
|
199
203
|
comm = stat[re]
|
200
204
|
comm.tr!(' ', '-')
|
201
205
|
stat[re] = comm
|
@@ -203,7 +207,7 @@ module Sys
|
|
203
207
|
stat = stat.split
|
204
208
|
|
205
209
|
struct.pid = stat[0].to_i
|
206
|
-
struct.comm = stat[1].tr('()','') # Remove parens
|
210
|
+
struct.comm = stat[1].tr('()', '') # Remove parens
|
207
211
|
struct.state = stat[2]
|
208
212
|
struct.ppid = stat[3].to_i
|
209
213
|
struct.pgrp = stat[4].to_i
|
@@ -250,16 +254,16 @@ module Sys
|
|
250
254
|
|
251
255
|
# Get /proc/<pid>/status information (name, uid, euid, gid, egid)
|
252
256
|
begin
|
253
|
-
|
257
|
+
File.foreach("/proc/#{file}/status") do |line|
|
254
258
|
case line
|
255
259
|
when /Name:\s*?(\w+)/
|
256
|
-
struct.name =
|
260
|
+
struct.name = Regexp.last_match(1)
|
257
261
|
when /Uid:\s*?(\d+)\s*?(\d+)/
|
258
|
-
struct.uid =
|
259
|
-
struct.euid =
|
262
|
+
struct.uid = Regexp.last_match(1).to_i
|
263
|
+
struct.euid = Regexp.last_match(2).to_i
|
260
264
|
when /Gid:\s*?(\d+)\s*?(\d+)/
|
261
|
-
struct.gid =
|
262
|
-
struct.egid =
|
265
|
+
struct.gid = Regexp.last_match(1).to_i
|
266
|
+
struct.egid = Regexp.last_match(2).to_i
|
263
267
|
end
|
264
268
|
end
|
265
269
|
rescue Errno::ESRCH, Errno::ENOENT
|
@@ -280,7 +284,7 @@ module Sys
|
|
280
284
|
else
|
281
285
|
array << struct
|
282
286
|
end
|
283
|
-
|
287
|
+
end
|
284
288
|
|
285
289
|
pid ? struct : array
|
286
290
|
end
|
@@ -295,21 +299,21 @@ module Sys
|
|
295
299
|
# puts "Field: #{field}"
|
296
300
|
# }
|
297
301
|
#
|
298
|
-
|
299
|
-
|
302
|
+
class << self
|
303
|
+
attr_reader :fields
|
300
304
|
end
|
301
305
|
|
302
|
-
private
|
303
|
-
|
304
306
|
# Calculate the percentage of memory usage for the given process.
|
305
307
|
#
|
306
308
|
def self.get_pctmem(rss)
|
307
309
|
return nil unless @mem_total
|
308
310
|
page_size = 4096
|
309
311
|
rss_total = rss * page_size
|
310
|
-
|
312
|
+
format("%3.2f", (rss_total.to_f / @mem_total) * 100).to_f
|
311
313
|
end
|
312
314
|
|
315
|
+
private_class_method :get_pctmem
|
316
|
+
|
313
317
|
# Calculate the percentage of CPU usage for the given process.
|
314
318
|
#
|
315
319
|
def self.get_pctcpu(utime, start_time)
|
@@ -317,7 +321,9 @@ module Sys
|
|
317
321
|
hertz = 100.0
|
318
322
|
utime = (utime * 10000).to_f
|
319
323
|
stime = (start_time.to_f / hertz) + @boot_time
|
320
|
-
|
324
|
+
format("%3.2f", (utime / 10000.0) / (Time.now.to_i - stime)).to_f
|
321
325
|
end
|
326
|
+
|
327
|
+
private_class_method :get_pctcpu
|
322
328
|
end
|
323
329
|
end
|
data/lib/sunos/sys/proctable.rb
CHANGED
@@ -110,7 +110,7 @@ module Sys
|
|
110
110
|
:pr_slptime, Timeval,
|
111
111
|
:pr_wtime, Timeval,
|
112
112
|
:pr_stoptime, Timeval,
|
113
|
-
:pr_filetime, [Timeval,6],
|
113
|
+
:pr_filetime, [Timeval, 6],
|
114
114
|
:pr_minf, :ulong_t,
|
115
115
|
:pr_majf, :ulong_t,
|
116
116
|
:pr_nswap, :ulong_t,
|
@@ -343,7 +343,7 @@ module Sys
|
|
343
343
|
env_address += data.length + 1 # Add 1 for the space
|
344
344
|
end
|
345
345
|
end
|
346
|
-
rescue Errno::EACCES, Errno::EOVERFLOW, EOFError, RangeError
|
346
|
+
rescue Errno::EACCES, Errno::EBADF, Errno::EOVERFLOW, EOFError, RangeError
|
347
347
|
# Skip this if we don't have proper permissions, if there's
|
348
348
|
# no associated environment, or if there's a largefile issue.
|
349
349
|
rescue Errno::ENOENT
|
data/lib/sys/top.rb
CHANGED
@@ -15,7 +15,7 @@ module Sys
|
|
15
15
|
#
|
16
16
|
# Exception: the default sort field is 'pid' on AIX, Darwin and Windows.
|
17
17
|
#
|
18
|
-
def self.top(num=10, field='pctcpu')
|
18
|
+
def self.top(num = 10, field = 'pctcpu')
|
19
19
|
field = field.to_s if field.is_a?(Symbol)
|
20
20
|
|
21
21
|
aix = RbConfig::CONFIG['host_os'] =~ /aix/i
|