sys-proctable 1.2.5 → 1.2.7
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/{CHANGES.rdoc → CHANGES.md} +72 -48
- data/Gemfile +2 -0
- data/{MANIFEST.rdoc → MANIFEST.md} +11 -8
- data/README.md +8 -3
- data/Rakefile +7 -4
- data/certs/djberg96_pub.pem +26 -0
- data/lib/darwin/sys/proctable.rb +59 -22
- 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 +11 -20
- 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 +87 -60
- 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 +56 -19
- metadata.gz.sig +0 -0
data/lib/darwin/sys/proctable.rb
CHANGED
@@ -11,24 +11,39 @@ 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
|
|
29
|
-
|
37
|
+
private_constant :MAXTHREADNAMESIZE
|
38
|
+
private_constant :PROC_PIDPATHINFO_MAXSIZE
|
39
|
+
|
40
|
+
# JRuby/Truffleruby on Mac
|
30
41
|
unless defined? FFI::StructLayout::CharArray
|
31
|
-
|
42
|
+
if defined? FFI::StructLayout::CharArrayProxy
|
43
|
+
FFI::StructLayout::CharArray = FFI::StructLayout::CharArrayProxy
|
44
|
+
else
|
45
|
+
FFI::StructLayout::CharArray = FFI::Struct::CharArray
|
46
|
+
end
|
32
47
|
end
|
33
48
|
|
34
49
|
class ProcBsdInfo < FFI::Struct
|
@@ -58,6 +73,8 @@ module Sys
|
|
58
73
|
)
|
59
74
|
end
|
60
75
|
|
76
|
+
private_constant :ProcBsdInfo
|
77
|
+
|
61
78
|
class ProcTaskInfo < FFI::Struct
|
62
79
|
layout(
|
63
80
|
:pti_virtual_size, :uint64_t,
|
@@ -81,6 +98,8 @@ module Sys
|
|
81
98
|
)
|
82
99
|
end
|
83
100
|
|
101
|
+
private_constant :ProcTaskInfo
|
102
|
+
|
84
103
|
class ProcThreadInfo < FFI::Struct
|
85
104
|
layout(
|
86
105
|
:pth_user_time, :uint64_t,
|
@@ -97,28 +116,37 @@ module Sys
|
|
97
116
|
)
|
98
117
|
end
|
99
118
|
|
119
|
+
private_constant :ProcThreadInfo
|
120
|
+
|
100
121
|
# Map the fields from the FFI::Structs to the Sys::ProcTable struct on
|
101
122
|
# class load to reduce the amount of objects needing to be generated for
|
102
123
|
# each invocation of Sys::ProcTable.ps
|
103
|
-
all_members
|
104
|
-
|
124
|
+
all_members = ProcBsdInfo.members + ProcTaskInfo.members + ProcThreadInfo.members
|
125
|
+
|
126
|
+
PROC_STRUCT_FIELD_MAP = all_members.map do |member|
|
105
127
|
temp = member.to_s.split('_')
|
106
128
|
sproperty = temp.size > 1 ? temp[1..-1].join('_') : temp.first
|
107
129
|
[member, sproperty.to_sym]
|
108
|
-
|
130
|
+
end.to_h
|
109
131
|
|
110
132
|
class ProcTaskAllInfo < FFI::Struct
|
111
133
|
layout(:pbsd, ProcBsdInfo, :ptinfo, ProcTaskInfo)
|
112
134
|
end
|
113
135
|
|
136
|
+
private_constant :ProcTaskAllInfo
|
137
|
+
|
114
138
|
ffi_lib 'proc'
|
115
139
|
|
116
|
-
attach_function :proc_listallpids, [
|
117
|
-
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
|
118
142
|
|
119
143
|
ffi_lib FFI::Library::LIBC
|
120
144
|
|
121
|
-
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
|
122
150
|
|
123
151
|
# These mostly mimic the struct members, but we've added a few custom ones as well.
|
124
152
|
@fields = %w[
|
@@ -132,16 +160,18 @@ module Sys
|
|
132
160
|
|
133
161
|
# Add a couple aliases to make it similar to Linux
|
134
162
|
ProcTableStruct = Struct.new("ProcTableStruct", *@fields) do
|
135
|
-
|
136
|
-
|
163
|
+
alias_method :vsize, :virtual_size
|
164
|
+
alias_method :rss, :resident_size
|
137
165
|
end
|
138
166
|
|
167
|
+
private_constant :ProcTableStruct
|
168
|
+
|
139
169
|
ThreadInfoStruct = Struct.new("ThreadInfo", :user_time, :system_time,
|
140
170
|
:cpu_usage, :policy, :run_state, :flags, :sleep_time, :curpri,
|
141
171
|
:priority, :maxpriority, :name
|
142
172
|
)
|
143
173
|
|
144
|
-
|
174
|
+
private_constant :ThreadInfoStruct
|
145
175
|
|
146
176
|
# Returns an array of fields that each ProcTableStruct will contain. This
|
147
177
|
# may be useful if you want to know in advance what fields are available
|
@@ -218,7 +248,7 @@ module Sys
|
|
218
248
|
array = block_given? ? nil : []
|
219
249
|
|
220
250
|
pids.each do |lpid|
|
221
|
-
next
|
251
|
+
next if pid && pid != lpid
|
222
252
|
info = ProcTaskAllInfo.new
|
223
253
|
|
224
254
|
nb = proc_pidinfo(lpid, PROC_PIDTASKALLINFO, 0, info, info.size)
|
@@ -254,8 +284,6 @@ module Sys
|
|
254
284
|
end
|
255
285
|
end
|
256
286
|
|
257
|
-
private
|
258
|
-
|
259
287
|
# Pass by reference method that updates the Ruby struct based on the FFI struct.
|
260
288
|
#
|
261
289
|
def self.apply_info_to_struct(info, struct)
|
@@ -271,6 +299,8 @@ module Sys
|
|
271
299
|
end
|
272
300
|
end
|
273
301
|
|
302
|
+
private_class_method :apply_info_to_struct
|
303
|
+
|
274
304
|
# Returns an array of ThreadInfo objects for the given pid.
|
275
305
|
#
|
276
306
|
def self.get_thread_info(pid, struct, ptinfo)
|
@@ -288,7 +318,7 @@ module Sys
|
|
288
318
|
max = ptinfo[:pti_threadnum]
|
289
319
|
struct[:threadinfo] = []
|
290
320
|
|
291
|
-
0.upto(max-1) do |index|
|
321
|
+
0.upto(max - 1) do |index|
|
292
322
|
tinfo = ProcThreadInfo.new
|
293
323
|
|
294
324
|
# Use read_array_of_uint64 for compatibility with JRuby if necessary.
|
@@ -300,7 +330,7 @@ module Sys
|
|
300
330
|
|
301
331
|
if nb <= 0
|
302
332
|
if [Errno::EPERM::Errno, Errno::ESRCH::Errno].include?(FFI.errno)
|
303
|
-
|
333
|
+
next # Either we don't have permission, or the pid no longer exists
|
304
334
|
else
|
305
335
|
raise SystemCallError.new('proc_pidinfo', FFI.errno)
|
306
336
|
end
|
@@ -317,15 +347,21 @@ module Sys
|
|
317
347
|
tinfo[:pth_curpri],
|
318
348
|
tinfo[:pth_priority],
|
319
349
|
tinfo[:pth_maxpriority],
|
320
|
-
tinfo[:pth_name].to_s
|
350
|
+
tinfo[:pth_name].to_s
|
321
351
|
)
|
322
352
|
|
323
353
|
struct[:threadinfo] << tinfo_struct
|
324
354
|
end
|
325
355
|
end
|
326
356
|
|
357
|
+
private_class_method :get_thread_info
|
358
|
+
|
327
359
|
# Get the command line arguments, as well as the environment settings,
|
328
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.
|
329
365
|
#
|
330
366
|
def self.get_cmd_args_and_env(pid, struct)
|
331
367
|
len = FFI::MemoryPointer.new(:size_t)
|
@@ -385,22 +421,23 @@ module Sys
|
|
385
421
|
|
386
422
|
# Extract the full command line and its arguments from the array
|
387
423
|
argc.times do
|
388
|
-
cmdline << ' '
|
424
|
+
cmdline << ' ' << array.shift
|
389
425
|
end
|
390
426
|
|
391
427
|
struct[:cmdline] = cmdline.strip
|
392
428
|
|
393
429
|
# Anything remaining at this point is a collection of key=value
|
394
430
|
# pairs which we convert into a hash.
|
395
|
-
environ = array.
|
431
|
+
environ = array.each_with_object({}) do |string, hash|
|
396
432
|
if string && string.include?('=')
|
397
433
|
key, value = string.split('=')
|
398
434
|
hash[key] = value
|
399
435
|
end
|
400
|
-
hash
|
401
436
|
end
|
402
437
|
|
403
438
|
struct[:environ] = environ
|
404
439
|
end
|
440
|
+
|
441
|
+
private_class_method :get_cmd_args_and_env
|
405
442
|
end
|
406
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
|