sys-proctable 0.7.6-powerpc-darwin
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.
- 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
|
+
}
|