sys-proctable 0.7.6-powerpc-darwin
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +233 -0
- data/MANIFEST +41 -0
- data/README +140 -0
- data/doc/freebsd.txt +90 -0
- data/doc/hpux.txt +77 -0
- data/doc/linux.txt +85 -0
- data/doc/solaris.txt +99 -0
- data/doc/top.txt +53 -0
- data/doc/windows.txt +122 -0
- data/ext/darwin/darwin.c +240 -0
- data/ext/extconf.rb +98 -0
- data/ext/version.h +2 -0
- data/lib/sys/top.rb +23 -0
- data/test/tc_all.rb +59 -0
- data/test/tc_freebsd.rb +45 -0
- data/test/tc_hpux.rb +49 -0
- data/test/tc_kvm_bsd.rb +31 -0
- data/test/tc_linux.rb +45 -0
- data/test/tc_sunos.rb +52 -0
- data/test/tc_top.rb +26 -0
- data/test/tc_windows.rb +40 -0
- data/test/test_memleak.rb +54 -0
- metadata +71 -0
data/doc/hpux.txt
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
= Description
|
2
|
+
sys-proctable
|
3
|
+
|
4
|
+
A Ruby version of the 'ps' command. This is a C extension, not parsed
|
5
|
+
output. For HP-UX, proc structs are grabbed via the pstat_getproc() call.
|
6
|
+
|
7
|
+
= Synopsis
|
8
|
+
require 'sys/proctable'
|
9
|
+
include Sys
|
10
|
+
|
11
|
+
# Everything
|
12
|
+
ProcTable.ps{ |p|
|
13
|
+
puts p.pid.to_s
|
14
|
+
puts p.comm
|
15
|
+
...
|
16
|
+
}
|
17
|
+
|
18
|
+
or
|
19
|
+
|
20
|
+
# Return the results as an array of ProcTableStructs
|
21
|
+
a = ProcTable.ps()
|
22
|
+
a.each do |p|
|
23
|
+
puts a.pid
|
24
|
+
...
|
25
|
+
end
|
26
|
+
|
27
|
+
= Constants
|
28
|
+
VERSION
|
29
|
+
Returns the current version number for this package (as a string).
|
30
|
+
|
31
|
+
= Class Methods
|
32
|
+
ProcTable.fields
|
33
|
+
Returns an array of fields available on the current OS.
|
34
|
+
|
35
|
+
ProcTable.ps(pid=nil)
|
36
|
+
ProcTable.ps{ |s| ... }
|
37
|
+
Returns a struct of type ProcTableStruct for every process in the proc
|
38
|
+
table in block form. Otherwise it returns an array of ProcTableStruct's.
|
39
|
+
|
40
|
+
If a pid is provided then a single ProcTable struct is returned, or nil
|
41
|
+
if the pid is not found.
|
42
|
+
|
43
|
+
= Supported fields
|
44
|
+
You can view the supported fields with the "fields()" class method.
|
45
|
+
|
46
|
+
= Future Plans
|
47
|
+
Have the flags field return a meaningful value.
|
48
|
+
|
49
|
+
= Notes
|
50
|
+
The "comm" field isn't really part of the psinfo struct. It is just a copy
|
51
|
+
(i.e. is identical to) the "fname" field. I added it to provide a degree
|
52
|
+
of consistency between all of the platforms. I will also make a point
|
53
|
+
of adding it to any future platform releases.
|
54
|
+
|
55
|
+
= Known Bugs
|
56
|
+
None that I'm aware of. Please log any bugs on the project page at
|
57
|
+
http://www.rubyforge.org/projects/sysutils
|
58
|
+
|
59
|
+
= License
|
60
|
+
Ruby's
|
61
|
+
|
62
|
+
= Copyright
|
63
|
+
(C) 2003-2006 Daniel J. Berger
|
64
|
+
All Rights Reserved.
|
65
|
+
|
66
|
+
= Warranty
|
67
|
+
This package is provided "as is" and without any express or
|
68
|
+
implied warranties, including, without limitation, the implied
|
69
|
+
warranties of merchantability and fitness for a particular purpose.
|
70
|
+
|
71
|
+
= Author
|
72
|
+
Daniel J. Berger
|
73
|
+
djberg96 at nospam at gmail dot com
|
74
|
+
imperator on IRC (Freenode)
|
75
|
+
|
76
|
+
= See Also
|
77
|
+
ps, proc
|
data/doc/linux.txt
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
= Description
|
2
|
+
sys-proctable
|
3
|
+
|
4
|
+
A Ruby version of the 'ps' command. This is a C extension, not parsed
|
5
|
+
output. For Linux, process information is read out of /proc.
|
6
|
+
|
7
|
+
= Synopsis
|
8
|
+
require 'sys/proctable'
|
9
|
+
include Sys
|
10
|
+
|
11
|
+
# Everything
|
12
|
+
ProcTable.ps{ |p|
|
13
|
+
puts p.pid.to_s
|
14
|
+
puts p.comm
|
15
|
+
...
|
16
|
+
}
|
17
|
+
|
18
|
+
or
|
19
|
+
|
20
|
+
# Just one process
|
21
|
+
p = ProcTable.ps(2123)
|
22
|
+
puts p.pid.to_s
|
23
|
+
puts p.comm
|
24
|
+
...
|
25
|
+
|
26
|
+
or
|
27
|
+
|
28
|
+
# Return the results as an array of ProcTableStructs
|
29
|
+
a = ProcTable.ps()
|
30
|
+
a.each do |p|
|
31
|
+
puts a.pid
|
32
|
+
...
|
33
|
+
end
|
34
|
+
|
35
|
+
= Constants
|
36
|
+
VERSION
|
37
|
+
Returns the current version number for this package (as a string).
|
38
|
+
|
39
|
+
= Class Methods
|
40
|
+
ProcTable.fields
|
41
|
+
Returns an array of fields available on the current OS.
|
42
|
+
|
43
|
+
ProcTable.ps(pid=nil)
|
44
|
+
ProcTable.ps{ |s| ... }
|
45
|
+
If no pid's or processes are included as arguments, in block form it
|
46
|
+
returns a struct of type ProcTableStruct for every process in the proc
|
47
|
+
table. Otherwise it returns an array of ProcTableStruct's.
|
48
|
+
|
49
|
+
If a process id is provided, a single ProcTable struct is returned, or
|
50
|
+
nil if the pid is not found.
|
51
|
+
|
52
|
+
= Exception Classes
|
53
|
+
ProcTableError < StandardError
|
54
|
+
Raised if the /proc field is unreadable and/or unmounted.
|
55
|
+
|
56
|
+
= Supported fields
|
57
|
+
You can view the supported fields with the "fields()" class method.
|
58
|
+
|
59
|
+
= Future Plans
|
60
|
+
Create a pure Ruby version as an alternative.
|
61
|
+
Change the ttynum field to ttydev and return a string instead of an int.
|
62
|
+
|
63
|
+
= Known Bugs
|
64
|
+
None known. Please log any bugs on the project page at
|
65
|
+
http://www.rubyforge.org/projects/sysutils
|
66
|
+
|
67
|
+
= License
|
68
|
+
Ruby's
|
69
|
+
|
70
|
+
= Copyright
|
71
|
+
(C) 2003-2006 Daniel J. Berger
|
72
|
+
All Rights Reserved
|
73
|
+
|
74
|
+
= Warranty
|
75
|
+
This package is provided "as is" and without any express or
|
76
|
+
implied warranties, including, without limitation, the implied
|
77
|
+
warranties of merchantability and fitness for a particular purpose.
|
78
|
+
|
79
|
+
= Author
|
80
|
+
Daniel J. Berger
|
81
|
+
djberg96 at nospam at gmail dot com
|
82
|
+
rubyhacker1 on IRC (Freenode)
|
83
|
+
|
84
|
+
= See Also
|
85
|
+
ps, proc(5)
|
data/doc/solaris.txt
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
= Description
|
2
|
+
sys-proctable
|
3
|
+
|
4
|
+
A Ruby version of the 'ps' command. This is a C extension, not parsed
|
5
|
+
output. For Solaris, data is read out of /proc via the psinfo struct.
|
6
|
+
|
7
|
+
= Synopsis
|
8
|
+
require 'sys/proctable'
|
9
|
+
include Sys
|
10
|
+
|
11
|
+
# Everything
|
12
|
+
ProcTable.ps{ |p|
|
13
|
+
puts p.pid.to_s
|
14
|
+
puts p.comm
|
15
|
+
...
|
16
|
+
}
|
17
|
+
|
18
|
+
or
|
19
|
+
|
20
|
+
# Just one process
|
21
|
+
s = ProcTable.ps(2123)
|
22
|
+
puts s.pid.to_s
|
23
|
+
puts s.comm
|
24
|
+
...
|
25
|
+
|
26
|
+
# Return the results as an array of ProcTableStructs
|
27
|
+
a = ProcTable.ps
|
28
|
+
a.each do |p|
|
29
|
+
puts a.pid
|
30
|
+
...
|
31
|
+
end
|
32
|
+
|
33
|
+
= Constants
|
34
|
+
VERSION
|
35
|
+
Returns the current version number for this package (as a string).
|
36
|
+
|
37
|
+
= Class Methods
|
38
|
+
ProcTable.fields
|
39
|
+
Returns an array of fields available on the current OS.
|
40
|
+
|
41
|
+
ProcTable.ps(pid=nil)
|
42
|
+
ProcTable.ps{ |s| ... }
|
43
|
+
If no pid is included as an argument, in block form it
|
44
|
+
returns a struct of type ProcTableStruct for every process in the proc
|
45
|
+
table. Otherwise it returns an array of ProcTable struct's. If a pid
|
46
|
+
is provided it will return a single ProcTable struct for that pid, or
|
47
|
+
nil if it is not found.
|
48
|
+
|
49
|
+
= Exception Classes
|
50
|
+
ProcTableError < StandardError
|
51
|
+
Raised if the /proc directory is unreadable and/or unmounted.
|
52
|
+
|
53
|
+
= Supported fields
|
54
|
+
You can view the supported fields with the "fields()" class method.
|
55
|
+
|
56
|
+
= Future Plans
|
57
|
+
Return a more meaningful result for the wchan member (2.6+).
|
58
|
+
Add env info where possible.
|
59
|
+
|
60
|
+
= Notes
|
61
|
+
The "comm" field isn't really part of the psinfo struct. It is just a copy
|
62
|
+
(i.e. is identical to) the "fname" field. I added it to provide a degree
|
63
|
+
of consistency between all of the platforms. I will also make a point
|
64
|
+
of adding it to any future platform releases.
|
65
|
+
|
66
|
+
The cmdline string is limited to 80 characters, except for those processes
|
67
|
+
which you (or your program) own.
|
68
|
+
|
69
|
+
The ttydev field is, for now, an integer. If there is no associated tty with
|
70
|
+
the process, a -1 is returned. In the future, this field will be changed to
|
71
|
+
a string (i.e. the actual device name).
|
72
|
+
|
73
|
+
I suppose I *could* add a -lkvm version for Solaris (this is what Dan Urist
|
74
|
+
is now using in Proc::ProcessTable) but I haven't found a compelling reason
|
75
|
+
to do so. If you think you have one, please let me know.
|
76
|
+
|
77
|
+
= Known Bugs
|
78
|
+
None that I am aware of. Please log any bugs on the RubyForge project page at
|
79
|
+
http://www.rubyforge.org/projects/sysutils
|
80
|
+
|
81
|
+
= License
|
82
|
+
Ruby's
|
83
|
+
|
84
|
+
= Copyright
|
85
|
+
(C) 2003-2006 Daniel J. Berger
|
86
|
+
All Rights Reserved.
|
87
|
+
|
88
|
+
= Warranty
|
89
|
+
This package is provided "as is" and without any express or
|
90
|
+
implied warranties, including, without limitation, the implied
|
91
|
+
warranties of merchantability and fitness for a particular purpose.
|
92
|
+
|
93
|
+
= Author
|
94
|
+
Daniel J. Berger
|
95
|
+
djberg96 at nospam at gmail dot com
|
96
|
+
imperator on IRC (Freenode)
|
97
|
+
|
98
|
+
= See Also
|
99
|
+
ps, proc
|
data/doc/top.txt
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
= Description
|
2
|
+
A simple 'top' interface for Ruby
|
3
|
+
|
4
|
+
= Prerequisites
|
5
|
+
Requires the "sys/proctable" package (which should be installed along
|
6
|
+
with this package).
|
7
|
+
|
8
|
+
= Synopsis
|
9
|
+
require "sys/top"
|
10
|
+
include Sys
|
11
|
+
|
12
|
+
Top.top(5).each{ |ps|
|
13
|
+
p ps
|
14
|
+
}
|
15
|
+
|
16
|
+
= Constants
|
17
|
+
VERSION
|
18
|
+
Returns the version number of this package as a String.
|
19
|
+
|
20
|
+
= Class Methods
|
21
|
+
Top.top(number=10, field="pctcpu")
|
22
|
+
Returns an array of ProcTableStruct's. The size of the array (i.e. the
|
23
|
+
number of processes) that it returns is based on +number+, and sorted by
|
24
|
+
+pctcpu+. By default, the size and field values are 10 and "pctcpu",
|
25
|
+
respectively.
|
26
|
+
|
27
|
+
= Notes
|
28
|
+
Not all fields are available on all platforms. Please check your
|
29
|
+
platform specific documentation for which fields are available.
|
30
|
+
|
31
|
+
I used sort() instead of sort_by() internally to maintain backward
|
32
|
+
compatability with Ruby 1.6.8, which I happen to need.
|
33
|
+
|
34
|
+
= Bugs
|
35
|
+
None that I'm aware of. Please log bug reports on the project page at
|
36
|
+
http://www.rubyforge.org/projects/sysutils
|
37
|
+
|
38
|
+
= License
|
39
|
+
Ruby's
|
40
|
+
|
41
|
+
= Copyright
|
42
|
+
(C) 2004-2006 Daniel J. Berger
|
43
|
+
All Rights Reserved.
|
44
|
+
|
45
|
+
= Warranty
|
46
|
+
This package is provided "as is" and without any express or
|
47
|
+
implied warranties, including, without limitation, the implied
|
48
|
+
warranties of merchantability and fitness for a particular purpose.
|
49
|
+
|
50
|
+
= Author
|
51
|
+
Daniel J. Berger
|
52
|
+
djberg96 at nospam at gmail dot com
|
53
|
+
imperator on IRC (Freenode)
|
data/doc/windows.txt
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
= Description
|
2
|
+
A Ruby interface for gathering process information. For MS Windows,
|
3
|
+
the process information is gathered via OLE + WMI, using pure Ruby.
|
4
|
+
|
5
|
+
= Synopsis
|
6
|
+
require 'sys/proctable'
|
7
|
+
include Sys
|
8
|
+
|
9
|
+
# Everything
|
10
|
+
ProcTable.ps{ |p|
|
11
|
+
puts p.pid.to_s
|
12
|
+
puts p.comm
|
13
|
+
...
|
14
|
+
}
|
15
|
+
|
16
|
+
or
|
17
|
+
|
18
|
+
# A single pid
|
19
|
+
p = ProcTable.ps(1234)
|
20
|
+
puts p.pid.to_s
|
21
|
+
puts p.comm
|
22
|
+
...
|
23
|
+
|
24
|
+
or
|
25
|
+
|
26
|
+
# Return the results as an array of ProcTableStructs
|
27
|
+
a = ProcTable.ps
|
28
|
+
a.each do |p|
|
29
|
+
puts a.pid
|
30
|
+
...
|
31
|
+
end
|
32
|
+
|
33
|
+
= Constants
|
34
|
+
VERSION
|
35
|
+
Returns the current version number for this package (as a string).
|
36
|
+
|
37
|
+
= Class Methods
|
38
|
+
ProcTable.fields
|
39
|
+
Returns an Array of fields available on the current OS in the
|
40
|
+
ProcTableStruct.
|
41
|
+
|
42
|
+
ProcTable.ps(pid=nil, host='localhost')
|
43
|
+
ProcTable.ps{ |s| ... }
|
44
|
+
Returns a struct of type ProcTableStruct for every process in the proc
|
45
|
+
table in block form. Otherwise it returns an array of ProcTableStruct's.
|
46
|
+
|
47
|
+
If 'pid' is provided, then only a struct for that pid is returned, or
|
48
|
+
nil if it is not found.
|
49
|
+
|
50
|
+
If 'host' is provided, then processes from that host are gathered. By
|
51
|
+
default, process information is gathered on the local host.
|
52
|
+
|
53
|
+
= Supported fields
|
54
|
+
The currently supported fields for MS Windows (i.e. your ProcTable struct
|
55
|
+
members) are:
|
56
|
+
|
57
|
+
caption, cmdline, comm, creation_class_name, creation_date,
|
58
|
+
cs_creation_class_name, cs_name, description, executable_path,
|
59
|
+
execution_state, handle, handle_count, install_date, kernel_mode_time,
|
60
|
+
maximum_working_set_size, minimum_working_set_size, name,
|
61
|
+
os_creation_class_name, os_name, other_operation_count,
|
62
|
+
other_transfer_count, page_faults, page_file_usage, peak_virtual_size,
|
63
|
+
ppid, peak_working_set_size, priority, private_page_count, pid,
|
64
|
+
quota_non_paged_pool_usage, quota_paged_pool_usage,
|
65
|
+
quota_peak_non_paged_pool_usage, quota_non_paged_pool_usage,
|
66
|
+
read_operation_count, read_transfer_count, session_id,
|
67
|
+
termination_date, thread_count, user_mode_time, virtual_size,
|
68
|
+
windows_version, working_set_size, write_operation_count,
|
69
|
+
write_transfer_count
|
70
|
+
|
71
|
+
You can also view them with the fields() class method.
|
72
|
+
|
73
|
+
= Notes
|
74
|
+
For the sake of attempting to provide a somewhat common API, the 'comm'
|
75
|
+
and 'cmdline' fields have been included as part of the structure. The
|
76
|
+
'comm' member corresponds to the Name attribute of Win32_Process. The
|
77
|
+
'cmdline' attribute corresponds to either the Executable_Path attribute
|
78
|
+
(on Windows 2000 or earlier) or the CommandLine attribute (on Windows XP
|
79
|
+
and later).
|
80
|
+
|
81
|
+
Also note that the ProcessId and ParentProcessId attributes have been
|
82
|
+
abbreviated as 'pid' and 'ppid' in the struct members, again to keep the
|
83
|
+
members more consistent between platforms.
|
84
|
+
|
85
|
+
The "Mem Usage" and "VM Size" that you may be used to seeing in your Task
|
86
|
+
Manager window (probably) correspond to the 'working_set_size' and
|
87
|
+
'page_file_usage' struct members, respectively, keeping in mind that
|
88
|
+
those values are in bytes, not kilobytes. I say 'probably' because
|
89
|
+
comments that I've read online indicate that it may not always line up
|
90
|
+
with what you see in the Task Manager, based on the current version (or
|
91
|
+
even Service Pack) of Windows that you are using.
|
92
|
+
|
93
|
+
= Future Plans
|
94
|
+
Possibly use the Win32_PerfFormattedData_PerfProc_Process class to get
|
95
|
+
additional process information.
|
96
|
+
|
97
|
+
= Known Bugs
|
98
|
+
Versions of Ruby earlier than 1.8.2 resulted in segfaults when trying to
|
99
|
+
run this code. You will likely encounter the same behavior.
|
100
|
+
|
101
|
+
Please log any additional bug reports on the project page at
|
102
|
+
http://www.rubyforge.org/projects/sysutils
|
103
|
+
|
104
|
+
= License
|
105
|
+
Ruby's
|
106
|
+
|
107
|
+
= Copyright
|
108
|
+
(C) 2003-2006 Daniel J. Berger
|
109
|
+
All Rights Reserved
|
110
|
+
|
111
|
+
= Warranty
|
112
|
+
This package is provided "as is" and without any express or
|
113
|
+
implied warranties, including, without limitation, the implied
|
114
|
+
warranties of merchantability and fitness for a particular purpose.
|
115
|
+
|
116
|
+
= Author
|
117
|
+
Daniel J. Berger
|
118
|
+
djberg96 at nospam at gmail dot com
|
119
|
+
imperator on IRC (freenode)
|
120
|
+
|
121
|
+
= See Also
|
122
|
+
OLE + WMI
|
data/ext/darwin/darwin.c
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
/* Mac OS X code for Ruby Sys::ProcTable */
|
2
|
+
/* Date: 3-Mar-2006 (original submission date) */
|
3
|
+
/* Author: David Felstead (david.felstead at gmail dot com) */
|
4
|
+
/* Based on bsd.c by Daniel J. Berger (djberg96 at gmail dot com) */
|
5
|
+
|
6
|
+
#include "ruby.h"
|
7
|
+
#include "version.h"
|
8
|
+
#include <sys/param.h>
|
9
|
+
#include <sys/stat.h>
|
10
|
+
#include <sys/sysctl.h>
|
11
|
+
#include <sys/types.h>
|
12
|
+
#include <sys/user.h>
|
13
|
+
#include <errno.h>
|
14
|
+
|
15
|
+
#define PROC_MIB_LEN 4
|
16
|
+
#define ARGS_MIB_LEN 3
|
17
|
+
#define ARGS_MAX_LEN 4096
|
18
|
+
VALUE cProcTableError, sProcStruct;
|
19
|
+
|
20
|
+
char* fields[] = {
|
21
|
+
"pid","ppid","pgid","ruid",
|
22
|
+
"rgid","comm","state","pctcpu","cpu_num","tty_num","tty_dev","wchan",
|
23
|
+
"time", "priority","usr_priority","nice","cmdline","start_time",
|
24
|
+
"max_rss","ix_rss","id_rss","is_rss","minflt","maxflt","nswap",
|
25
|
+
"inblock","oublock","msgsnd","msgrcv","nsignals","nvcsw","nivcsw",
|
26
|
+
"user_time","system_time"
|
27
|
+
};
|
28
|
+
|
29
|
+
/*
|
30
|
+
* call-seq:
|
31
|
+
* ProcTable.ps(pid=nil)
|
32
|
+
* ProcTable.ps(pid=nil){ |ps| ... }
|
33
|
+
*
|
34
|
+
* In block form, yields a ProcTableStruct for each process entry that you
|
35
|
+
* have rights to. This method returns an array of ProcTableStruct's in
|
36
|
+
* non-block form.
|
37
|
+
*
|
38
|
+
* If a +pid+ is provided, then only a single ProcTableStruct is yielded or
|
39
|
+
* returned, or nil if no process information is found for that +pid+.
|
40
|
+
*/
|
41
|
+
static VALUE pt_ps(int argc, VALUE* argv, VALUE klass){
|
42
|
+
int err;
|
43
|
+
char state[8];
|
44
|
+
struct kinfo_proc* procs;
|
45
|
+
int count; /* Holds total number of processes */
|
46
|
+
int i = 0;
|
47
|
+
VALUE v_pid, v_tty_num, v_tty_dev, v_start_time;
|
48
|
+
VALUE v_pstruct = Qnil;
|
49
|
+
VALUE v_array = rb_ary_new();
|
50
|
+
size_t length;
|
51
|
+
char args[ARGS_MAX_LEN+1];
|
52
|
+
/* Passed into sysctl call */
|
53
|
+
static const int name_mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
|
54
|
+
|
55
|
+
rb_scan_args(argc, argv, "01", &v_pid);
|
56
|
+
|
57
|
+
/* Get size of proc kproc buffer */
|
58
|
+
err = sysctl( (int *) name_mib, PROC_MIB_LEN, NULL, &length, NULL, 0);
|
59
|
+
|
60
|
+
/* TODO: Get error message from errno */
|
61
|
+
if(err == -1) rb_raise(cProcTableError, strerror(errno));
|
62
|
+
|
63
|
+
/* Populate the kproc buffer */
|
64
|
+
procs = malloc(length);
|
65
|
+
|
66
|
+
if(procs == NULL) rb_raise(cProcTableError, strerror(errno));
|
67
|
+
|
68
|
+
err = sysctl( (int *) name_mib, PROC_MIB_LEN, procs, &length, NULL, 0);
|
69
|
+
|
70
|
+
/* TODO: Get error message from errno */
|
71
|
+
if(err == -1) rb_raise(cProcTableError, strerror(errno));
|
72
|
+
|
73
|
+
/* If we're here, we got our list */
|
74
|
+
count = length / sizeof(struct kinfo_proc);
|
75
|
+
|
76
|
+
for(i=0; i<count; i++) {
|
77
|
+
|
78
|
+
/* Reset some variables */
|
79
|
+
v_tty_num = Qnil;
|
80
|
+
v_tty_dev = Qnil;
|
81
|
+
v_start_time = Qnil;
|
82
|
+
|
83
|
+
/* If a PID is provided, skip unless the PID matches */
|
84
|
+
if( (!NIL_P(v_pid)) && (procs[i].kp_proc.p_pid != NUM2INT(v_pid))) continue;
|
85
|
+
|
86
|
+
*args = '\0';
|
87
|
+
|
88
|
+
/* Query the command line args */
|
89
|
+
/* TODO: Cmd line not working for now - fix */
|
90
|
+
|
91
|
+
/*args_mib[ARGS_MIB_LEN - 1] = procs[i].kp_proc.p_pid;
|
92
|
+
args_err = sysctl( (int *) args_mib, ARGS_MIB_LEN, args, &args_size, NULL, 0);
|
93
|
+
|
94
|
+
if(args_err >= 0) {
|
95
|
+
fprintf(stderr, "Ret: %d LEN: %d\n", err, args_size);
|
96
|
+
char *c;
|
97
|
+
for(c = args; c < args+args_size; c++)
|
98
|
+
if(*c == '\0') *c = ' ';
|
99
|
+
args[args_size] = '\0';
|
100
|
+
} else {
|
101
|
+
fprintf(stderr, "err: %s LEN: %d\n", strerror(errno), args_size);
|
102
|
+
}*/
|
103
|
+
|
104
|
+
/* Get the start time of the process */
|
105
|
+
v_start_time = rb_time_new(
|
106
|
+
procs[i].kp_proc.p_un.__p_starttime.tv_sec,
|
107
|
+
procs[i].kp_proc.p_un.__p_starttime.tv_usec
|
108
|
+
);
|
109
|
+
|
110
|
+
/* Get the state of the process */
|
111
|
+
switch(procs[i].kp_proc.p_stat)
|
112
|
+
{
|
113
|
+
case SIDL:
|
114
|
+
strcpy(state, "idle");
|
115
|
+
break;
|
116
|
+
case SRUN:
|
117
|
+
strcpy(state, "run");
|
118
|
+
break;
|
119
|
+
case SSLEEP:
|
120
|
+
strcpy(state, "sleep");
|
121
|
+
break;
|
122
|
+
case SSTOP:
|
123
|
+
strcpy(state, "stop");
|
124
|
+
break;
|
125
|
+
case SZOMB:
|
126
|
+
strcpy(state, "zombie");
|
127
|
+
break;
|
128
|
+
default:
|
129
|
+
strcpy(state, "unknown");
|
130
|
+
break;
|
131
|
+
}
|
132
|
+
|
133
|
+
/* Get ttynum and ttydev. If ttynum is -1, there is no tty */
|
134
|
+
if(procs[i].kp_eproc.e_tdev != -1){
|
135
|
+
v_tty_num = INT2FIX(procs[i].kp_eproc.e_tdev),
|
136
|
+
v_tty_dev = rb_str_new2(devname(procs[i].kp_eproc.e_tdev, S_IFCHR));
|
137
|
+
}
|
138
|
+
v_pstruct = rb_struct_new(
|
139
|
+
sProcStruct,
|
140
|
+
INT2FIX(procs[i].kp_proc.p_pid),
|
141
|
+
INT2FIX(procs[i].kp_eproc.e_ppid),
|
142
|
+
INT2FIX(procs[i].kp_eproc.e_pgid),
|
143
|
+
INT2FIX(procs[i].kp_eproc.e_pcred.p_ruid),
|
144
|
+
INT2FIX(procs[i].kp_eproc.e_pcred.p_rgid),
|
145
|
+
rb_str_new2(procs[i].kp_proc.p_comm),
|
146
|
+
rb_str_new2(state),
|
147
|
+
rb_float_new(procs[i].kp_proc.p_pctcpu),
|
148
|
+
Qnil, //INT2FIX(procs[i].kp_proc.p_oncpu),
|
149
|
+
v_tty_num,
|
150
|
+
v_tty_dev,
|
151
|
+
rb_str_new2(procs[i].kp_eproc.e_wmesg),
|
152
|
+
INT2FIX(procs[i].kp_proc.p_rtime.tv_sec),
|
153
|
+
INT2FIX(procs[i].kp_proc.p_priority),
|
154
|
+
INT2FIX(procs[i].kp_proc.p_usrpri),
|
155
|
+
INT2FIX(procs[i].kp_proc.p_nice),
|
156
|
+
rb_str_new2(args),
|
157
|
+
v_start_time,
|
158
|
+
/* For some processes, p_ru is NULL */
|
159
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_maxrss) : Qnil,
|
160
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_ixrss) : Qnil,
|
161
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_idrss) : Qnil,
|
162
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_isrss) : Qnil,
|
163
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_minflt) : Qnil,
|
164
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_majflt) : Qnil,
|
165
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nswap) : Qnil,
|
166
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_inblock) : Qnil,
|
167
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_oublock) : Qnil,
|
168
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgsnd) : Qnil,
|
169
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgrcv) : Qnil,
|
170
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nsignals) : Qnil,
|
171
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nvcsw) : Qnil,
|
172
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nivcsw) : Qnil,
|
173
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_utime.tv_sec) : Qnil,
|
174
|
+
procs[i].kp_proc.p_ru ? LONG2NUM(procs[i].kp_proc.p_ru->ru_stime.tv_sec) : Qnil
|
175
|
+
);
|
176
|
+
|
177
|
+
if(rb_block_given_p())
|
178
|
+
rb_yield(v_pstruct);
|
179
|
+
else
|
180
|
+
rb_ary_push(v_array, v_pstruct);
|
181
|
+
}
|
182
|
+
|
183
|
+
if(procs) free(procs);
|
184
|
+
|
185
|
+
if(!rb_block_given_p()){
|
186
|
+
if(NIL_P(v_pid))
|
187
|
+
return v_array;
|
188
|
+
else
|
189
|
+
return v_pstruct;
|
190
|
+
}
|
191
|
+
|
192
|
+
return Qnil;
|
193
|
+
}
|
194
|
+
|
195
|
+
/*
|
196
|
+
* call-seq:
|
197
|
+
* ProcTable.fields
|
198
|
+
*
|
199
|
+
* Returns an array of fields that each ProcTableStruct will contain. This
|
200
|
+
* may be useful if you want to know in advance what fields are available
|
201
|
+
* without having to perform at least one read of the /proc table.
|
202
|
+
*/
|
203
|
+
static VALUE pt_fields(VALUE klass){
|
204
|
+
VALUE v_array = rb_ary_new();
|
205
|
+
int size = sizeof(fields) / sizeof(fields[0]);
|
206
|
+
int i;
|
207
|
+
|
208
|
+
for(i = 0; i < size; i++)
|
209
|
+
rb_ary_push(v_array, rb_str_new2(fields[i]));
|
210
|
+
|
211
|
+
return v_array;
|
212
|
+
}
|
213
|
+
|
214
|
+
/*
|
215
|
+
* A Ruby interface for gathering process table information.
|
216
|
+
*/
|
217
|
+
void Init_proctable(){
|
218
|
+
VALUE mSys, cProcTable;
|
219
|
+
|
220
|
+
/* Classes and Modules */
|
221
|
+
mSys = rb_define_module("Sys");
|
222
|
+
cProcTable = rb_define_class_under(mSys, "ProcTable", rb_cObject);
|
223
|
+
cProcTableError = rb_define_class_under(mSys, "ProcTableError", rb_eStandardError);
|
224
|
+
|
225
|
+
/* Class Methods */
|
226
|
+
rb_define_singleton_method(cProcTable, "ps", pt_ps, -1);
|
227
|
+
rb_define_singleton_method(cProcTable, "fields", pt_fields, 0);
|
228
|
+
|
229
|
+
/* Constants */
|
230
|
+
rb_define_const(cProcTable, "VERSION", rb_str_new2(SYS_PROCTABLE_VERSION));
|
231
|
+
|
232
|
+
/* Structures */
|
233
|
+
sProcStruct = rb_struct_define("ProcTableStruct","pid","ppid","pgid","ruid",
|
234
|
+
"rgid","comm","state","pctcpu","cpu_num","tty_num","tty_dev","wchan",
|
235
|
+
"time", "priority","usr_priority","nice","cmdline","start_time",
|
236
|
+
"max_rss","ix_rss","id_rss","is_rss","minflt","maxflt","nswap",
|
237
|
+
"inblock","oublock","msgsnd","msgrcv","nsignals","nvcsw","nivcsw",
|
238
|
+
"user_time","system_time", NULL
|
239
|
+
);
|
240
|
+
}
|