sys-proctable 0.7.6 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -0
  4. data/CHANGES +165 -0
  5. data/MANIFEST +33 -41
  6. data/README +115 -135
  7. data/Rakefile +94 -0
  8. data/benchmarks/bench_ps.rb +21 -0
  9. data/doc/top.txt +5 -11
  10. data/examples/example_ps.rb +20 -0
  11. data/lib/aix/sys/proctable.rb +458 -0
  12. data/lib/darwin/sys/proctable.rb +363 -0
  13. data/lib/freebsd/sys/proctable.rb +363 -0
  14. data/lib/linux/sys/proctable.rb +314 -0
  15. data/lib/linux/sys/proctable/cgroup_entry.rb +50 -0
  16. data/lib/linux/sys/proctable/smaps.rb +118 -0
  17. data/lib/sunos/sys/proctable.rb +456 -0
  18. data/lib/sys-proctable.rb +1 -0
  19. data/lib/sys-top.rb +1 -0
  20. data/lib/sys/proctable.rb +18 -0
  21. data/lib/sys/proctable/version.rb +6 -0
  22. data/lib/sys/top.rb +28 -19
  23. data/lib/windows/sys/proctable.rb +208 -0
  24. data/spec/sys_proctable_aix_spec.rb +328 -0
  25. data/spec/sys_proctable_all_spec.rb +89 -0
  26. data/spec/sys_proctable_darwin_spec.rb +120 -0
  27. data/spec/sys_proctable_freebsd_spec.rb +210 -0
  28. data/spec/sys_proctable_linux_spec.rb +310 -0
  29. data/spec/sys_proctable_sunos_spec.rb +316 -0
  30. data/spec/sys_proctable_windows_spec.rb +317 -0
  31. data/spec/sys_top_spec.rb +51 -0
  32. data/sys-proctable.gemspec +38 -0
  33. metadata +140 -64
  34. metadata.gz.sig +0 -0
  35. data/doc/freebsd.txt +0 -90
  36. data/doc/hpux.txt +0 -77
  37. data/doc/linux.txt +0 -85
  38. data/doc/solaris.txt +0 -99
  39. data/doc/windows.txt +0 -122
  40. data/ext/extconf.rb +0 -98
  41. data/ext/sunos/sunos.c +0 -374
  42. data/ext/sunos/sunos.h +0 -177
  43. data/ext/version.h +0 -2
  44. data/test/tc_all.rb +0 -59
  45. data/test/tc_freebsd.rb +0 -45
  46. data/test/tc_hpux.rb +0 -49
  47. data/test/tc_kvm_bsd.rb +0 -31
  48. data/test/tc_linux.rb +0 -45
  49. data/test/tc_sunos.rb +0 -52
  50. data/test/tc_top.rb +0 -26
  51. data/test/tc_windows.rb +0 -40
  52. data/test/test_memleak.rb +0 -54
@@ -1,85 +0,0 @@
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)
@@ -1,99 +0,0 @@
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
@@ -1,122 +0,0 @@
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
@@ -1,98 +0,0 @@
1
- #############################################################################
2
- # Installation script for sys-proctable.
3
- #
4
- # By running this file, it is assumed that you want a C extension, and not
5
- # a pure Ruby version. If you want a pure Ruby version (and you're on a
6
- # platform for which it's supported), run install.rb instead.
7
- #############################################################################
8
- require 'mkmf'
9
- require 'fileutils'
10
-
11
- c_file = nil
12
- h_file = nil
13
- tc_file = nil
14
-
15
- ########################################################################
16
- # Ruby 1.8.3 and later mandates the use of rb_pid_t over pid_t because
17
- # some libraries define their own pid_t. So, we check for that.
18
- ########################################################################
19
- have_type('rb_pid_t', 'ruby.h')
20
-
21
- ##########################################################################
22
- # Determine appropriate source files based on platform. Also, check for
23
- # certain header files and/or libraries on some platforms.
24
- #
25
- # On FreeBSD a different source file is used if the /proc filesystem is
26
- # not found (kvm is used instead). For OpenBSD or NetBSD, the kvm
27
- # interface is always used for now.
28
- ##########################################################################
29
- case RUBY_PLATFORM
30
- when /hpux/i
31
- c_file = 'hpux/hpux.c'
32
- h_file = 'hpux/hpux.h'
33
- tc_file = 'tc_hpux'
34
- when /freebsd/i
35
- if File.exists?('/proc') && Dir['/proc/*'].length > 0
36
- c_file = 'freebsd/freebsd.c'
37
- h_file = 'freebsd/freebsd.h'
38
- tc_file = 'tc_freebsd'
39
- else
40
- have_library('kvm')
41
- have_struct_member('struct kinfo_proc', 'kp_proc', 'sys/user.h')
42
- have_struct_member('struct kinfo_proc', 'kp_eproc', 'sys/user.h')
43
- c_file = 'bsd/bsd.c'
44
- tc_file = 'tc_kvm_bsd.rb'
45
- end
46
- when /openbsd|netbsd/
47
- have_library('kvm')
48
- c_file = 'bsd/bsd.c'
49
- tc_file = 'tc_kvm_bsd.rb'
50
- when /solaris|sunos/i
51
- c_file = 'sunos/sunos.c'
52
- h_file = 'sunos/sunos.h'
53
- tc_file = 'tc_sunos'
54
- have_header('procfs.h') # false means Solaris 2.5.x
55
- when /linux/i
56
- c_file = 'linux/linux.c'
57
- h_file = 'linux/linux.h'
58
- tc_file = 'tc_linux'
59
- when /darwin/i
60
- c_file = 'darwin/darwin.c'
61
- tc_file = 'tc_darwin'
62
- when /windows|win32|cygwin|mingw|dos/i
63
- msg = 'Use the install_pure_ruby.rb script to install on MS Windows'
64
- STDERR.puts msg
65
- exit
66
- else
67
- puts 'This platform not currently supported. Exiting...'
68
- exit
69
- end
70
-
71
- #####################################################################
72
- # Move the 'windows.rb' file under 'lib/sys/' to '.orig' to prevent
73
- # mkmf from installing it during the 'make install' phase.
74
- #####################################################################
75
- if File.exists?('../lib/sys/windows.rb')
76
- File.rename('../lib/sys/windows.rb', '../lib/sys/windows.orig')
77
- end
78
-
79
- ###################
80
- # build ts_all.rb
81
- ###################
82
- test_file = '../test/ts_all.rb'
83
- File.open(test_file, 'w'){ |fh|
84
- fh.puts "require 'tc_all'"
85
- fh.puts "require '#{tc_file}'"
86
- fh.puts "require 'tc_top'"
87
- }
88
-
89
- ########################################################################
90
- # Copy or link files to current directory for create_makefile to work.
91
- ########################################################################
92
- File.delete('proctable.c') rescue nil
93
- File.delete(File.basename(h_file)) rescue nil
94
-
95
- FileUtils.cp(c_file, 'proctable.c')
96
- FileUtils.cp(h_file, File.basename(h_file)) if h_file
97
-
98
- create_makefile('sys/proctable')
@@ -1,374 +0,0 @@
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