linux_stat 1.2.2 → 1.5.1

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.
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Mounted device related information of the current system.
3
+
2
4
  module Mounts
3
5
  class << self
4
6
  ##
@@ -209,17 +211,17 @@ module LinuxStat
209
211
 
210
212
  private
211
213
  def mount_readable?
212
- @@mount_readable ||= File.readable?('/proc/mounts')
214
+ @@mount_readable ||= File.readable?('/proc/mounts'.freeze)
213
215
  end
214
216
 
215
217
  def mounts
216
218
  return [] unless mount_readable?
217
- IO.readlines('/proc/mounts').each(&:strip!)
219
+ IO.readlines('/proc/mounts'.freeze).each(&:strip!)
218
220
  end
219
221
 
220
222
  def find_root
221
223
  return [] unless mount_readable?
222
- @@root ||= IO.foreach('/proc/mounts').find { |x| x.split[1] == '/'.freeze }.split
224
+ @@root ||= IO.foreach('/proc/mounts'.freeze).find { |x| x.split[1] == '/'.freeze }.split
223
225
  end
224
226
 
225
227
  def fs_info(dev)
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various Net related information of the current system.
3
+
2
4
  module Net
3
5
  class << self
4
6
  DEV = '/proc/net/dev'.freeze
@@ -86,13 +88,13 @@ module LinuxStat
86
88
 
87
89
  data = IO.readlines(DEV).drop(2)
88
90
  indices = find_index_of_bytes
89
- data.reject! { |x| x.strip.start_with?('lo:') }
91
+ data.reject! { |x| x.strip.start_with?('lo:'.freeze) }
90
92
  r, t = data.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
91
93
 
92
94
  sleep(interval)
93
95
 
94
96
  data2 = IO.readlines(DEV).drop(2)
95
- data2.reject! { |x| x.strip.start_with?('lo:') }
97
+ data2.reject! { |x| x.strip.start_with?('lo:'.freeze) }
96
98
  r2, t2 = data2.map { |x| x.split.values_at(*indices).map(&:to_i) }.transpose.map(&:sum)
97
99
 
98
100
  # Measure the difference
@@ -118,8 +120,8 @@ module LinuxStat
118
120
 
119
121
  r.each_with_index { |x, i|
120
122
  downcased = x.downcase
121
- h.merge!(:r => i) if downcased.start_with?('receive')
122
- h.merge!(:t => i) if downcased.start_with?('transmit')
123
+ h.merge!(:r => i) if downcased.start_with?('receive'.freeze)
124
+ h.merge!(:t => i) if downcased.start_with?('transmit'.freeze)
123
125
  }
124
126
 
125
127
  data_0 = data.next.gsub(?|.freeze, ' %'.freeze)
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various OS related information of the current system.
3
+
2
4
  module OS
3
5
  class << self
4
6
  ##
@@ -52,7 +54,7 @@ module LinuxStat
52
54
  elsif v.key?(:DISTRIB_ID)
53
55
  v[:DISTRIB_ID]
54
56
  elsif File.readable?('/etc/issue'.freeze)
55
- IO.read('/etc/issue'.freeze, encoding: 'ASCII-8bit').strip
57
+ IO.read('/etc/issue'.freeze, encoding: 'ASCII-8bit'.freeze).strip
56
58
  else
57
59
  'Unknown'.freeze
58
60
  end
@@ -156,6 +158,40 @@ module LinuxStat
156
158
  }.freeze
157
159
  end
158
160
 
