sys-proctable 0.7.5 → 0.7.6
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 +17 -1
- data/MANIFEST +1 -1
- data/README +38 -29
- data/ext/extconf.rb +1 -3
- data/ext/sunos/sunos.c +374 -0
- data/ext/sunos/sunos.h +177 -0
- data/ext/version.h +1 -1
- data/test/tc_all.rb +23 -29
- data/test/tc_freebsd.rb +0 -19
- data/test/tc_hpux.rb +0 -18
- data/test/tc_kvm_bsd.rb +0 -14
- data/test/tc_linux.rb +2 -18
- data/test/tc_sunos.rb +0 -17
- data/test/tc_top.rb +0 -8
- data/test/tc_windows.rb +0 -9
- metadata +16 -16
- data/ext/linux/linux.c +0 -320
- data/ext/linux/linux.h +0 -138
data/CHANGES
CHANGED
@@ -1,5 +1,21 @@
|
|
1
|
+
== 0.7.6 - 11-Jul-2007
|
2
|
+
* Fixed the starttime for Linux. Thanks go to Yaroslav Dmitriev for the spot.
|
3
|
+
* Fixed a bug in the MS Windows version within a private method that parsed
|
4
|
+
an MS specific date format. This was caused by a backwards incompatible
|
5
|
+
change in the Time.parse method in Ruby 1.8.6. See ruby-core: 11245 ff.
|
6
|
+
* Fixed the gemspec (I hope). Please let me know if you have problems.
|
7
|
+
* Added a Rakefile. Building, testing and installing should now be handled via
|
8
|
+
Rake tasks. The install.rb file has been removed - that code is now
|
9
|
+
integrated in the Rakefile.
|
10
|
+
* Minor directory layout changes and cleanup (mostly for the extconf.rb file).
|
11
|
+
* Side note - it seems that the code for OS X *does* work, at least on 10.4.10.
|
12
|
+
I can only conclude that previous reports about it failing were related to
|
13
|
+
bugs in OS X or were really just build issues. Apologies (and thanks, again)
|
14
|
+
to David Felstead for the code. However, see the README for more information
|
15
|
+
specific to OS X, as there are shortcomings.
|
16
|
+
|
1
17
|
== 0.7.5 - 23-Nov-2006
|
2
|
-
* Fixed int/long issues for Linux.
|
18
|
+
* Fixed int/long issues for Linux. Thanks go to Matt Lightner for the spot.
|
3
19
|
* Minor documentation fixes and changes to the extconf.rb file.
|
4
20
|
|
5
21
|
== 0.7.4 - 20-Nov-2006
|
data/MANIFEST
CHANGED
data/README
CHANGED
@@ -13,17 +13,11 @@
|
|
13
13
|
* FreeBSD (/proc or kvm)
|
14
14
|
* Solaris
|
15
15
|
* HP-UX
|
16
|
+
* OS X
|
16
17
|
|
17
18
|
= Installation
|
18
|
-
|
19
|
-
|
20
|
-
make
|
21
|
-
cd ..; ruby test/ts_all.rb (optional)
|
22
|
-
make install
|
23
|
-
|
24
|
-
=== MS Windows
|
25
|
-
ruby test/tc_windows.rb (optional)
|
26
|
-
ruby install.rb
|
19
|
+
* rake test (optional)
|
20
|
+
* rake install
|
27
21
|
|
28
22
|
= Synopsis
|
29
23
|
require 'sys/proctable'
|
@@ -53,7 +47,7 @@
|
|
53
47
|
|
54
48
|
= Notes
|
55
49
|
Windows users may pass a host name as a second argument to get process
|
56
|
-
information from a different host.
|
50
|
+
information from a different host. This relies on the WMI service running.
|
57
51
|
|
58
52
|
If you're building C source code, the ts_all.rb file is autogenerated for
|
59
53
|
you.
|
@@ -61,56 +55,71 @@
|
|
61
55
|
= Known Issues
|
62
56
|
=== BSD
|
63
57
|
If you're building on FreeBSD, a standard /proc filesystem read approach is
|
64
|
-
used if mounted.
|
58
|
+
used if mounted. Otherwise, a kvm interface is used. There are more fields
|
65
59
|
available with the kvm interface, but keep in mind that you need to be a
|
66
|
-
member of the kvm group (or root) to use this.
|
67
|
-
|
60
|
+
member of the kvm group (or root) to use this. You can tweak the extconf.rb
|
61
|
+
file manually if you want to force the issue.
|
68
62
|
|
69
|
-
Not all fields are available on FreeBSD 5.x (yet).
|
63
|
+
Not all fields are available on FreeBSD 5.x (yet). OpenBSD and NetBSD are
|
70
64
|
not yet supported.
|
71
65
|
|
72
|
-
Research has indicated that the kvm approach is less favored than a sysctl
|
73
|
-
approach. I will try to add this interface in the 0.8.0 release.
|
74
|
-
|
75
66
|
=== Solaris
|
76
67
|
The cmdline member on solaris is limited to 80 characters unless you (or
|
77
|
-
your program) own the process.
|
68
|
+
your program) own the process. This is a Solaris design flaw/feature.
|
69
|
+
|
70
|
+
=== OS X
|
71
|
+
At the moment you do not get the full command line string. The code required
|
72
|
+
to get this information is obnoxious and I don't have any compelling desire
|
73
|
+
to add it. However, if you're willing to submit a patch I'll accept it.
|
74
|
+
|
75
|
+
You can find a good starting point with the OS X code found in Dan Urist's
|
76
|
+
Proc::ProcessTable module. You can find that module on CPAN. Point your
|
77
|
+
browser at http://search.cpan.org.
|
78
78
|
|
79
79
|
=== Misc
|
80
|
-
If you build your library as a C extension (
|
81
|
-
|
82
|
-
is renamed to 'windows.orig'.
|
83
|
-
it during the 'make install' phase.
|
80
|
+
If you build your library as a C extension (which is what will happen if
|
81
|
+
you run the 'build', 'test', or 'install' Rake tasks), then the windows.rb
|
82
|
+
file under 'lib/sys/' is renamed to 'windows.orig'. This is necessary to
|
83
|
+
prevent mkmf from auto-installing it during the 'make install' phase.
|
84
|
+
|
85
|
+
The 'clean' Rake task will rename it back to 'windows.rb'.
|
84
86
|
|
85
87
|
=== Thread Safety
|
86
88
|
I am not currently using a thread-safe version of readdir(). I am not
|
87
89
|
especially concerned about it either. If you are trying to read information
|
88
90
|
out of /proc from different threads at the same time there is something
|
89
|
-
seriously wrong with your code logic.
|
91
|
+
seriously wrong with your code logic. Using readdir_r() still won't solve
|
90
92
|
all potential thread safety issues anyway.
|
91
93
|
|
92
94
|
= Future Plans
|
93
95
|
I'm considering using a pure Ruby version for Linux.
|
94
96
|
|
97
|
+
Research has indicated that the kvm approach is less favored than a sysctl
|
98
|
+
approach on BSD variants. I will try to add this interface in the 0.8.0
|
99
|
+
release.
|
100
|
+
|
95
101
|
= Acknowledgements
|
96
102
|
This package is largely based on the Perl module Proc::ProcessTable by
|
97
103
|
Dan Urist. Many ideas, as well as large chunks of code, were taken
|
98
|
-
from his work.
|
104
|
+
from his work. So, a big THANK YOU goes out to Dan Urist.
|
99
105
|
|
100
106
|
A big thanks also goes out to Mike Hall who was very helpful with ideas,
|
101
107
|
logic and testing.
|
102
108
|
|
103
109
|
Thanks also go to Sean Chittenden for providing an account on one of his
|
104
|
-
FreeBSD machines.
|
110
|
+
FreeBSD machines. This is how the FreeBSD support was (initially) added.
|
105
111
|
|
106
112
|
Thanks go to James Hranicky for providing a patch that grabs name, eid,
|
107
113
|
euid, gid and guid info in the Linux version, along with some general
|
108
114
|
debugging help.
|
109
115
|
|
116
|
+
Finally I'd like to thank all the folks who have submitted bug reports
|
117
|
+
and/or patches.
|
118
|
+
|
110
119
|
= Help Wanted
|
111
|
-
I do not have access to all platforms.
|
112
|
-
out there, namely
|
113
|
-
like to see ports for.
|
120
|
+
I do not have access to all platforms. There are a few other major platforms
|
121
|
+
out there, namely AIX, OpenBSD, and IRIX, among others, that I would
|
122
|
+
like to see ports for. There are two ways you can help - either submit code
|
114
123
|
for your particular platform or give me an account on your platform so I can
|
115
124
|
develop on it.
|
116
125
|
|
@@ -122,7 +131,7 @@
|
|
122
131
|
Ruby's
|
123
132
|
|
124
133
|
= Copyright
|
125
|
-
(C) 2003-
|
134
|
+
(C) 2003-2007 Daniel J. Berger
|
126
135
|
All Rights Reserved.
|
127
136
|
|
128
137
|
= Author
|
data/ext/extconf.rb
CHANGED
@@ -81,9 +81,7 @@ end
|
|
81
81
|
###################
|
82
82
|
test_file = '../test/ts_all.rb'
|
83
83
|
File.open(test_file, 'w'){ |fh|
|
84
|
-
fh.puts
|
85
|
-
fh.puts '$LOAD_PATH.unshift Dir.pwd + "/lib"'
|
86
|
-
fh.puts '$LOAD_PATH.unshift Dir.pwd + "/ext"'
|
84
|
+
fh.puts "require 'tc_all'"
|
87
85
|
fh.puts "require '#{tc_file}'"
|
88
86
|
fh.puts "require 'tc_top'"
|
89
87
|
}
|
data/ext/sunos/sunos.c
ADDED
@@ -0,0 +1,374 @@
|
|
1
|
+
/**************************************************************************
|
2
|
+
* sunos.c (proctable.c)
|
3
|
+
*
|
4
|
+
* Solaris specific code for the Ruby ps extension. Some code
|
5
|
+
* has been copied directly from Dan Urist's Proc::ProcessTable
|
6
|
+
* Perl module.
|
7
|
+
*
|
8
|
+
* The portion of code that grabs data out of /proc/xxx/as is based
|
9
|
+
* on a post by Roger Faulkner on comp.unix.questions.
|
10
|
+
**************************************************************************/
|
11
|
+
#include "ruby.h"
|
12
|
+
#include "sunos.h"
|
13
|
+
#include "version.h"
|
14
|
+
|
15
|
+
#ifdef __cplusplus
|
16
|
+
extern "C"
|
17
|
+
{
|
18
|
+
#endif
|
19
|
+
|
20
|
+
VALUE sProcStruct, cProcError;
|
21
|
+
|
22
|
+
/*
|
23
|
+
* Private method that converts a psinfo struct into a Ruby struct.
|
24
|
+
*/
|
25
|
+
#ifdef HAVE_PROCFS_H
|
26
|
+
static VALUE proctable_getprocstruct(struct psinfo *p, VALUE v_cmd_array)
|
27
|
+
#else
|
28
|
+
static VALUE proctable_getprocstruct(struct prpsinfo *p, VALUE v_cmd_array)
|
29
|
+
#endif
|
30
|
+
{
|
31
|
+
char state[STATE_MAX];
|
32
|
+
char comm[COMM_MAX];
|
33
|
+
prusage_t pbuf;
|
34
|
+
VALUE cmdline;
|
35
|
+
VALUE rbTTY = Qnil;
|
36
|
+
|
37
|
+
/*
|
38
|
+
* If we were unable to get the full command line, resort to the limited
|
39
|
+
* pr_psargs struct member.
|
40
|
+
*/
|
41
|
+
if(RARRAY(v_cmd_array)->len == 0)
|
42
|
+
cmdline = rb_str_new2(p->pr_psargs);
|
43
|
+
else
|
44
|
+
cmdline = rb_ary_join(v_cmd_array,rb_str_new2(" "));
|
45
|
+
|
46
|
+
if(PRNODEV != p->pr_ttydev)
|
47
|
+
rbTTY = UINT2NUM(p->pr_ttydev);
|
48
|
+
else
|
49
|
+
rbTTY = INT2NUM(-1);
|
50
|
+
|
51
|
+
#ifndef HAVE_PROCFS_H
|
52
|
+
char wchan[WCHAN_MAX];
|
53
|
+
sprintf(wchan, "%x", (unsigned int)p->pr_wchan);
|
54
|
+
#endif
|
55
|
+
|
56
|
+
#ifdef HAVE_PROCFS_H
|
57
|
+
switch(p->pr_lwp.pr_state)
|
58
|
+
#else
|
59
|
+
switch(p->pr_state)
|
60
|
+
#endif
|
61
|
+
{
|
62
|
+
case SSLEEP:
|
63
|
+
strcpy(state, SLEEP);
|
64
|
+
break;
|
65
|
+
case SRUN:
|
66
|
+
strcpy(state, RUN);
|
67
|
+
break;
|
68
|
+
case SZOMB:
|
69
|
+
strcpy(state, ZOMBIE);
|
70
|
+
break;
|
71
|
+
case SSTOP:
|
72
|
+
strcpy(state, STOP);
|
73
|
+
break;
|
74
|
+
case SIDL:
|
75
|
+
strcpy(state, IDLE);
|
76
|
+
break;
|
77
|
+
case SONPROC:
|
78
|
+
strcpy(state, ONPROC);
|
79
|
+
break;
|
80
|
+
}
|
81
|
+
|
82
|
+
strcpy(comm, p->pr_fname);
|
83
|
+
|
84
|
+
getprusage(p->pr_pid,&pbuf); /* Get the process usage info */
|
85
|
+
|
86
|
+
return rb_struct_new(sProcStruct,
|
87
|
+
INT2FIX(p->pr_flag),
|
88
|
+
#ifdef HAVE_PROCFS_H
|
89
|
+
INT2FIX(p->pr_nlwp),
|
90
|
+
#endif
|
91
|
+
UINT2NUM(p->pr_pid),
|
92
|
+
UINT2NUM(p->pr_ppid),
|
93
|
+
#ifdef HAVE_PROCFS_H
|
94
|
+
UINT2NUM(p->pr_pgid),
|
95
|
+
#else
|
96
|
+
UINT2NUM(p->pr_pgrp),
|
97
|
+
#endif
|
98
|
+
UINT2NUM(p->pr_sid),
|
99
|
+
UINT2NUM(p->pr_uid),
|
100
|
+
UINT2NUM(p->pr_euid),
|
101
|
+
UINT2NUM(p->pr_gid),
|
102
|
+
UINT2NUM(p->pr_egid),
|
103
|
+
#ifdef HAVE_PROCFS_H
|
104
|
+
INT2FIX(p->pr_lwp.pr_pri),
|
105
|
+
INT2FIX(p->pr_lwp.pr_nice),
|
106
|
+
#else
|
107
|
+
INT2FIX(p->pr_pri),
|
108
|
+
INT2FIX(p->pr_nice),
|
109
|
+
#endif
|
110
|
+
rbTTY,
|
111
|
+
INT2FIX(p->pr_time.tv_sec),
|
112
|
+
INT2FIX(p->pr_ctime.tv_sec),
|
113
|
+
#ifdef HAVE_PROCFS_H
|
114
|
+
INT2FIX(p->pr_size * 1024),
|
115
|
+
INT2FIX(p->pr_rssize * 1024),
|
116
|
+
UINT2NUM(p->pr_lwp.pr_wchan),
|
117
|
+
#else
|
118
|
+
INT2FIX(p->pr_bysize),
|
119
|
+
INT2FIX(p->pr_rssize),
|
120
|
+
rb_str_new2(wchan),
|
121
|
+
#endif
|
122
|
+
rb_float_new(((double)p->pr_pctcpu)/0x8000*100),
|
123
|
+
rb_float_new(((double)p->pr_pctmem)/0x8000*100),
|
124
|
+
rb_str_new2(state),
|
125
|
+
rb_str_new2(p->pr_fname),
|
126
|
+
cmdline,
|
127
|
+
rb_time_new(p->pr_start.tv_sec,0),
|
128
|
+
#ifdef HAVE_PROCFS_H
|
129
|
+
INT2NUM(p->pr_lwp.pr_onpro),
|
130
|
+
#endif
|
131
|
+
rb_str_new2(comm),
|
132
|
+
INT2FIX(p->pr_argc),
|
133
|
+
v_cmd_array,
|
134
|
+
LONG2FIX(pbuf.pr_lwpid),
|
135
|
+
INT2FIX(pbuf.pr_count),
|
136
|
+
LONG2FIX(pbuf.pr_tstamp.tv_sec),
|
137
|
+
LONG2FIX(pbuf.pr_create.tv_sec),
|
138
|
+
LONG2FIX(pbuf.pr_term.tv_sec),
|
139
|
+
LONG2FIX(pbuf.pr_rtime.tv_sec),
|
140
|
+
LONG2FIX(pbuf.pr_utime.tv_sec),
|
141
|
+
LONG2FIX(pbuf.pr_stime.tv_sec),
|
142
|
+
LONG2FIX(pbuf.pr_ttime.tv_sec),
|
143
|
+
LONG2FIX(pbuf.pr_tftime.tv_sec),
|
144
|
+
LONG2FIX(pbuf.pr_dftime.tv_sec),
|
145
|
+
LONG2FIX(pbuf.pr_kftime.tv_sec),
|
146
|
+
LONG2FIX(pbuf.pr_ltime.tv_sec),
|
147
|
+
LONG2FIX(pbuf.pr_slptime.tv_sec),
|
148
|
+
LONG2FIX(pbuf.pr_wtime.tv_sec),
|
149
|
+
LONG2FIX(pbuf.pr_stoptime.tv_sec),
|
150
|
+
ULONG2NUM(pbuf.pr_minf),
|
151
|
+
ULONG2NUM(pbuf.pr_majf),
|
152
|
+
ULONG2NUM(pbuf.pr_nswap),
|
153
|
+
ULONG2NUM(pbuf.pr_inblk),
|
154
|
+
ULONG2NUM(pbuf.pr_oublk),
|
155
|
+
ULONG2NUM(pbuf.pr_msnd),
|
156
|
+
ULONG2NUM(pbuf.pr_mrcv),
|
157
|
+
ULONG2NUM(pbuf.pr_sigs),
|
158
|
+
ULONG2NUM(pbuf.pr_vctx),
|
159
|
+
ULONG2NUM(pbuf.pr_ictx),
|
160
|
+
ULONG2NUM(pbuf.pr_sysc),
|
161
|
+
ULONG2NUM(pbuf.pr_ioch)
|
162
|
+
);
|
163
|
+
}
|
164
|
+
|
165
|
+
/*
|
166
|
+
* call-seq:
|
167
|
+
* ProcTable.ps(pid=nil)
|
168
|
+
* ProcTable.ps(pid=nil){ |ps| ... }
|
169
|
+
*
|
170
|
+
* In block form, yields a ProcTableStruct for each process entry that you
|
171
|
+
* have rights to. This method returns an array of ProcTableStruct's in
|
172
|
+
* non-block form.
|
173
|
+
*
|
174
|
+
* If a +pid+ is provided, then only a single ProcTableStruct is yielded or
|
175
|
+
* returned, or nil if no process information is found for that +pid+.
|
176
|
+
*/
|
177
|
+
static VALUE proctable_ps(int argc, VALUE *argv, VALUE klass)
|
178
|
+
{
|
179
|
+
DIR *procdir;
|
180
|
+
struct dirent *procdirp;
|
181
|
+
int psdata;
|
182
|
+
char pathbuf[PATH_MAX];
|
183
|
+
|
184
|
+
char* arg;
|
185
|
+
uintptr_t addr_args;
|
186
|
+
uintptr_t* arg_vec;
|
187
|
+
size_t arg_len;
|
188
|
+
int fd, arg_count, i, pid;
|
189
|
+
|
190
|
+
VALUE v_pid;
|
191
|
+
VALUE v_ps_struct = Qnil;
|
192
|
+
VALUE v_array = Qnil;
|
193
|
+
VALUE v_cmd_array = rb_ary_new();
|
194
|
+
|
195
|
+
#ifdef HAVE_PROCFS_H
|
196
|
+
struct psinfo p;
|
197
|
+
char as_file[MAXPATHLEN];
|
198
|
+
#else
|
199
|
+
struct prpsinfo p;
|
200
|
+
#endif
|
201
|
+
|
202
|
+
rb_scan_args(argc, argv, "01", &v_pid);
|
203
|
+
|
204
|
+
if(!rb_block_given_p())
|
205
|
+
v_array = rb_ary_new();
|
206
|
+
|
207
|
+
if( (procdir = opendir( "/proc" )) == NULL )
|
208
|
+
rb_raise(cProcError,"/proc filesystem unreadable");
|
209
|
+
|
210
|
+
while( (procdirp = readdir(procdir)) != NULL )
|
211
|
+
{
|
212
|
+
/* Only look at this file if it's a proc id; that is, all numbers */
|
213
|
+
if(strtok(procdirp->d_name, "0123456789") != NULL ){ continue; }
|
214
|
+
|
215
|
+
/* If a pid is provided, only return info on that pid */
|
216
|
+
if(!NIL_P(v_pid)){
|
217
|
+
pid = NUM2INT(v_pid);
|
218
|
+
if(atoi(procdirp->d_name) != pid)
|
219
|
+
continue;
|
220
|
+
}
|
221
|
+
|
222
|
+
/* Construct path of the form /proc/proc_number */
|
223
|
+
strcpy(pathbuf, "/proc/");
|
224
|
+
strcpy(as_file, "/proc/");
|
225
|
+
strcat(pathbuf, procdirp->d_name);
|
226
|
+
strcat(as_file, procdirp->d_name);
|
227
|
+
|
228
|
+
#ifdef HAVE_PROCFS_H
|
229
|
+
strcat(pathbuf, "/psinfo"); /* Solaris 2.6+ has process info here */
|
230
|
+
strcat(as_file, "/as");
|
231
|
+
#endif
|
232
|
+
|
233
|
+
if( (psdata = open( pathbuf, O_RDONLY )) == -1 )
|
234
|
+
continue;
|
235
|
+
|
236
|
+
#ifdef HAVE_PROCFS_H
|
237
|
+
read(psdata, (void *) &p, sizeof(struct psinfo));
|
238
|
+
#else
|
239
|
+
if(ioctl(psdata, PIOCPSINFO, &p) == -1)
|
240
|
+
continue;
|
241
|
+
#endif
|
242
|
+
|
243
|
+
#ifdef HAVE_PROCFS_H
|
244
|
+
/*
|
245
|
+
* For those processes where it is possible to read /proc/xxx/as
|
246
|
+
* get the entire command line string.
|
247
|
+
*/
|
248
|
+
addr_args = p.pr_argv;
|
249
|
+
arg_count = p.pr_argc;
|
250
|
+
|
251
|
+
if((fd = open(as_file, O_RDONLY)) < 0){
|
252
|
+
/* Do nothing - you can only get info on processes you rights to */
|
253
|
+
}
|
254
|
+
else
|
255
|
+
{
|
256
|
+
arg_vec = malloc(arg_count * sizeof(uintptr_t));
|
257
|
+
|
258
|
+
/* We need this here to pick up args properly on 2.8+ */
|
259
|
+
#ifdef PR_MODEL_NATIVE
|
260
|
+
if(p.pr_dmodel == PR_MODEL_NATIVE){
|
261
|
+
(void)pread(fd, arg_vec, arg_count * sizeof (uintptr_t), addr_args);
|
262
|
+
}
|
263
|
+
else{
|
264
|
+
caddr32_t *arg_vec32 = (caddr32_t *)arg_vec;
|
265
|
+
(void)pread(fd, arg_vec32, arg_count * sizeof (caddr32_t), addr_args);
|
266
|
+
for (i = arg_count - 1; i >= 0; --i)
|
267
|
+
{
|
268
|
+
arg_vec[i] = arg_vec32[i];
|
269
|
+
}
|
270
|
+
}
|
271
|
+
#else
|
272
|
+
/* Need a better patch for 2.6 here */
|
273
|
+
(void)pread(fd, arg_vec, arg_count * sizeof (uintptr_t), addr_args);
|
274
|
+
#endif
|
275
|
+
|
276
|
+
arg_len = 16;
|
277
|
+
arg = malloc(arg_len+1);
|
278
|
+
for(i = 0; i < arg_count; i++) {
|
279
|
+
|
280
|
+
if(pread(fd, arg, arg_len, arg_vec[i]) < 0)
|
281
|
+
continue;
|
282
|
+
|
283
|
+
arg[arg_len] = '\0';
|
284
|
+
if(strlen(arg) == arg_len){
|
285
|
+
arg_len *= 2;
|
286
|
+
arg = realloc(arg, arg_len + 1);
|
287
|
+
i--;
|
288
|
+
continue;
|
289
|
+
}
|
290
|
+
rb_ary_push(v_cmd_array, rb_str_new2(arg));
|
291
|
+
}
|
292
|
+
free(arg);
|
293
|
+
free(arg_vec);
|
294
|
+
}
|
295
|
+
close(fd);
|
296
|
+
#endif
|
297
|
+
|
298
|
+
close(psdata);
|
299
|
+
v_ps_struct = proctable_getprocstruct(&p, v_cmd_array);
|
300
|
+
|
301
|
+
if(rb_block_given_p()){
|
302
|
+
rb_yield(v_ps_struct);
|
303
|
+
}
|
304
|
+
else{
|
305
|
+
rb_ary_push(v_array, v_ps_struct);
|
306
|
+
}
|
307
|
+
rb_ary_clear(v_cmd_array);
|
308
|
+
}
|
309
|
+
closedir(procdir);
|
310
|
+
|
311
|
+
/* If a process ID was provided and found, return a single struct */
|
312
|
+
if(!NIL_P(v_pid))
|
313
|
+
return v_ps_struct;
|
314
|
+
|
315
|
+
return v_array; /* nil if block was provided */
|
316
|
+
}
|
317
|
+
|
318
|
+
/*
|
319
|
+
* call-seq:
|
320
|
+
* ProcTable.fields
|
321
|
+
*
|
322
|
+
* Returns an array of fields that each ProcTableStruct will contain. This
|
323
|
+
* may be useful if you want to know in advance what fields are available
|
324
|
+
* without having to perform at least one read of the /proc table.
|
325
|
+
*/
|
326
|
+
static VALUE proctable_fields(VALUE klass){
|
327
|
+
uint_t i;
|
328
|
+
VALUE rbFarray = rb_ary_new();
|
329
|
+
|
330
|
+
for(i = 0; i < (sizeof(fields) / sizeof(fields[0])); i++)
|
331
|
+
rb_ary_push(rbFarray, rb_str_new2(fields[i]));
|
332
|
+
|
333
|
+
return rbFarray;
|
334
|
+
}
|
335
|
+
|
336
|
+
/*
|
337
|
+
* A Ruby interface for gathering process table information.
|
338
|
+
*/
|
339
|
+
void Init_proctable(){
|
340
|
+
VALUE mSys, cProcTable;
|
341
|
+
|
342
|
+
/* Modules and Classes */
|
343
|
+
mSys = rb_define_module("Sys");
|
344
|
+
cProcTable = rb_define_class_under(mSys, "ProcTable", rb_cObject);
|
345
|
+
cProcError = rb_define_class_under(mSys, "ProcTableError", rb_eStandardError);
|
346
|
+
|
347
|
+
/* Class methods */
|
348
|
+
rb_define_singleton_method(cProcTable, "fields", proctable_fields, 0);
|
349
|
+
rb_define_singleton_method(cProcTable, "ps", proctable_ps, -1);
|
350
|
+
|
351
|
+
/* Constants */
|
352
|
+
rb_define_const(cProcTable, "VERSION", rb_str_new2(SYS_PROCTABLE_VERSION));
|
353
|
+
|
354
|
+
/* Structs */
|
355
|
+
sProcStruct = rb_struct_define("ProcTableStruct","flag",
|
356
|
+
#ifdef HAVE_PROCFS_H
|
357
|
+
"nlwp",
|
358
|
+
#endif
|
359
|
+
"pid","ppid","pgid","sid","uid","euid","gid","egid","priority","nice",
|
360
|
+
"ttydev","time","ctime","size","rss","wchan","pctcpu","pctmem","state",
|
361
|
+
"fname","cmdline","start",
|
362
|
+
#ifdef HAVE_PROCFS_H
|
363
|
+
"processor",
|
364
|
+
#endif
|
365
|
+
"comm","num_args","cmd_args","lwpid","count","tstamp","create","term",
|
366
|
+
"rtime","utime","stime","ttime","tftime","dftime","kftime","ltime",
|
367
|
+
"slptime","wtime","stoptime","minf","majf","nswap","inblk","oublk",
|
368
|
+
"msnd","mrcv","sigs","vctx","ictx","sysc","ioch",NULL
|
369
|
+
);
|
370
|
+
}
|
371
|
+
|
372
|
+
#ifdef __cplusplus
|
373
|
+
}
|
374
|
+
#endif
|