sys-proctable 0.9.3-universal-freebsd → 0.9.4-universal-freebsd
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGES +11 -0
- data/MANIFEST +5 -3
- data/README +8 -9
- data/Rakefile +32 -21
- data/lib/freebsd/sys/proctable.rb +363 -0
- data/lib/sys/top.rb +6 -4
- data/sys-proctable.gemspec +3 -2
- data/test/test_sys_proctable_all.rb +2 -5
- data/test/{test_sys_proctable_bsd.rb → test_sys_proctable_freebsd.rb} +34 -34
- metadata +76 -64
- data/ext/bsd/extconf.rb +0 -14
- data/ext/bsd/sys/proctable.c +0 -301
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1c45e6ae56c6571febf5b2b7038bcc643d3cb337
|
4
|
+
data.tar.gz: f42dd07643ccc87be3ad289b8b0e9d3b2c7252cf
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 06e5a4dfbe1c74ca7fae99ceaad63adf7657fb789298fb7928f776c5684611b82927cca7b3abc4b1671771ea1383953c3f4ad91bcfb7a69cc8f2236612c6c46f
|
7
|
+
data.tar.gz: 87253dd8de985d402bc83034083c603743e4ae6ac80121a4c6b5bdfb1b58d4c0ae483071fa60205b9038887b0425ed6fe06289b2af4ce85ec49e94314f40d3cb
|
data/CHANGES
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.9.4 - 4-Mar-2014
|
2
|
+
* Added support for AIX 5.3 or later courtesy of Rick Ohnemus.
|
3
|
+
* The Solaris version now uses FFI structs instead of a packed array.
|
4
|
+
It solved issues with 64-bit versions of Ruby and it's self-documenting.
|
5
|
+
* The FreeBSD version has been converted to use FFI. In addition, additional
|
6
|
+
struct members have been added, and members that previously returned nil
|
7
|
+
now return meaningful data.
|
8
|
+
* Support for NetBSD and OpenBSD has been temporarily dropped. Considering
|
9
|
+
that the C code did not build on those platforms anyway, I doubt most of
|
10
|
+
you will notice. Patches for those platforms are welcome, but only using FFI.
|
11
|
+
|
1
12
|
== 0.9.3 - 17-Mar-2013
|
2
13
|
* Fixed a bug on OSX where a long command string arg could cause
|
3
14
|
a segfault. Thanks go to Nathaniel Bibler for the spot.
|
data/MANIFEST
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
* Rakefile
|
4
4
|
* README
|
5
5
|
* sys-proctable.gemspec
|
6
|
+
* doc/aix.txt
|
6
7
|
* doc/bsd.txt
|
7
8
|
* doc/hpux.txt
|
8
9
|
* doc/linux.txt
|
@@ -10,20 +11,21 @@
|
|
10
11
|
* doc/top.txt
|
11
12
|
* doc/windows.txt
|
12
13
|
* example/example_ps.rb
|
13
|
-
* ext/bsd/extconf.rb
|
14
|
-
* ext/bsd/sys/proctable.c
|
15
14
|
* ext/darwin/extconf.rb
|
16
15
|
* ext/darwin/sys/proctable.c
|
17
16
|
* ext/hpux/extconf.rb
|
18
17
|
* ext/hpux/sys/proctable.c
|
19
18
|
* lib/sys/top.rb
|
19
|
+
* lib/aix/sys/proctable.rb
|
20
|
+
* lib/freebsd/sys/proctable.rb
|
20
21
|
* lib/linux/sys/proctable.rb
|
21
22
|
* lib/sunos/sys/proctable.rb
|
22
23
|
* lib/windows/sys/proctable.rb
|
24
|
+
* test/test_sys_proctable_aix.rb
|
23
25
|
* test/test_sys_proctable_all.rb
|
24
26
|
* test/test_sys_proctable_darwin.rb
|
27
|
+
* test/test_sys_proctable_freebsd.rb
|
25
28
|
* test/test_sys_proctable_hpux.rb
|
26
|
-
* test/test_sys_proctable_bsd.rb
|
27
29
|
* test/test_sys_proctable_linux.rb
|
28
30
|
* test/test_sys_proctable_sunos.rb
|
29
31
|
* test/test_sys_proctable_windows.rb
|
data/README
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
== Supported Platforms
|
8
8
|
* Windows 2000 or later
|
9
9
|
* Linux 2.6+
|
10
|
-
*
|
10
|
+
* FreeBSD
|
11
11
|
* Solaris 8+
|
12
12
|
* HP-UX 10+
|
13
13
|
* OS X 10.4+
|
@@ -20,7 +20,7 @@
|
|
20
20
|
gem install sys-proctable --platform mswin32 # Windows
|
21
21
|
gem install sys-proctable --platform sunos # Solaris
|
22
22
|
gem install sys-proctable --platform linux # Linux
|
23
|
-
gem install sys-proctable --platform freebsd #
|
23
|
+
gem install sys-proctable --platform freebsd # FreeBSD
|
24
24
|
|
25
25
|
== Synopsis
|
26
26
|
require 'sys/proctable'
|
@@ -51,7 +51,7 @@
|
|
51
51
|
information from a different host. This relies on the WMI service running.
|
52
52
|
|
53
53
|
== Known Issues
|
54
|
-
===
|
54
|
+
=== FreeBSD
|
55
55
|
A kvm interface is used. That means the owner of the process using the
|
56
56
|
sys-proctable library needs to be a member of the kvm group (or root).
|
57
57
|
|
@@ -67,13 +67,12 @@
|
|
67
67
|
Using readdir_r() still won't solve all potential thread safety issues anyway.
|
68
68
|
|
69
69
|
== Future Plans
|
70
|
-
|
71
|
-
|
72
|
-
release.
|
70
|
+
Add support for NetBSD and OpenBSD.
|
71
|
+
Convert existing C code to FFI.
|
73
72
|
|
74
73
|
== Acknowledgements
|
75
|
-
This library
|
76
|
-
Dan Urist. Many ideas, as well as large chunks of code, were taken
|
74
|
+
This library was originally based on the Perl module Proc::ProcessTable
|
75
|
+
by Dan Urist. Many ideas, as well as large chunks of code, were taken
|
77
76
|
from his work. So, a big THANK YOU goes out to Dan Urist.
|
78
77
|
|
79
78
|
A big thanks also goes out to Mike Hall who was very helpful with ideas,
|
@@ -105,7 +104,7 @@
|
|
105
104
|
Artistic 2.0
|
106
105
|
|
107
106
|
== Copyright
|
108
|
-
(C) 2003-
|
107
|
+
(C) 2003-2014 Daniel J. Berger
|
109
108
|
All Rights Reserved.
|
110
109
|
|
111
110
|
== Author
|
data/Rakefile
CHANGED
@@ -8,7 +8,7 @@ CLEAN.include(
|
|
8
8
|
'**/*.core', # Core dump files
|
9
9
|
'**/*.gem', # Gem files
|
10
10
|
'**/*.rbc', # Rubinius
|
11
|
-
'
|
11
|
+
'**/*.rbx', # Rubinius
|
12
12
|
'**/*.o', # C object file
|
13
13
|
'**/*.log', # Ruby extension build log
|
14
14
|
'**/Makefile', # C Makefile
|
@@ -27,9 +27,6 @@ task :build => [:clean] do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
case CONFIG['host_os']
|
30
|
-
when /bsd/i
|
31
|
-
dir = 'ext/bsd'
|
32
|
-
ext = '.so'
|
33
30
|
when /darwin/i
|
34
31
|
dir = 'ext/darwin'
|
35
32
|
ext = '.bundle'
|
@@ -38,7 +35,7 @@ task :build => [:clean] do
|
|
38
35
|
ext = '.sl'
|
39
36
|
end
|
40
37
|
|
41
|
-
|
38
|
+
if CONFIG['host_os'] =~ /darwin|hpux/i
|
42
39
|
Dir.chdir(dir) do
|
43
40
|
ruby 'extconf.rb'
|
44
41
|
sh 'make'
|
@@ -61,8 +58,10 @@ task :install => [:build] do
|
|
61
58
|
file = 'lib/linux/sys/proctable.rb'
|
62
59
|
when /sunos|solaris/i
|
63
60
|
file = 'lib/sunos/sys/proctable.rb'
|
64
|
-
when /
|
65
|
-
|
61
|
+
when /aix/i
|
62
|
+
file = 'lib/aix/sys/proctable.rb'
|
63
|
+
when /freebsd/i
|
64
|
+
file = 'lib/freebsd/sys/proctable.rb'
|
66
65
|
when /darwin/i
|
67
66
|
Dir.chdir('ext/darwin'){ sh 'make install' }
|
68
67
|
when /hpux/i
|
@@ -75,12 +74,12 @@ end
|
|
75
74
|
desc 'Uninstall the sys-proctable library'
|
76
75
|
task :uninstall do
|
77
76
|
case CONFIG['host_os']
|
78
|
-
when /
|
79
|
-
dir = File.join(CONFIG['sitelibdir'], 'sys')
|
80
|
-
file = File.join(dir, 'proctable.rb')
|
81
|
-
else
|
77
|
+
when /darwin|hpux/i
|
82
78
|
dir = File.join(CONFIG['sitearchdir'], 'sys')
|
83
79
|
file = File.join(dir, 'proctable.' + CONFIG['DLEXT'])
|
80
|
+
else
|
81
|
+
dir = File.join(CONFIG['sitelibdir'], 'sys')
|
82
|
+
file = File.join(dir, 'proctable.rb')
|
84
83
|
end
|
85
84
|
|
86
85
|
rm(file)
|
@@ -111,12 +110,15 @@ Rake::TestTask.new do |t|
|
|
111
110
|
when /sunos|solaris/i
|
112
111
|
t.test_files = FileList['test/test_sys_proctable_sunos.rb']
|
113
112
|
t.libs << 'lib/sunos'
|
113
|
+
when /aix/i
|
114
|
+
t.test_files = FileList['test/test_sys_proctable_aix.rb']
|
115
|
+
t.libs << 'lib/aix'
|
116
|
+
when /freebsd/i
|
117
|
+
t.test_files = FileList['test/test_sys_proctable_freebsd.rb']
|
118
|
+
t.libs << 'lib/freebsd'
|
114
119
|
when /darwin/i
|
115
120
|
t.libs << 'ext/darwin'
|
116
121
|
t.test_files = FileList['test/test_sys_proctable_darwin.rb']
|
117
|
-
when /bsd/i
|
118
|
-
t.libs << 'ext/bsd'
|
119
|
-
t.test_files = FileList['test/test_sys_proctable_bsd.rb']
|
120
122
|
when /hpux/i
|
121
123
|
t.libs << 'ext/hpux'
|
122
124
|
t.test_files = FileList['test/test_sys_proctable_hpux.rb']
|
@@ -133,13 +135,12 @@ namespace :gem do
|
|
133
135
|
# of some bugginess in Rubygems' platform.rb.
|
134
136
|
#
|
135
137
|
case CONFIG['host_os']
|
136
|
-
when /
|
138
|
+
when /freebsd/i
|
137
139
|
spec.platform = Gem::Platform.new(['universal', 'freebsd'])
|
138
|
-
spec.
|
139
|
-
spec.files
|
140
|
-
spec.
|
141
|
-
spec.
|
142
|
-
spec.extensions = ['ext/bsd/extconf.rb']
|
140
|
+
spec.require_paths = ['lib', 'lib/freebsd']
|
141
|
+
spec.files += ['lib/freebsd/sys/proctable.rb']
|
142
|
+
spec.test_files << 'test/test_sys_proctable_freebsd.rb'
|
143
|
+
spec.add_dependency('ffi')
|
143
144
|
when /darwin/i
|
144
145
|
spec.platform = Gem::Platform.new(['universal', 'darwin'])
|
145
146
|
spec.files << 'ext/darwin/sys/proctable.c'
|
@@ -162,6 +163,11 @@ namespace :gem do
|
|
162
163
|
spec.require_paths = ['lib', 'lib/sunos']
|
163
164
|
spec.files += ['lib/sunos/sys/proctable.rb']
|
164
165
|
spec.test_files << 'test/test_sys_proctable_sunos.rb'
|
166
|
+
when /aix/i
|
167
|
+
spec.platform = Gem::Platform.new(['universal', 'aix5'])
|
168
|
+
spec.require_paths = ['lib', 'lib/aix']
|
169
|
+
spec.files += ['lib/aix/sys/proctable.rb']
|
170
|
+
spec.test_files << 'test/test_sys_proctable_aix.rb'
|
165
171
|
when /mswin|win32|dos|cygwin|mingw|windows/i
|
166
172
|
spec.platform = Gem::Platform.new(['universal', 'mingw32'])
|
167
173
|
spec.require_paths = ['lib', 'lib/windows']
|
@@ -172,7 +178,12 @@ namespace :gem do
|
|
172
178
|
# https://github.com/rubygems/rubygems/issues/147
|
173
179
|
spec.original_platform = spec.platform
|
174
180
|
|
175
|
-
Gem::
|
181
|
+
if Gem::VERSION < "2.0"
|
182
|
+
Gem::Builder.new(spec).build
|
183
|
+
else
|
184
|
+
require 'rubygems/package'
|
185
|
+
Gem::Package.build(spec)
|
186
|
+
end
|
176
187
|
end
|
177
188
|
|
178
189
|
desc 'Install the sys-proctable library as a gem'
|
@@ -0,0 +1,363 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
|
3
|
+
module Sys
|
4
|
+
class ProcTable
|
5
|
+
extend FFI::Library
|
6
|
+
|
7
|
+
# The version of the sys-proctable library.
|
8
|
+
VERSION = '0.9.4'
|
9
|
+
|
10
|
+
# Error typically raised if the ProcTable.ps method fails.
|
11
|
+
class Error < StandardError; end
|
12
|
+
|
13
|
+
# There is no constructor
|
14
|
+
private_class_method :new
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
ffi_lib :kvm
|
19
|
+
|
20
|
+
attach_function :devname, [:dev_t, :mode_t], :string
|
21
|
+
attach_function :kvm_open, [:string, :string, :string, :int, :string], :pointer
|
22
|
+
attach_function :kvm_close, [:pointer], :int
|
23
|
+
attach_function :kvm_getprocs, [:pointer, :int, :int, :pointer], :pointer
|
24
|
+
attach_function :kvm_getargv, [:pointer, :pointer, :int], :pointer
|
25
|
+
|
26
|
+
POSIX_ARG_MAX = 4096
|
27
|
+
|
28
|
+
KERN_PROC_PID = 1
|
29
|
+
KERN_PROC_PROC = 8
|
30
|
+
|
31
|
+
S_IFCHR = 0020000
|
32
|
+
|
33
|
+
WMESGLEN = 8
|
34
|
+
LOCKNAMELEN = 8
|
35
|
+
OCOMMLEN = 16
|
36
|
+
COMMLEN = 19
|
37
|
+
KI_EMULNAMELEN = 16
|
38
|
+
KI_NGROUPS = 16
|
39
|
+
LOGNAMELEN = 17
|
40
|
+
KI_NSPARE_INT = 9
|
41
|
+
KI_NSPARE_LONG = 12
|
42
|
+
KI_NSPARE_PTR = 6
|
43
|
+
|
44
|
+
class Timeval < FFI::Struct
|
45
|
+
layout(:tv_sec, :time_t, :tv_usec, :suseconds_t)
|
46
|
+
end
|
47
|
+
|
48
|
+
class Priority < FFI::Struct
|
49
|
+
layout(
|
50
|
+
:pri_class, :uchar,
|
51
|
+
:pri_level, :uchar,
|
52
|
+
:pri_native, :uchar,
|
53
|
+
:pri_user, :uchar
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
class Rusage < FFI::Struct
|
58
|
+
layout(
|
59
|
+
:ru_utime, Timeval,
|
60
|
+
:ru_stime, Timeval,
|
61
|
+
:ru_maxrss, :long,
|
62
|
+
:ru_ixrss, :long,
|
63
|
+
:ru_idrss, :long,
|
64
|
+
:ru_isrss, :long,
|
65
|
+
:ru_minflt, :long,
|
66
|
+
:ru_majflt, :long,
|
67
|
+
:ru_nswap, :long,
|
68
|
+
:ru_inblock, :long,
|
69
|
+
:ru_oublock, :long,
|
70
|
+
:ru_msgsnd, :long,
|
71
|
+
:ru_msgrcv, :long,
|
72
|
+
:ru_nsignals, :long,
|
73
|
+
:ru_nvcsw, :long,
|
74
|
+
:ru_nivcsw, :long
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
class Pargs < FFI::Struct
|
79
|
+
layout(
|
80
|
+
:ar_ref, :uint,
|
81
|
+
:ar_length, :uint,
|
82
|
+
:ar_args, [:uchar,1]
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
class KInfoProc < FFI::Struct
|
87
|
+
layout(
|
88
|
+
:ki_structsize, :int,
|
89
|
+
:ki_layout, :int,
|
90
|
+
:ki_args, :pointer,
|
91
|
+
:ki_paddr, :pointer,
|
92
|
+
:ki_addr, :pointer,
|
93
|
+
:ki_tracep, :pointer,
|
94
|
+
:ki_textvp, :pointer,
|
95
|
+
:ki_fd, :pointer,
|
96
|
+
:ki_vmspace, :pointer,
|
97
|
+
:ki_wchan, :pointer,
|
98
|
+
:ki_pid, :pid_t,
|
99
|
+
:ki_ppid, :pid_t,
|
100
|
+
:ki_pgid, :pid_t,
|
101
|
+
:ki_tpgid, :pid_t,
|
102
|
+
:ki_sid, :pid_t,
|
103
|
+
:ki_tsid, :pid_t,
|
104
|
+
:ki_jobc, :short,
|
105
|
+
:ki_spare_short1, :short,
|
106
|
+
:ki_tdev, :dev_t,
|
107
|
+
:ki_siglist, [:uint32_t, 4],
|
108
|
+
:ki_sigmask, [:uint32_t, 4],
|
109
|
+
:ki_sigignore, [:uint32_t, 4],
|
110
|
+
:ki_sigcatch, [:uint32_t, 4],
|
111
|
+
:ki_uid, :uid_t,
|
112
|
+
:ki_ruid, :uid_t,
|
113
|
+
:ki_svuid, :uid_t,
|
114
|
+
:ki_rgid, :gid_t,
|
115
|
+
:ki_svgid, :gid_t,
|
116
|
+
:ki_ngroups, :short,
|
117
|
+
:ki_spare_short2, :short,
|
118
|
+
:ki_groups, [:gid_t, KI_NGROUPS],
|
119
|
+
:ki_size, :vm_size_t,
|
120
|
+
:ki_rssize, :segsz_t,
|
121
|
+
:ki_swrss, :segsz_t,
|
122
|
+
:ki_tsize, :segsz_t,
|
123
|
+
:ki_dsize, :segsz_t,
|
124
|
+
:ki_ssize, :segsz_t,
|
125
|
+
:ki_xstat, :u_short,
|
126
|
+
:ki_acflag, :u_short,
|
127
|
+
:ki_pctcpu, :fixpt_t,
|
128
|
+
:ki_estcpu, :uint,
|
129
|
+
:ki_slptime, :uint,
|
130
|
+
:ki_swtime, :uint,
|
131
|
+
:ki_swtime, :int,
|
132
|
+
:ki_runtime, :uint64_t,
|
133
|
+
:ki_start, Timeval,
|
134
|
+
:ki_childtime, Timeval,
|
135
|
+
:ki_flag, :long,
|
136
|
+
:ki_kiflag, :long,
|
137
|
+
:ki_traceflag, :int,
|
138
|
+
:ki_stat, :char,
|
139
|
+
:ki_nice, :char,
|
140
|
+
:ki_lock, :char,
|
141
|
+
:ki_rqindex, :char,
|
142
|
+
:ki_oncpu, :uchar,
|
143
|
+
:ki_lastcpu, :uchar,
|
144
|
+
:ki_ocomm, [:char, OCOMMLEN+1],
|
145
|
+
:ki_wmesg, [:char, WMESGLEN+1],
|
146
|
+
:ki_login, [:char, LOGNAMELEN+1],
|
147
|
+
:ki_lockname, [:char, LOCKNAMELEN+1],
|
148
|
+
:ki_comm, [:char, COMMLEN+1],
|
149
|
+
:ki_emul, [:char, KI_EMULNAMELEN+1],
|
150
|
+
:ki_sparestrings, [:char, 68],
|
151
|
+
:ki_spareints, [:int, KI_NSPARE_INT],
|
152
|
+
:ki_cr_flags, :uint,
|
153
|
+
:ki_jid, :int,
|
154
|
+
:ki_numthreads, :int,
|
155
|
+
:ki_tid, :lwpid_t,
|
156
|
+
:ki_pri, Priority,
|
157
|
+
:ki_rusage, Rusage,
|
158
|
+
:ki_rusage_ch, Rusage,
|
159
|
+
:ki_pcb, :pointer,
|
160
|
+
:ki_kstack, :pointer,
|
161
|
+
:ki_udata, :pointer,
|
162
|
+
:ki_tdaddr, :pointer,
|
163
|
+
:ki_spareptrs, [:pointer, KI_NSPARE_PTR],
|
164
|
+
:ki_sparelongs, [:long, KI_NSPARE_LONG],
|
165
|
+
:ki_sflags, :long,
|
166
|
+
:ki_tdflags, :long
|
167
|
+
)
|
168
|
+
end
|
169
|
+
|
170
|
+
@fields = %w[
|
171
|
+
pid ppid pgid tpgid sid tsid jobc uid ruid rgid
|
172
|
+
ngroups groups size rssize swrss tsize dsize ssize
|
173
|
+
xstat acflag pctcpu estcpu slptime swtime runtime start
|
174
|
+
flag state nice lock rqindex oncpu lastcpu wmesg login
|
175
|
+
lockname comm ttynum ttydev jid priority usrpri cmdline
|
176
|
+
utime stime maxrss ixrss idrss isrss minflt majflt nswap
|
177
|
+
inblock oublock msgsnd msgrcv nsignals nvcsw nivcsw
|
178
|
+
]
|
179
|
+
|
180
|
+
ProcTableStruct = Struct.new('ProcTableStruct', *@fields)
|
181
|
+
|
182
|
+
public
|
183
|
+
|
184
|
+
# In block form, yields a ProcTableStruct for each process entry that you
|
185
|
+
# have rights to. This method returns an array of ProcTableStruct's in
|
186
|
+
# non-block form.
|
187
|
+
#
|
188
|
+
# If a +pid+ is provided, then only a single ProcTableStruct is yielded or
|
189
|
+
# returned, or nil if no process information is found for that +pid+.
|
190
|
+
#
|
191
|
+
# Example:
|
192
|
+
#
|
193
|
+
# # Iterate over all processes
|
194
|
+
# ProcTable.ps do |proc_info|
|
195
|
+
# p proc_info
|
196
|
+
# end
|
197
|
+
#
|
198
|
+
# # Print process table information for only pid 1001
|
199
|
+
# p ProcTable.ps(1001)
|
200
|
+
#
|
201
|
+
def self.ps(pid = nil)
|
202
|
+
begin
|
203
|
+
kd = kvm_open(nil, nil, nil, 0, nil)
|
204
|
+
|
205
|
+
if kd.null?
|
206
|
+
raise SystemCallError.new('kvm_open', FFI.errno)
|
207
|
+
end
|
208
|
+
|
209
|
+
ptr = FFI::MemoryPointer.new(:int) # count
|
210
|
+
|
211
|
+
if pid
|
212
|
+
procs = kvm_getprocs(kd, KERN_PROC_PID, pid, ptr)
|
213
|
+
else
|
214
|
+
procs = kvm_getprocs(kd, KERN_PROC_PROC, 0, ptr)
|
215
|
+
end
|
216
|
+
|
217
|
+
if procs.null?
|
218
|
+
if pid && FFI.errno == Errno::ESRCH::Errno
|
219
|
+
return nil
|
220
|
+
else
|
221
|
+
raise SystemCallError.new('kvm_getprocs', FFI.errno)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
count = ptr.read_int
|
226
|
+
array = []
|
227
|
+
|
228
|
+
0.upto(count-1){ |i|
|
229
|
+
cmd = nil
|
230
|
+
kinfo = KInfoProc.new(procs[i * KInfoProc.size])
|
231
|
+
|
232
|
+
args = kvm_getargv(kd, kinfo, 0)
|
233
|
+
|
234
|
+
unless args.null?
|
235
|
+
cmd = []
|
236
|
+
|
237
|
+
until ((ptr = args.read_pointer).null?)
|
238
|
+
cmd << ptr.read_string
|
239
|
+
args += FFI::Type::POINTER.size
|
240
|
+
end
|
241
|
+
|
242
|
+
cmd = cmd.join(' ')
|
243
|
+
end
|
244
|
+
|
245
|
+
struct = ProcTableStruct.new(
|
246
|
+
kinfo[:ki_pid],
|
247
|
+
kinfo[:ki_ppid],
|
248
|
+
kinfo[:ki_pgid],
|
249
|
+
kinfo[:ki_tpgid],
|
250
|
+
kinfo[:ki_sid],
|
251
|
+
kinfo[:ki_tsid],
|
252
|
+
kinfo[:ki_jobc],
|
253
|
+
kinfo[:ki_uid],
|
254
|
+
kinfo[:ki_ruid],
|
255
|
+
kinfo[:ki_rgid],
|
256
|
+
kinfo[:ki_ngroups],
|
257
|
+
kinfo[:ki_groups].to_a[0...kinfo[:ki_ngroups]],
|
258
|
+
kinfo[:ki_size],
|
259
|
+
kinfo[:ki_rssize],
|
260
|
+
kinfo[:ki_swrss],
|
261
|
+
kinfo[:ki_tsize],
|
262
|
+
kinfo[:ki_dsize],
|
263
|
+
kinfo[:ki_ssize],
|
264
|
+
kinfo[:ki_xstat],
|
265
|
+
kinfo[:ki_acflag],
|
266
|
+
kinfo[:ki_pctcpu].to_f,
|
267
|
+
kinfo[:ki_estcpu],
|
268
|
+
kinfo[:ki_slptime],
|
269
|
+
kinfo[:ki_swtime],
|
270
|
+
kinfo[:ki_runtime],
|
271
|
+
Time.at(kinfo[:ki_start][:tv_sec]),
|
272
|
+
kinfo[:ki_flag],
|
273
|
+
get_state(kinfo[:ki_stat]),
|
274
|
+
kinfo[:ki_nice],
|
275
|
+
kinfo[:ki_lock],
|
276
|
+
kinfo[:ki_rqindex],
|
277
|
+
kinfo[:ki_oncpu],
|
278
|
+
kinfo[:ki_lastcpu],
|
279
|
+
kinfo[:ki_wmesg].to_s,
|
280
|
+
kinfo[:ki_login].to_s,
|
281
|
+
kinfo[:ki_lockname].to_s,
|
282
|
+
kinfo[:ki_comm].to_s,
|
283
|
+
kinfo[:ki_tdev],
|
284
|
+
devname(kinfo[:ki_tdev], S_IFCHR),
|
285
|
+
kinfo[:ki_jid],
|
286
|
+
kinfo[:ki_pri][:pri_level],
|
287
|
+
kinfo[:ki_pri][:pri_user],
|
288
|
+
cmd,
|
289
|
+
kinfo[:ki_rusage][:ru_utime][:tv_sec],
|
290
|
+
kinfo[:ki_rusage][:ru_stime][:tv_sec],
|
291
|
+
kinfo[:ki_rusage][:ru_maxrss],
|
292
|
+
kinfo[:ki_rusage][:ru_ixrss],
|
293
|
+
kinfo[:ki_rusage][:ru_idrss],
|
294
|
+
kinfo[:ki_rusage][:ru_isrss],
|
295
|
+
kinfo[:ki_rusage][:ru_minflt],
|
296
|
+
kinfo[:ki_rusage][:ru_majflt],
|
297
|
+
kinfo[:ki_rusage][:ru_nswap],
|
298
|
+
kinfo[:ki_rusage][:ru_inblock],
|
299
|
+
kinfo[:ki_rusage][:ru_oublock],
|
300
|
+
kinfo[:ki_rusage][:ru_msgsnd],
|
301
|
+
kinfo[:ki_rusage][:ru_msgrcv],
|
302
|
+
kinfo[:ki_rusage][:ru_nsignals],
|
303
|
+
kinfo[:ki_rusage][:ru_nvcsw],
|
304
|
+
kinfo[:ki_rusage][:ru_nivcsw]
|
305
|
+
)
|
306
|
+
|
307
|
+
struct.freeze # This is readonly data
|
308
|
+
|
309
|
+
if block_given?
|
310
|
+
yield struct
|
311
|
+
else
|
312
|
+
array << struct
|
313
|
+
end
|
314
|
+
}
|
315
|
+
ensure
|
316
|
+
kvm_close(kd) unless kd.null?
|
317
|
+
end
|
318
|
+
|
319
|
+
if block_given?
|
320
|
+
nil
|
321
|
+
else
|
322
|
+
pid ? array.first : array
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# Returns an array of fields that each ProcTableStruct will contain. This
|
327
|
+
# may be useful if you want to know in advance what fields are available
|
328
|
+
# without having to perform at least one read of the /proc table.
|
329
|
+
#
|
330
|
+
# Example:
|
331
|
+
#
|
332
|
+
# Sys::ProcTable.fields.each{ |field|
|
333
|
+
# puts "Field: #{field}"
|
334
|
+
# }
|
335
|
+
#
|
336
|
+
def self.fields
|
337
|
+
@fields
|
338
|
+
end
|
339
|
+
|
340
|
+
private
|
341
|
+
|
342
|
+
SIDL = 1
|
343
|
+
SRUN = 2
|
344
|
+
SSLEEP = 3
|
345
|
+
SSTOP = 4
|
346
|
+
SZOMB = 5
|
347
|
+
SWAIT = 6
|
348
|
+
SLOCK = 7
|
349
|
+
|
350
|
+
def self.get_state(int)
|
351
|
+
case int
|
352
|
+
when SIDL; "idle"
|
353
|
+
when SRUN; "run"
|
354
|
+
when SSLEEP; "sleep"
|
355
|
+
when SSTOP; "stop"
|
356
|
+
when SZOMB; "zombie"
|
357
|
+
when SWAIT; "waiting"
|
358
|
+
when SLOCK; "locked"
|
359
|
+
else; "unknown"
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
data/lib/sys/top.rb
CHANGED
@@ -7,19 +7,21 @@ module Sys
|
|
7
7
|
class Top
|
8
8
|
|
9
9
|
# The version of the sys-top library
|
10
|
-
VERSION = '1.0.
|
10
|
+
VERSION = '1.0.4'
|
11
11
|
|
12
12
|
# Returns an array of Struct::ProcTableStruct elements containing up
|
13
13
|
# to +num+ elements, sorted by +field+. The default number of elements
|
14
14
|
# is 10, while the default field is 'pctcpu'.
|
15
15
|
#
|
16
|
-
# Exception: the default sort field is 'pid' on
|
16
|
+
# Exception: the default sort field is 'pid' on AIX and Windows.
|
17
17
|
#
|
18
18
|
def self.top(num=10, field='pctcpu')
|
19
19
|
field = field.to_s if field.is_a?(Symbol)
|
20
20
|
|
21
|
-
|
22
|
-
|
21
|
+
aix = RbConfig::CONFIG['host_os'] =~ /aix/i
|
22
|
+
|
23
|
+
# Sort by pid on Windows and AIX by default
|
24
|
+
if (File::ALT_SEPARATOR || aix) && field == 'pctcpu'
|
23
25
|
field = 'pid'
|
24
26
|
end
|
25
27
|
|
data/sys-proctable.gemspec
CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'sys-proctable'
|
5
|
-
spec.version = '0.9.
|
5
|
+
spec.version = '0.9.4'
|
6
6
|
spec.author = 'Daniel J. Berger'
|
7
7
|
spec.license = 'Artistic 2.0'
|
8
8
|
spec.email = 'djberg96@gmail.com'
|
@@ -26,7 +26,8 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.rubyforge_project = 'sysutils'
|
27
27
|
spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST', 'doc/top.txt']
|
28
28
|
|
29
|
-
spec.add_development_dependency('test-unit'
|
29
|
+
spec.add_development_dependency('test-unit')
|
30
|
+
spec.add_development_dependency('rake')
|
30
31
|
|
31
32
|
spec.description = <<-EOF
|
32
33
|
The sys-proctable library provides an interface for gathering information
|
@@ -4,10 +4,7 @@
|
|
4
4
|
# Test suite for methods common to all platforms. Generally speaking
|
5
5
|
# you should run this test case using the 'rake test' task.
|
6
6
|
#######################################################################
|
7
|
-
require '
|
8
|
-
gem 'test-unit'
|
9
|
-
|
10
|
-
require 'test/unit'
|
7
|
+
require 'test-unit'
|
11
8
|
require 'sys/proctable'
|
12
9
|
require 'test/test_sys_top'
|
13
10
|
include Sys
|
@@ -22,7 +19,7 @@ class TC_ProcTable_All < Test::Unit::TestCase
|
|
22
19
|
end
|
23
20
|
|
24
21
|
def test_version
|
25
|
-
assert_equal('0.9.
|
22
|
+
assert_equal('0.9.4', ProcTable::VERSION)
|
26
23
|
end
|
27
24
|
|
28
25
|
def test_fields
|
@@ -1,29 +1,29 @@
|
|
1
1
|
################################################################
|
2
|
-
#
|
2
|
+
# test_sys_proctable_freebsd.rb
|
3
3
|
#
|
4
|
-
# Test suite for
|
5
|
-
#
|
4
|
+
# Test suite for FreeBSD for the sys-proctable library.
|
5
|
+
# You should run these tests via 'rake test'.
|
6
6
|
################################################################
|
7
|
-
require '
|
8
|
-
gem 'test-unit'
|
9
|
-
|
10
|
-
require 'test/unit'
|
7
|
+
require 'test-unit'
|
11
8
|
require 'sys/proctable'
|
12
9
|
require 'test/test_sys_proctable_all'
|
13
10
|
include Sys
|
14
11
|
|
15
|
-
class
|
12
|
+
class TC_Sys_ProcTable_FreeBSD < Test::Unit::TestCase
|
16
13
|
def self.startup
|
17
|
-
@@fields = %w
|
18
|
-
pid ppid pgid
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
@@fields = %w[
|
15
|
+
pid ppid pgid tpgid sid tsid jobc uid ruid rgid
|
16
|
+
ngroups groups size rssize swrss tsize dsize ssize
|
17
|
+
xstat acflag pctcpu estcpu slptime swtime runtime start
|
18
|
+
flag state nice lock rqindex oncpu lastcpu wmesg login
|
19
|
+
lockname comm ttynum ttydev jid priority usrpri cmdline
|
20
|
+
utime stime maxrss ixrss idrss isrss minflt majflt nswap
|
21
|
+
inblock oublock msgsnd msgrcv nsignals nvcsw nivcsw
|
22
|
+
]
|
23
23
|
end
|
24
24
|
|
25
25
|
def setup
|
26
|
-
@ptable = ProcTable.ps.
|
26
|
+
@ptable = ProcTable.ps(Process.pid)
|
27
27
|
end
|
28
28
|
|
29
29
|
def test_fields
|
@@ -92,9 +92,9 @@ class TC_Sys_ProcTable_BSD < Test::Unit::TestCase
|
|
92
92
|
assert_kind_of(String, @ptable.wmesg)
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
assert_respond_to(@ptable, :
|
97
|
-
assert_kind_of(Fixnum, @ptable.
|
95
|
+
def test_runtime
|
96
|
+
assert_respond_to(@ptable, :runtime)
|
97
|
+
assert_kind_of(Fixnum, @ptable.runtime)
|
98
98
|
end
|
99
99
|
|
100
100
|
def test_priority
|
@@ -124,82 +124,82 @@ class TC_Sys_ProcTable_BSD < Test::Unit::TestCase
|
|
124
124
|
|
125
125
|
def test_maxrss
|
126
126
|
assert_respond_to(@ptable, :maxrss)
|
127
|
-
|
127
|
+
assert_kind_of(Fixnum, @ptable.maxrss)
|
128
128
|
end
|
129
129
|
|
130
130
|
def test_ixrss
|
131
131
|
assert_respond_to(@ptable, :ixrss)
|
132
|
-
|
132
|
+
assert_kind_of(Fixnum, @ptable.ixrss)
|
133
133
|
end
|
134
134
|
|
135
135
|
def test_idrss
|
136
136
|
assert_respond_to(@ptable, :idrss)
|
137
|
-
|
137
|
+
assert_kind_of(Fixnum, @ptable.idrss)
|
138
138
|
end
|
139
139
|
|
140
140
|
def test_isrss
|
141
141
|
assert_respond_to(@ptable, :isrss)
|
142
|
-
|
142
|
+
assert_kind_of(Fixnum, @ptable.isrss)
|
143
143
|
end
|
144
144
|
|
145
145
|
def test_minflt
|
146
146
|
assert_respond_to(@ptable, :minflt)
|
147
|
-
|
147
|
+
assert_kind_of(Fixnum, @ptable.minflt)
|
148
148
|
end
|
149
149
|
|
150
150
|
def test_majflt
|
151
151
|
assert_respond_to(@ptable, :majflt)
|
152
|
-
|
152
|
+
assert_kind_of(Fixnum, @ptable.majflt)
|
153
153
|
end
|
154
154
|
|
155
155
|
def test_nswap
|
156
156
|
assert_respond_to(@ptable, :nswap)
|
157
|
-
|
157
|
+
assert_kind_of(Fixnum, @ptable.nswap)
|
158
158
|
end
|
159
159
|
|
160
160
|
def test_inblock
|
161
161
|
assert_respond_to(@ptable, :inblock)
|
162
|
-
|
162
|
+
assert_kind_of(Fixnum, @ptable.inblock)
|
163
163
|
end
|
164
164
|
|
165
165
|
def test_oublock
|
166
166
|
assert_respond_to(@ptable, :oublock)
|
167
|
-
|
167
|
+
assert_kind_of(Fixnum, @ptable.oublock)
|
168
168
|
end
|
169
169
|
|
170
170
|
def test_msgsnd
|
171
171
|
assert_respond_to(@ptable, :msgsnd)
|
172
|
-
|
172
|
+
assert_kind_of(Fixnum, @ptable.msgsnd)
|
173
173
|
end
|
174
174
|
|
175
175
|
def test_msgrcv
|
176
176
|
assert_respond_to(@ptable, :msgrcv)
|
177
|
-
|
177
|
+
assert_kind_of(Fixnum, @ptable.msgrcv)
|
178
178
|
end
|
179
179
|
|
180
180
|
def test_nsignals
|
181
181
|
assert_respond_to(@ptable, :nsignals)
|
182
|
-
|
182
|
+
assert_kind_of(Fixnum, @ptable.nsignals)
|
183
183
|
end
|
184
184
|
|
185
185
|
def test_nvcsw
|
186
186
|
assert_respond_to(@ptable, :nvcsw)
|
187
|
-
|
187
|
+
assert_kind_of(Fixnum, @ptable.nvcsw)
|
188
188
|
end
|
189
189
|
|
190
190
|
def test_nivcsw
|
191
191
|
assert_respond_to(@ptable, :nivcsw)
|
192
|
-
|
192
|
+
assert_kind_of(Fixnum, @ptable.nivcsw)
|
193
193
|
end
|
194
194
|
|
195
195
|
def test_utime
|
196
196
|
assert_respond_to(@ptable, :utime)
|
197
|
-
|
197
|
+
assert_kind_of(Fixnum, @ptable.utime)
|
198
198
|
end
|
199
199
|
|
200
200
|
def test_stime
|
201
201
|
assert_respond_to(@ptable, :stime)
|
202
|
-
|
202
|
+
assert_kind_of(Fixnum, @ptable.stime)
|
203
203
|
end
|
204
204
|
|
205
205
|
def teardown
|
metadata
CHANGED
@@ -1,97 +1,109 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: sys-proctable
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 9
|
9
|
-
- 3
|
10
|
-
version: 0.9.3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.4
|
11
5
|
platform: universal-freebsd
|
12
|
-
authors:
|
6
|
+
authors:
|
13
7
|
- Daniel J. Berger
|
14
8
|
autorequire:
|
15
9
|
bindir: bin
|
16
10
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2014-03-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
21
14
|
name: test-unit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
22
21
|
prerelease: false
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
26
31
|
- - ">="
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 2
|
31
|
-
- 4
|
32
|
-
- 0
|
33
|
-
version: 2.4.0
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
|
-
|
36
|
-
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: ffi
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: |2
|
56
|
+
The sys-proctable library provides an interface for gathering information
|
57
|
+
about processes on your system, i.e. the process table. Most major
|
58
|
+
platforms are supported and, while different platforms may return
|
59
|
+
different information, the external interface is identical across
|
60
|
+
platforms.
|
37
61
|
email: djberg96@gmail.com
|
38
62
|
executables: []
|
39
|
-
|
40
|
-
|
41
|
-
- ext/bsd/extconf.rb
|
42
|
-
extra_rdoc_files:
|
63
|
+
extensions: []
|
64
|
+
extra_rdoc_files:
|
43
65
|
- CHANGES
|
44
66
|
- README
|
45
67
|
- MANIFEST
|
46
68
|
- doc/top.txt
|
47
|
-
|
48
|
-
files:
|
49
|
-
- benchmarks/bench_ps.rb
|
50
|
-
- examples/example_ps.rb
|
51
|
-
- lib/sys/top.rb
|
69
|
+
files:
|
52
70
|
- CHANGES
|
53
71
|
- MANIFEST
|
54
|
-
- Rakefile
|
55
72
|
- README
|
73
|
+
- Rakefile
|
74
|
+
- benchmarks/bench_ps.rb
|
75
|
+
- doc/top.txt
|
76
|
+
- examples/example_ps.rb
|
77
|
+
- lib/freebsd/sys/proctable.rb
|
78
|
+
- lib/sys/top.rb
|
56
79
|
- sys-proctable.gemspec
|
57
80
|
- test/test_sys_proctable_all.rb
|
58
|
-
-
|
59
|
-
- ext/bsd/sys/proctable.c
|
60
|
-
- test/test_sys_proctable_bsd.rb
|
61
|
-
- ext/bsd/extconf.rb
|
81
|
+
- test/test_sys_proctable_freebsd.rb
|
62
82
|
homepage: http://www.rubyforge.org/projects/sysutils
|
63
|
-
licenses:
|
83
|
+
licenses:
|
64
84
|
- Artistic 2.0
|
85
|
+
metadata: {}
|
65
86
|
post_install_message:
|
66
87
|
rdoc_options: []
|
67
|
-
|
68
|
-
require_paths:
|
88
|
+
require_paths:
|
69
89
|
- lib
|
70
|
-
|
71
|
-
|
72
|
-
requirements:
|
90
|
+
- lib/freebsd
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
73
93
|
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
version: "0"
|
79
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
-
none: false
|
81
|
-
requirements:
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
82
98
|
- - ">="
|
83
|
-
- !ruby/object:Gem::Version
|
84
|
-
|
85
|
-
segments:
|
86
|
-
- 0
|
87
|
-
version: "0"
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
88
101
|
requirements: []
|
89
|
-
|
90
102
|
rubyforge_project: sysutils
|
91
|
-
rubygems_version:
|
103
|
+
rubygems_version: 2.2.2
|
92
104
|
signing_key:
|
93
|
-
specification_version:
|
105
|
+
specification_version: 4
|
94
106
|
summary: An interface for providing process table information
|
95
|
-
test_files:
|
107
|
+
test_files:
|
96
108
|
- test/test_sys_proctable_all.rb
|
97
|
-
- test/
|
109
|
+
- test/test_sys_proctable_freebsd.rb
|
data/ext/bsd/extconf.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
require 'mkmf'
|
2
|
-
|
3
|
-
have_type('rb_pid_t', 'ruby.h')
|
4
|
-
|
5
|
-
have_library('kvm')
|
6
|
-
have_func('kvm_openfiles')
|
7
|
-
have_struct_member('struct kinfo_proc', 'kp_proc', 'sys/user.h')
|
8
|
-
have_struct_member('struct kinfo_proc', 'kp_eproc', 'sys/user.h')
|
9
|
-
have_struct_member('struct kinfo_proc', 'u_kproc', 'sys/user.h')
|
10
|
-
have_struct_member('struct eproc', 'e_stats', 'sys/sysctl.h')
|
11
|
-
have_struct_member('struct eproc', 'p_oncpu', 'sys/sysctl.h')
|
12
|
-
have_struct_member('struct eproc', 'p_runtime', 'sys/sysctl.h')
|
13
|
-
|
14
|
-
create_makefile('sys/proctable', 'sys')
|
data/ext/bsd/sys/proctable.c
DELETED
@@ -1,301 +0,0 @@
|
|
1
|
-
/**********************************************************************
|
2
|
-
* proctable.c
|
3
|
-
*
|
4
|
-
* This is a generic kvm interface used by the various BSD flavors
|
5
|
-
* for the sys-proctable library.
|
6
|
-
**********************************************************************/
|
7
|
-
#include "ruby.h"
|
8
|
-
#include <kvm.h>
|
9
|
-
#include <sys/param.h>
|
10
|
-
#include <sys/stat.h>
|
11
|
-
#include <sys/sysctl.h>
|
12
|
-
#include <sys/types.h>
|
13
|
-
#include <sys/user.h>
|
14
|
-
|
15
|
-
#define SYS_PROCTABLE_VERSION "0.9.3"
|
16
|
-
|
17
|
-
VALUE cProcTableError, sProcStruct;
|
18
|
-
|
19
|
-
const char* fields[] = {
|
20
|
-
"pid", "ppid", "pgid", "ruid",
|
21
|
-
"rgid", "comm", "state", "pctcpu", "oncpu", "ttynum", "ttydev", "wmesg",
|
22
|
-
"time", "priority", "usrpri", "nice", "cmdline", "start",
|
23
|
-
"maxrss", "ixrss", "idrss", "isrss", "minflt", "majflt", "nswap",
|
24
|
-
"inblock", "oublock", "msgsnd", "msgrcv", "nsignals", "nvcsw", "nivcsw",
|
25
|
-
"utime", "stime"
|
26
|
-
};
|
27
|
-
|
28
|
-
/*
|
29
|
-
* call-seq:
|
30
|
-
* ProcTable.ps(pid=nil)
|
31
|
-
* ProcTable.ps(pid=nil){ |ps| ... }
|
32
|
-
*
|
33
|
-
* In block form, yields a ProcTableStruct for each process entry that you
|
34
|
-
* have rights to. This method returns an array of ProcTableStruct's in
|
35
|
-
* non-block form.
|
36
|
-
*
|
37
|
-
* If a +pid+ is provided, then only a single ProcTableStruct is yielded or
|
38
|
-
* returned, or nil if no process information is found for that +pid+.
|
39
|
-
*/
|
40
|
-
static VALUE pt_ps(int argc, VALUE* argv, VALUE klass){
|
41
|
-
kvm_t *kd;
|
42
|
-
char errbuf[_POSIX2_LINE_MAX];
|
43
|
-
char cmdline[_POSIX_ARG_MAX+1];
|
44
|
-
char state[8];
|
45
|
-
char** args = malloc(sizeof(char*));
|
46
|
-
struct kinfo_proc* procs;
|
47
|
-
int count; // Holds total number of processes
|
48
|
-
int i = 0;
|
49
|
-
VALUE v_pid, v_tty_num, v_tty_dev, v_start_time;
|
50
|
-
VALUE v_pstruct = Qnil;
|
51
|
-
VALUE v_array = Qnil;
|
52
|
-
|
53
|
-
rb_scan_args(argc, argv, "01", &v_pid);
|
54
|
-
|
55
|
-
if(!NIL_P(v_pid))
|
56
|
-
Check_Type(v_pid, T_FIXNUM);
|
57
|
-
|
58
|
-
if(!rb_block_given_p())
|
59
|
-
v_array = rb_ary_new();
|
60
|
-
|
61
|
-
// Open the kvm interface, get a descriptor
|
62
|
-
if((kd = kvm_open(NULL, NULL, NULL, 0, "kvm_open")) == NULL)
|
63
|
-
rb_raise(cProcTableError, "kvm_open failed: %s", strerror(errno));
|
64
|
-
|
65
|
-
// Get the list of processes
|
66
|
-
if((procs = kvm_getprocs(kd, KERN_PROC_ALL, 0, &count)) == NULL) {
|
67
|
-
strcpy(errbuf, kvm_geterr(kd));
|
68
|
-
kvm_close(kd);
|
69
|
-
rb_raise(cProcTableError, errbuf);
|
70
|
-
}
|
71
|
-
|
72
|
-
for(i=0; i<count; i++){
|
73
|
-
// Reset some variables
|
74
|
-
v_tty_num = Qnil;
|
75
|
-
v_tty_dev = Qnil;
|
76
|
-
v_start_time = Qnil;
|
77
|
-
|
78
|
-
// If a PID is provided, skip unless the PID matches
|
79
|
-
if(!NIL_P(v_pid)){
|
80
|
-
#ifdef HAVE_ST_KP_PROC
|
81
|
-
if(procs[i].kp_proc.p_pid != NUM2INT(v_pid))
|
82
|
-
continue;
|
83
|
-
#else
|
84
|
-
if(procs[i].ki_pid != NUM2INT(v_pid))
|
85
|
-
continue;
|
86
|
-
#endif
|
87
|
-
}
|
88
|
-
|
89
|
-
// Get the command line arguments for the process
|
90
|
-
cmdline[0] = '\0';
|
91
|
-
args = kvm_getargv(kd, (const struct kinfo_proc *)&procs[i], 0);
|
92
|
-
|
93
|
-
if(args){
|
94
|
-
int j = 0;
|
95
|
-
while (args[j] && strlen(cmdline) <= _POSIX_ARG_MAX) {
|
96
|
-
strcat(cmdline, args[j]);
|
97
|
-
strcat(cmdline, " ");
|
98
|
-
j++;
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
// Get the start time of the process
|
103
|
-
v_start_time = rb_time_new(
|
104
|
-
#ifdef HAVE_ST_E_STATS
|
105
|
-
procs[i].kp_eproc.e_stats.p_start.tv_sec,
|
106
|
-
procs[i].kp_eproc.e_stats.p_start.tv_usec
|
107
|
-
#else
|
108
|
-
0,0
|
109
|
-
#endif
|
110
|
-
);
|
111
|
-
|
112
|
-
// Get the state of the process
|
113
|
-
#ifdef HAVE_ST_KP_PROC
|
114
|
-
switch(procs[i].kp_proc.p_stat)
|
115
|
-
#else
|
116
|
-
switch(procs[i].ki_stat)
|
117
|
-
#endif
|
118
|
-
{
|
119
|
-
case SIDL:
|
120
|
-
strcpy(state, "idle");
|
121
|
-
break;
|
122
|
-
case SRUN:
|
123
|
-
strcpy(state, "run");
|
124
|
-
break;
|
125
|
-
case SSLEEP:
|
126
|
-
strcpy(state, "sleep");
|
127
|
-
break;
|
128
|
-
case SSTOP:
|
129
|
-
strcpy(state, "stop");
|
130
|
-
break;
|
131
|
-
case SZOMB:
|
132
|
-
strcpy(state, "zombie");
|
133
|
-
break;
|
134
|
-
default:
|
135
|
-
strcpy(state, "unknown");
|
136
|
-
break;
|
137
|
-
}
|
138
|
-
|
139
|
-
// Get ttynum and ttydev. If ttynum is -1, there is no tty
|
140
|
-
#ifdef HAVE_ST_KP_EPROC
|
141
|
-
v_tty_num = INT2FIX(procs[i].kp_eproc.e_tdev),
|
142
|
-
v_tty_dev = rb_str_new2(devname(procs[i].kp_eproc.e_tdev, S_IFCHR));
|
143
|
-
#elif HAVE_ST_U_KPROC
|
144
|
-
v_tty_num = INT2FIX(procs[i].u_kproc.ki_tdev),
|
145
|
-
v_tty_dev = rb_str_new2(devname(procs[i].u_kproc.ki_tdev, S_IFCHR));
|
146
|
-
#else
|
147
|
-
v_tty_num = INT2FIX(procs[i].ki_tdev),
|
148
|
-
v_tty_dev = rb_str_new2(devname(procs[i].ki_tdev, S_IFCHR));
|
149
|
-
#endif
|
150
|
-
|
151
|
-
#ifdef HAVE_ST_KP_PROC
|
152
|
-
v_pstruct = rb_struct_new(
|
153
|
-
sProcStruct,
|
154
|
-
INT2FIX(procs[i].kp_proc.p_pid),
|
155
|
-
INT2FIX(procs[i].kp_eproc.e_ppid),
|
156
|
-
INT2FIX(procs[i].kp_eproc.e_pgid),
|
157
|
-
INT2FIX(procs[i].kp_eproc.e_pcred.p_ruid),
|
158
|
-
INT2FIX(procs[i].kp_eproc.e_pcred.p_rgid),
|
159
|
-
rb_str_new2(procs[i].kp_proc.p_comm),
|
160
|
-
rb_str_new2(state),
|
161
|
-
rb_float_new(procs[i].kp_proc.p_pctcpu),
|
162
|
-
#ifdef HAVE_ST_P_ONCPU
|
163
|
-
INT2FIX(procs[i].kp_proc.p_oncpu),
|
164
|
-
#else
|
165
|
-
Qnil,
|
166
|
-
#endif
|
167
|
-
v_tty_num,
|
168
|
-
v_tty_dev,
|
169
|
-
rb_str_new2(procs[i].kp_eproc.e_wmesg),
|
170
|
-
#ifdef HAVE_ST_P_RUNTIME
|
171
|
-
INT2FIX(procs[i].kp_proc.p_runtime/1000000),
|
172
|
-
#else
|
173
|
-
Qnil,
|
174
|
-
#endif
|
175
|
-
INT2FIX(procs[i].kp_proc.p_priority),
|
176
|
-
INT2FIX(procs[i].kp_proc.p_usrpri),
|
177
|
-
INT2FIX(procs[i].kp_proc.p_nice),
|
178
|
-
rb_str_new2(cmdline),
|
179
|
-
v_start_time,
|
180
|
-
#ifdef HAVE_ST_E_STATS
|
181
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_maxrss),
|
182
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_ixrss),
|
183
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_idrss),
|
184
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_isrss),
|
185
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_minflt),
|
186
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_majflt),
|
187
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_nswap),
|
188
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_inblock),
|
189
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_oublock),
|
190
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_msgsnd),
|
191
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_msgrcv),
|
192
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_nsignals),
|
193
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_nvcsw),
|
194
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_nivcsw),
|
195
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_utime.tv_sec),
|
196
|
-
LONG2NUM(procs[i].kp_eproc.e_stats.p_ru.ru_stime.tv_sec)
|
197
|
-
#else
|
198
|
-
Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil,
|
199
|
-
Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil
|
200
|
-
#endif
|
201
|
-
);
|
202
|
-
#else
|
203
|
-
v_pstruct = rb_struct_new(
|
204
|
-
sProcStruct,
|
205
|
-
INT2FIX(procs[i].ki_pid),
|
206
|
-
INT2FIX(procs[i].ki_ppid),
|
207
|
-
INT2FIX(procs[i].ki_pgid),
|
208
|
-
INT2FIX(procs[i].ki_ruid),
|
209
|
-
INT2FIX(procs[i].ki_rgid),
|
210
|
-
rb_str_new2(procs[i].ki_ocomm),
|
211
|
-
rb_str_new2(state),
|
212
|
-
rb_float_new(procs[i].ki_pctcpu),
|
213
|
-
INT2FIX(procs[i].ki_oncpu),
|
214
|
-
v_tty_num,
|
215
|
-
v_tty_dev,
|
216
|
-
rb_str_new2(procs[i].ki_wmesg),
|
217
|
-
INT2FIX(procs[i].ki_runtime/1000000),
|
218
|
-
INT2FIX(procs[i].ki_pri.pri_level),
|
219
|
-
INT2FIX(procs[i].ki_pri.pri_user),
|
220
|
-
INT2FIX(procs[i].ki_nice),
|
221
|
-
rb_str_new2(cmdline),
|
222
|
-
v_start_time,
|
223
|
-
Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil,
|
224
|
-
Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil
|
225
|
-
);
|
226
|
-
#endif
|
227
|
-
|
228
|
-
OBJ_FREEZE(v_pstruct); // Read-only data
|
229
|
-
|
230
|
-
if(rb_block_given_p())
|
231
|
-
rb_yield(v_pstruct);
|
232
|
-
else
|
233
|
-
rb_ary_push(v_array, v_pstruct);
|
234
|
-
}
|
235
|
-
|
236
|
-
if(kd)
|
237
|
-
kvm_close(kd);
|
238
|
-
|
239
|
-
if(!NIL_P(v_pid))
|
240
|
-
return v_pstruct;
|
241
|
-
|
242
|
-
return v_array; // Nil if block given
|
243
|
-
}
|
244
|
-
|
245
|
-
/*
|
246
|
-
* call-seq:
|
247
|
-
* ProcTable.fields
|
248
|
-
*
|
249
|
-
* Returns an array of fields that each ProcTableStruct will contain. This
|
250
|
-
* may be useful if you want to know in advance what fields are available
|
251
|
-
* without having to perform at least one read of the /proc table.
|
252
|
-
*/
|
253
|
-
static VALUE pt_fields(VALUE klass){
|
254
|
-
VALUE v_array = rb_ary_new();
|
255
|
-
int size = sizeof(fields) / sizeof(fields[0]);
|
256
|
-
int i;
|
257
|
-
|
258
|
-
for(i = 0; i < size; i++)
|
259
|
-
rb_ary_push(v_array, rb_str_new2(fields[i]));
|
260
|
-
|
261
|
-
return v_array;
|
262
|
-
}
|
263
|
-
|
264
|
-
/*
|
265
|
-
* A Ruby interface for gathering process table information.
|
266
|
-
*/
|
267
|
-
void Init_proctable(){
|
268
|
-
VALUE mSys, cProcTable;
|
269
|
-
|
270
|
-
/* The Sys module serves as a namespace only */
|
271
|
-
mSys = rb_define_module("Sys");
|
272
|
-
|
273
|
-
/* The ProcTable class encapsulates process table information */
|
274
|
-
cProcTable = rb_define_class_under(mSys, "ProcTable", rb_cObject);
|
275
|
-
|
276
|
-
/* The error typically raised if any of the ProcTable methods fail */
|
277
|
-
cProcTableError = rb_define_class_under(cProcTable, "Error", rb_eStandardError);
|
278
|
-
|
279
|
-
/* Singleton Methods */
|
280
|
-
|
281
|
-
rb_define_singleton_method(cProcTable, "ps", pt_ps, -1);
|
282
|
-
rb_define_singleton_method(cProcTable, "fields", pt_fields, 0);
|
283
|
-
|
284
|
-
/* There is no constructor */
|
285
|
-
rb_funcall(cProcTable, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
|
286
|
-
|
287
|
-
/* Constants */
|
288
|
-
|
289
|
-
/* 0.9.3: The version of the sys-proctable library */
|
290
|
-
rb_define_const(cProcTable, "VERSION", rb_str_new2(SYS_PROCTABLE_VERSION));
|
291
|
-
|
292
|
-
/* Structures */
|
293
|
-
|
294
|
-
sProcStruct = rb_struct_define("ProcTableStruct","pid","ppid","pgid","ruid",
|
295
|
-
"rgid","comm","state","pctcpu","oncpu","ttynum","ttydev","wmesg",
|
296
|
-
"time", "priority","usrpri","nice","cmdline","start",
|
297
|
-
"maxrss","ixrss","idrss","isrss","minflt","majflt","nswap",
|
298
|
-
"inblock","oublock","msgsnd","msgrcv","nsignals","nvcsw","nivcsw",
|
299
|
-
"utime","stime", NULL
|
300
|
-
);
|
301
|
-
}
|