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.
@@ -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
- # JRuby on Mac
37
+ private_constant :MAXTHREADNAMESIZE
38
+ private_constant :PROC_PIDPATHINFO_MAXSIZE
39
+
40
+ # JRuby/Truffleruby on Mac
30
41
  unless defined? FFI::StructLayout::CharArray
31
- FFI::StructLayout::CharArray = FFI::StructLayout::CharArrayProxy
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 = ProcBsdInfo.members + ProcTaskInfo.members + ProcThreadInfo.members
104
- 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|
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
- }.to_h
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, [:pointer, :int], :int
117
- 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
118
142
 
119
143
  ffi_lib FFI::Library::LIBC
120
144
 
121
- 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
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
- alias vsize virtual_size
136
- alias rss resident_size
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
- public
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 unless pid == lpid if pid
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
- 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
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 << ' ' + array.shift
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.inject({}) do |hash, string|
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
@@ -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
 
@@ -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
- # => #<Sys::ProcTable::Smaps:0x007f8ac5930768 @pid=123, @pss=107000, @rss=368000, @uss=96000, @swap=192000, @vss=136752000>
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
- alias_method :proportional_set_size, :pss
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
- alias_method :resident_set_size, :rss
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
- alias_method :unique_set_size, :uss
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
- alias_method :virtual_set_size, :vss
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
- alias_method :to_s, :inspect
110
+ alias to_s inspect
99
111
 
100
112
  private
101
113
 
102
114
  def parse_smaps_line(line)
103
115
  case line
104
- when /^Pss:\s+?(\d+)/
105
- @pss += Regexp.last_match[1].to_i * 1000
106
- when /^Rss:\s+?(\d+)/
107
- @rss += Regexp.last_match[1].to_i * 1000
108
- when /^Size:\s+?(\d+)/
109
- @vss += Regexp.last_match[1].to_i * 1000
110
- when /^Swap:\s+?(\d+)/
111
- @swap += Regexp.last_match[1].to_i * 1000
112
- when /^Private_(Clean|Dirty):\s+?(\d+)/
113
- @uss += Regexp.last_match[2].to_i * 1000
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
@@ -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
- private
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 unless pid.is_a?(Numeric) if pid
122
+ raise TypeError if pid && !pid.is_a?(Numeric)
125
123
 
126
- Dir.foreach("/proc"){ |file|
124
+ Dir.foreach("/proc") do |file|
127
125
  next if file =~ /\D/ # Skip non-numeric directories
128
- next unless file.to_i == pid if pid
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 = IO.read("/proc/#{file}/cmdline").tr("\000", ' ').strip
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
- IO.read("/proc/#{file}/environ").split("\0").each{ |str|
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 = IO.read("/proc/#{file}/stat") rescue next
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 = IO.readlines("/proc/#{file}/cgroup").map { |l| CgroupEntry.new(l) } rescue []
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 = IO.read("/proc/#{file}/smaps") rescue ""
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. Courtesy of Ara Howard.
198
- re = %r/\([^\)]+\)/
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
- IO.foreach("/proc/#{file}/status") do |line|
257
+ File.foreach("/proc/#{file}/status") do |line|
254
258
  case line
255
259
  when /Name:\s*?(\w+)/
256
- struct.name = $1
260
+ struct.name = Regexp.last_match(1)
257
261
  when /Uid:\s*?(\d+)\s*?(\d+)/
258
- struct.uid = $1.to_i
259
- struct.euid = $2.to_i
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 = $1.to_i
262
- struct.egid = $2.to_i
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
- def self.fields
299
- @fields
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
- sprintf("%3.2f", (rss_total.to_f / @mem_total) * 100).to_f
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
- sprintf("%3.2f", (utime / 10000.0) / (Time.now.to_i - stime)).to_f
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
@@ -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
@@ -1,6 +1,6 @@
1
1
  module Sys
2
2
  class ProcTable
3
3
  # The version of the sys-proctable library
4
- VERSION = '1.2.5'.freeze
4
+ VERSION = '1.2.7'.freeze
5
5
  end
6
6
  end
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