161
+ ##
162
+ # Returns uptime of the system reported by LinuxStat::Sysinfo.uptime()
163
+ # LinuxStat::OS.uptime_i
164
+ #
165
+ # 28956
166
+ #
167
+ # If the stat isn't available, nil is returned.
168
+ def uptime_i
169
+ LinuxStat::Sysinfo.uptime
170
+ end
171
+
172
+ ##
173
+ # The first three fields in this file are load average
174
+ # figures giving the number of jobs in the run queue (state R)
175
+ # or waiting for disk I/O (state D) averaged over 1, 5,
176
+ # and 15 minutes. They are the same as the load average
177
+ # numbers given by uptime(1) and other programs.
178
+ # https://man7.org/linux/man-pages/man5/procfs.5.html
179
+ #
180
+ # The return type is an Hash containing the values
181
+ # that maps to 1, 5, and 15.
182
+ # This method calls LinuxStat::Sysinfo.loads() directly.
183
+ #
184
+ # However, if the info isn't available, it will return nil as values.
185
+ def loadavg
186
+ loads = LinuxStat::Sysinfo.loads
187
+
188
+ {
189
+ 1 => loads[0],
190
+ 5 => loads[1],
191
+ 15 => loads[2]
192
+ }
193
+ end
194
+
159
195
  alias distrib_version version
160
196
 
161
197
  private
@@ -1,4 +1,6 @@
1
1
  module LinuxStat
2
+ # Shows various PCI device related information of the current system.
3
+
2
4
  module PCI
3
5
  class << self
4
6
  ##
@@ -1,4 +1,11 @@
1
1
  module LinuxStat
2
+ # Helps you convert bytes to a unit like:
3
+ #
4
+ # 1. kilobyte, megabyte, gigabyte, terabyte, petabyte, exabyte, zettabyte, yottabyte
5
+ # 2. kibibyte, mebibyte, gibibyte, tebibyte, pebibyte, exbibyte, zebibyte, yobibyte
6
+ # 3. kB, MB, GB, TB, PB, EB, ZB, YB
7
+ # 4. kiB, MiB, GiB, TiB, PiB, EiB, ZiB, YiB
8
+
2
9
  module PrettifyBytes
3
10
  class << self
4
11
  ##
@@ -16,13 +23,13 @@ module LinuxStat
16
23
  # LinuxStat::PrettifyBytes.convert_decimal(1024 ** 3)
17
24
  #
18
25
  # => "1.07 gigabytes"
19
- def convert_decimal(n)
26
+ def convert_decimal(n, precision: 2)
20
27
  @@d_units ||= %W(#{''} kilo mega giga tera peta exa zetta)
21
28
  .map.with_index { |x, i| [x, 1000.**(i + 1)] }
22
29
  unit = @@d_units.find { |x| n < x[1] } || ['yotta'.freeze, 10 ** 27]
23
30
 
24
31
  converted = n.fdiv(unit[1] / 1000).round(2)
25
- "#{pad_left(converted)} #{unit[0]}byte#{?s.freeze if converted != 1}"
32
+ "#{pad_left(converted, precision)} #{unit[0]}byte#{?s.freeze if converted != 1}"
26
33
  end
27
34
 
28
35
  # Converts a number to binary byte units and outputs with the IEC prefix
@@ -39,13 +46,13 @@ module LinuxStat
39
46
  # LinuxStat::PrettifyBytes.convert_binary(1024 ** 3)
40
47
  #
41
48
  # => "1.0 gibibyte"
42
- def convert_binary(n)
49
+ def convert_binary(n, precision: 2)
43
50
  @@b_units ||= %W(#{''} kibi mebi gibi tebi pebi exbi zebi)
44
51
  .map.with_index { |x, i| [x, 1024.**(i + 1)] }
45
52
  unit = @@b_units.find { |x| n < x[1] } || ['yobi'.freeze, 10 ** 27]
46
53
 
47
54
  converted = n.fdiv(unit[1] / 1024).round(2)
48
- "#{pad_left(converted)} #{unit[0]}byte#{?s.freeze if converted != 1}"
55
+ "#{pad_left(converted, precision)} #{unit[0]}byte#{?s.freeze if converted != 1}"
49
56
  end
50
57
 
51
58
  # Converts a number to decimal byte units
@@ -62,13 +69,13 @@ module LinuxStat
62
69
  # LinuxStat::PrettifyBytes.convert_short_decimal(1024 ** 3)
63
70
  #
64
71
  # => "1.07 GB"
65
- def convert_short_decimal(n)
72
+ def convert_short_decimal(n, precision: 2)
66
73
  @@sd_units ||= %W(#{''} k M G T P E Z)
67
74
  .map.with_index { |x, i| [x, 1000.**(i + 1)] }
68
75
  unit = @@sd_units.find { |x| n < x[1] } || [?Y.freeze, 10 ** 27]
69
76
 
70
77
  converted = n.fdiv(unit[1] / 1000).round(2)
71
- "#{pad_left(converted)} #{unit[0]}B"
78
+ "#{pad_left(converted, precision)} #{unit[0]}B"
72
79
  end
73
80
 
74
81
  ##
@@ -87,15 +94,15 @@ module LinuxStat
87
94
  # LinuxStat::PrettifyBytes.convert_short_binary(1024 ** 3)
88
95
  #
89
96
  # => "1.0 GiB"
90
- def convert_short_binary(n)
91
- return "#{n} B" if n < 1024
97
+ def convert_short_binary(n, precision: 2)
98
+ return "#{pad_left(n, precision)} B" if n < 1024
92
99
 
93
100
  @@sb_units ||= %W(#{''} K M G T P E Z)
94
101
  .map.with_index { |x, i| [x, 1024.**(i + 1)] }
95
102
  unit = @@sb_units.find { |x| n < x[1] } || [?Y.freeze, 1024 ** 9]
96
103
 
97
104
  converted = n.fdiv(unit[1] / 1024).round(2)
98
- "#{pad_left(converted)} #{unit[0]}iB"
105
+ "#{pad_left(converted, precision)} #{unit[0]}iB"
99
106
  end
100
107
 
101
108
  private
@@ -1,4 +1,7 @@
1
1
  module LinuxStat
2
+ # Shows various information about a process that is either
3
+ # running, sleeping, idle or a zombie.
4
+
2
5
  module Process
3
6
  class << self
4
7
  ##
@@ -6,10 +9,17 @@ module LinuxStat
6
9
  #
7
10
  # The return type is an Array of Integers.
8
11
  def list
9
- Dir['/proc/*'].select { |x|
10
- pid = File.split(x)[1]
11
- pid.to_i.to_s == pid
12
- }.map! { |x| File.split(x)[-1].to_i }
12
+ d = Dir['/proc/*'.freeze]
13
+ ret, i = [], -1
14
+ count = d.length
15
+
16
+ while(i += 1) < count
17
+ pid = File.split(d[i])[1]
18
+ pid_i = pid.to_i
19
+ ret << pid_i if pid_i.to_s == pid
20
+ end
21
+
22
+ ret
13
23
  end
14
24
 
15
25
  ##
@@ -17,39 +27,82 @@ module LinuxStat
17
27
  #
18
28
  # The return type is Integer.
19
29
  def count
20
- list.count
30
+ list.length
21
31
  end
22
32
 
23
33
  ##
24
- # Returns all the id of processes mapped with their names as a Hash.
34
+ # Returns all the id of processes mapped with their executable names (comm) as a Hash.
35
+ # The names can be truncated to TASK_COMM_LEN or (16 - 1 = 15) places.
25
36
  def names
26
- list.reduce({}) { |h, x|
37
+ h, i = {}, -1
38
+
39
+ l = list
40
+ count = l.length
41
+
42
+ while(i += 1) < count
43
+ x = l[i]
44
+
27
45
  begin
28
- h.merge!( x => IO.foreach(File.join('/proc', x.to_s, 'status')).first.split[1] )
29
- rescue Exception
30
- h
46
+ h.merge!( x => IO.read("/proc/#{x}/comm").strip)
47
+ rescue StandardError
31
48
  end
32
- }
49
+ end
50
+ h
51
+ end
52
+
53
+ ##
54
+ # Returns all the id of processes mapped with their cmdline info as a Hash.
55
+ # The cmdlines aren't usually truncated like names, but they can contain
56
+ # arguments with the command.
57
+ def cmdlines
58
+ h, i = {}, -1
59
+
60
+ l = list
61
+ count = l.length
62
+
63
+ while(i += 1) < count
64
+ x = l[i]
65
+
66
+ begin
67
+ cmdlines = IO.read("/proc/#{x}/cmdline").strip
68
+ cmdlines.gsub!(?\u0000.freeze, ?\s.freeze)
69
+ h.merge!( x => cmdlines)
70
+ rescue StandardError
71
+ end
72
+ end
73
+ h
33
74
  end
34
75
 
35
76
  ##
36
77
  # Returns all the id of processes mapped with their status as a Hash.
37
78
  def types
38
- list.reduce({}) { |h, x|
79
+ h, i = {}, -1
80
+
81
+ l = list
82
+ count = l.length
83
+
84
+ while(i += 1) < count
85
+ x = l[i]
86
+
39
87
  begin
40
88
  h.merge!(x =>
41
- case IO.read(File.join('/proc', x.to_s, 'stat')).split[2]
89
+ case IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip
42
90
  when ?S.freeze then :sleeping
43
91
  when ?I.freeze then :idle
44
92
  when ?Z.freeze then :zombie
45
93
  when ?R.freeze then :running
94
+ when ?T.freeze then :stopped
95
+ when ?X.freeze then :dead
96
+ when ?D.freeze then :sleeping
97
+ when ?t.freeze then :stopped
46
98
  else :unknown
47
99
  end
48
100
  )
49
- rescue Exception
50
- h
101
+ rescue StandardError
51
102
  end
52
- }
103
+ end
104
+
105
+ h
53
106
  end
54
107
 
55
108
  ##
@@ -58,9 +111,9 @@ module LinuxStat
58
111
  def sleeping
59
112
  list.select { |x|
60
113
  begin
61
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?S
62
- rescue Exception
63
- nil
114
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?S.freeze
115
+ rescue StandardError
116
+ false
64
117
  end
65
118
  }
66
119
  end
@@ -71,9 +124,9 @@ module LinuxStat
71
124
  def idle
72
125
  list.select { |x|
73
126
  begin
74
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?I
75
- rescue Exception
76
- nil
127
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?I.freeze
128
+ rescue StandardError
129
+ false
77
130
  end
78
131
  }
79
132
  end
@@ -84,9 +137,9 @@ module LinuxStat
84
137
  def zombie
85
138
  list.select { |x|
86
139
  begin
87
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?Z
88
- rescue Exception
89
- nil
140
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?Z.freeze
141
+ rescue StandardError
142
+ false
90
143
  end
91
144
  }
92
145
  end
@@ -97,9 +150,23 @@ module LinuxStat
97
150
  def running
98
151
  list.select { |x|
99
152
  begin
100
- IO.read(File.join('/proc', x.to_s, 'stat')).split[2] == ?R
101
- rescue Exception
102
- nil
153
+ IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip == ?R.freeze
154
+ rescue StandardError
155
+ false
156
+ end
157
+ }
158
+ end
159
+
160
+ ##
161
+ # Returns all the id of processes that are stopped.
162
+ # The return type is an Array of Integers.
163
+ def stopped
164
+ list.select { |x|
165
+ begin
166
+ v = IO.read("/proc/#{x}/stat").split(/(\(.*\))/)[-1][/\s.+?/].strip
167
+ v == ?T.freeze || v == ?t.freeze
168
+ rescue StandardError
169
+ false
103
170
  end
104
171
  }
105
172
  end
@@ -1,4 +1,11 @@
1
1
  module LinuxStat
2
+ # Shows various information about a process that is either
3
+ # running, sleeping, idle or a zombie.
4
+ # Most methods can take a PID, but some uses polling to calculate
5
+ # something, they can accept options instead of arguments.
6
+ # Consult the documentation on the specific methods
7
+ # for more details on that.
8
+
2
9
  module ProcessInfo
3
10
  class << self
4
11
  ##
@@ -62,6 +69,8 @@ module LinuxStat
62
69
 
63
70
  ##
64
71
  # = command_name(pid = $$)
72
+ # Not to be confused with process_name
73
+ # It just splits the cmdline to show the command name
65
74
  #
66
75
  # Where pid is the process ID.
67
76
  #
@@ -77,12 +86,40 @@ module LinuxStat
77
86
  # If the info isn't available it will return an empty frozen String.
78
87
  def command_name(pid = $$)
79
88
  # Do note that the /proc/ppid/comm may not contain the full name
80
- file = "/proc/#{pid}/cmdline".freeze
81
- return ''.freeze unless File.readable?(file)
89
+ # It's limited by TASK_COMM_LEN (16) characters
90
+ c = cmdline(pid).split[0]
91
+ return ''.freeze unless c
92
+ File.split(c)[-1]
93
+ end
82
94
 
83
- _cmdline = IO.read(file)
84
- _cmdline.gsub!(?\u0000, ?\s)
85
- File.split(_cmdline.tap(&:strip!).split[0])[-1]
95
+ ##
96
+ # = process_name(pid = $$)
97
+ # It shows the filename of the command
98
+ # Sometimes the filename is stripped
99
+ #
100
+ # Where pid is the process ID.
101
+ #
102
+ # By default it is the id of the current process ($$)
103
+ #
104
+ # It retuns the total command name of the process.
105
+ #
106
+ # The output is String. For example:
107
+ # LinuxStat::ProcessInfo.process_name
108
+ #
109
+ # "ruby"
110
+ #
111
+ # If the info isn't available it will return an empty frozen String.
112
+ def process_name(pid = $$)
113
+ file = "/proc/#{pid}/stat".freeze
114
+ return command_name unless File.readable?(file)
115
+
116
+ name = IO.read(file).split(/(\(.*\))/) &.[](1) &.[](1..-2)
117
+
118
+ if name && name.length > 0 && name.length < 15
119
+ name
120
+ else
121
+ command_name
122
+ end
86
123
  end
87
124
 
88
125
  ##
@@ -249,8 +286,11 @@ module LinuxStat
249
286
  ticks = get_ticks
250
287
 
251
288
  return {} unless File.readable?(file)
252
- utime, stime, starttime = IO.read(file)
253
- .split.values_at(13, 14, 21).map(&:to_f)
289
+
290
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
291
+ return {} unless stat
292
+
293
+ utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
254
294
 
255
295
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
256
296
 
@@ -260,9 +300,12 @@ module LinuxStat
260
300
  sleep(sleep)
261
301
 
262
302
  return {} unless File.readable?(file)
263
- stat = IO.read(file).split
264
303
 
265
- utime2, stime2, starttime2 = stat.values_at(13, 14, 21).map(&:to_f)
304
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
305
+ return {} unless stat
306
+
307
+ utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
308
+
266
309
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
267
310
 
268
311
  total_time2 = utime2 + stime2
@@ -273,8 +316,8 @@ module LinuxStat
273
316
 
274
317
  {
275
318
  cpu_usage: cpu_u > 100 ? 100.0 : cpu_u.round(2),
276
- threads: stat[19].to_i,
277
- last_executed_cpu: stat[38].to_i
319
+ threads: stat[17].to_i,
320
+ last_executed_cpu: stat[36].to_i
278
321
  }
279
322
  end
280
323
 
@@ -309,8 +352,11 @@ module LinuxStat
309
352
  ticks = get_ticks
310
353
 
311
354
  return nil unless File.readable?(file)
312
- utime, stime, starttime = IO.read(file)
313
- .split.values_at(13, 14, 21).map(&:to_f)
355
+
356
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
357
+ return nil unless stat
358
+
359
+ utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
314
360
 
315
361
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
316
362
 
@@ -320,9 +366,11 @@ module LinuxStat
320
366
  sleep(sleep)
321
367
 
322
368
  return nil unless File.readable?(file)
323
- utime2, stime2, starttime2 = IO.read(file)
324
- .split.values_at(13, 14, 21).map(&:to_f)
325
369
 
370
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
371
+ return nil unless stat
372
+
373
+ utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
326
374
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
327
375
 
328
376
  total_time2 = utime2 + stime2
@@ -361,8 +409,11 @@ module LinuxStat
361
409
  ticks = get_ticks
362
410
 
363
411
  return nil unless File.readable?(file)
364
- utime, stime, starttime = IO.read(file)
365
- .split.values_at(13, 14, 21).map(&:to_f)
412
+
413
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
414
+ return nil unless stat
415
+
416
+ utime, stime, starttime = *stat.values_at(11, 12, 19).map(&:to_f)
366
417
 
367
418
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
368
419
 
@@ -372,8 +423,11 @@ module LinuxStat
372
423
  sleep(sleep)
373
424
 
374
425
  return nil unless File.readable?(file)
375
- utime2, stime2, starttime2 = IO.read(file)
376
- .split.values_at(13, 14, 21).map(&:to_f)
426
+
427
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
428
+ return nil unless stat
429
+
430
+ utime2, stime2, starttime2 = *stat.values_at(11, 12, 19).map(&:to_f)
377
431
 
378
432
  uptime = IO.read('/proc/uptime'.freeze).to_f * ticks
379
433
 
@@ -409,7 +463,7 @@ module LinuxStat
409
463
  file = "/proc/#{pid}/stat".freeze
410
464
  return nil unless File.readable?(file)
411
465
 
412
- data = IO.foreach(file, ' '.freeze).first(20)[-1]
466
+ data = IO.read(file).split(/(\(.*\))/)[-1] &.split &.at(17)
413
467
  data ? data.to_i : nil
414
468
  end
415
469
 
@@ -434,7 +488,8 @@ module LinuxStat
434
488
  file = "/proc/#{pid}/stat".freeze
435
489
  return nil unless File.readable?(file)
436
490
 
437
- IO.read(file).split[38].to_i
491
+ data = IO.read(file).split(/(\(.*\))/)[-1] &.split &.at(36)
492
+ data ? data.to_i : nil
438
493
  end
439
494
 
440
495
  ##
@@ -517,8 +572,11 @@ module LinuxStat
517
572
  @@u_readable ||= File.readable?(uptime)
518
573
  return nil unless @@u_readable && File.readable?(stat_file)
519
574
 
575
+ stat = IO.read(stat_file).split(/(\(.*\))/)[-1] &.split
576
+ return nil unless stat
577
+
520
578
  u = IO.foreach(uptime, ' '.freeze).next.to_f
521
- st = (IO.foreach(stat_file, ' '.freeze).first(22)[-1].to_f / get_ticks)
579
+ st = stat[19].to_f / get_ticks
522
580
 
523
581
  # Getting two Time objects and dealing with floating point numbers
524
582
  # Just to make sure the time goes monotonically
@@ -567,8 +625,11 @@ module LinuxStat
567
625
  @@u_readable ||= File.readable?(uptime)
568
626
  return nil unless @@u_readable && File.readable?(stat_file)
569
627
 
628
+ stat = IO.read(stat_file).split(/(\(.*\))/)[-1] &.split
629
+ return nil unless stat
630
+
570
631
  IO.foreach(uptime, ' '.freeze).next.to_f
571
- .-(IO.read(stat_file).split[21].to_f / get_ticks).round(2)
632
+ .-(stat[19].to_f / get_ticks).round(2)
572
633
  end
573
634
 
574
635
  ##
@@ -592,7 +653,11 @@ module LinuxStat
592
653
  def state(pid = $$)
593
654
  file = "/proc/#{pid}/stat".freeze
594
655
  return ''.freeze unless File.readable?(file)
595
- IO.foreach(file, ' '.freeze).first(3)[-1].tap(&:rstrip!).freeze
656
+
657
+ stat = IO.read(file).split(/(\(.*\))/)[-1]
658
+ return '' unless stat
659
+
660
+ stat[/\s.+?/].strip
596
661
  end
597
662
 
598
663
  ##
@@ -608,7 +673,10 @@ module LinuxStat
608
673
  file = "/proc/#{pid}/stat"
609
674
  return nil unless File.readable?(file)
610
675
 
611
- IO.foreach(file, ' ').first(19)[-1].to_i
676
+ stat = IO.read(file).split(/(\(.*\))/)[-1] &.split
677
+ return nil unless stat
678
+
679
+ stat[16].to_i
612
680
  end
613
681
 
614
682
  ##