sigar 0.7.0

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.
Files changed (66) hide show
  1. data/README +2 -0
  2. data/Rakefile +105 -0
  3. data/bindings/SigarBuild.pm +310 -0
  4. data/bindings/SigarWrapper.pm +2978 -0
  5. data/bindings/ruby/examples/arp.rb +24 -0
  6. data/bindings/ruby/examples/cpu_info.rb +35 -0
  7. data/bindings/ruby/examples/df.rb +49 -0
  8. data/bindings/ruby/examples/free.rb +36 -0
  9. data/bindings/ruby/examples/ifconfig.rb +101 -0
  10. data/bindings/ruby/examples/logging.rb +58 -0
  11. data/bindings/ruby/examples/net_info.rb +31 -0
  12. data/bindings/ruby/examples/netstat.rb +71 -0
  13. data/bindings/ruby/examples/pargs.rb +35 -0
  14. data/bindings/ruby/examples/penv.rb +31 -0
  15. data/bindings/ruby/examples/route.rb +48 -0
  16. data/bindings/ruby/examples/version.rb +40 -0
  17. data/bindings/ruby/examples/who.rb +30 -0
  18. data/bindings/ruby/extconf.rb +128 -0
  19. data/bindings/ruby/rbsigar.c +888 -0
  20. data/bindings/ruby/test/cpu_test.rb +40 -0
  21. data/bindings/ruby/test/file_system_test.rb +43 -0
  22. data/bindings/ruby/test/helper.rb +57 -0
  23. data/bindings/ruby/test/loadavg_test.rb +30 -0
  24. data/bindings/ruby/test/mem_test.rb +45 -0
  25. data/bindings/ruby/test/swap_test.rb +36 -0
  26. data/bindings/ruby/test/uptime_test.rb +26 -0
  27. data/include/sigar.h +939 -0
  28. data/include/sigar_fileinfo.h +157 -0
  29. data/include/sigar_format.h +65 -0
  30. data/include/sigar_getline.h +18 -0
  31. data/include/sigar_log.h +80 -0
  32. data/include/sigar_private.h +422 -0
  33. data/include/sigar_ptql.h +53 -0
  34. data/include/sigar_util.h +191 -0
  35. data/src/os/aix/aix_sigar.c +2151 -0
  36. data/src/os/aix/sigar_os.h +73 -0
  37. data/src/os/darwin/Info.plist.in +27 -0
  38. data/src/os/darwin/darwin_sigar.c +3709 -0
  39. data/src/os/darwin/sigar_os.h +80 -0
  40. data/src/os/hpux/hpux_sigar.c +1342 -0
  41. data/src/os/hpux/sigar_os.h +49 -0
  42. data/src/os/linux/linux_sigar.c +2782 -0
  43. data/src/os/linux/sigar_os.h +82 -0
  44. data/src/os/solaris/get_mib2.c +321 -0
  45. data/src/os/solaris/get_mib2.h +127 -0
  46. data/src/os/solaris/kstats.c +181 -0
  47. data/src/os/solaris/procfs.c +97 -0
  48. data/src/os/solaris/sigar_os.h +224 -0
  49. data/src/os/solaris/solaris_sigar.c +2717 -0
  50. data/src/os/win32/peb.c +212 -0
  51. data/src/os/win32/sigar.rc.in +40 -0
  52. data/src/os/win32/sigar_os.h +653 -0
  53. data/src/os/win32/sigar_pdh.h +47 -0
  54. data/src/os/win32/win32_sigar.c +3911 -0
  55. data/src/sigar.c +2428 -0
  56. data/src/sigar_cache.c +179 -0
  57. data/src/sigar_fileinfo.c +815 -0
  58. data/src/sigar_format.c +696 -0
  59. data/src/sigar_getline.c +1849 -0
  60. data/src/sigar_ptql.c +1967 -0
  61. data/src/sigar_signal.c +216 -0
  62. data/src/sigar_util.c +1060 -0
  63. data/src/sigar_version.c.in +22 -0
  64. data/src/sigar_version_autoconf.c.in +22 -0
  65. data/version.properties +11 -0
  66. metadata +131 -0
data/README ADDED
@@ -0,0 +1,2 @@
1
+ Visit the SIGAR Wiki for documentation, bugs, support, etc.:
2
+ http://sigar.hyperic.com/
@@ -0,0 +1,105 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/testtask'
4
+
5
+ #so we can: ssh host rake -f $hudson_workspace/sigar/Rakefile
6
+ Dir.chdir(File.dirname(__FILE__))
7
+
8
+ props = {}
9
+ File.open("version.properties").each { |line|
10
+ next if line =~ /^#/
11
+ line.chomp!
12
+ line.strip!
13
+ next if line.empty?
14
+ key,val = line.split('=')
15
+ props[key] = val
16
+ }
17
+
18
+ GEM = props['project.name']
19
+ MAKE = (/mswin/ =~ RUBY_PLATFORM) ? 'nmake' : 'make'
20
+
21
+ spec = Gem::Specification.new do |s|
22
+ s.name = GEM
23
+ # s.version = props['version.major'] + '.' + props['version.minor'] + '.' + props['version.maint']
24
+ # '0.7.x' until the sigar-1.7.0 release
25
+ s.version = '0' + '.' + props['version.minor'] + '.' + '0'
26
+ s.summary = props['project.summary']
27
+ s.description = s.summary
28
+ s.author = props['project.author']
29
+ s.email = props['project.email']
30
+ s.homepage = props['project.homepage']
31
+ s.platform = Gem::Platform::RUBY
32
+ s.has_rdoc = false
33
+ s.extensions = 'bindings/ruby/extconf.rb'
34
+ s.files =
35
+ %w(README Rakefile version.properties) +
36
+ %w(bindings/SigarWrapper.pm bindings/SigarBuild.pm) +
37
+ Dir.glob("bindings/ruby/**/*") +
38
+ Dir.glob("include/*.h") +
39
+ Dir.glob("src/**/*.[ch]") +
40
+ Dir.glob("src/**/*.in")
41
+ end
42
+
43
+ Rake::GemPackageTask.new(spec) do |pkg|
44
+ pkg.gem_spec = spec
45
+ end
46
+
47
+ task :default => :test
48
+
49
+ def in_ext()
50
+ ext = 'bindings/ruby'
51
+ Dir.chdir(ext) if File.directory? ext
52
+ end
53
+
54
+ desc 'Build sigar extension'
55
+ task :build do
56
+ in_ext()
57
+ unless File.exists? "Makefile"
58
+ unless system("ruby extconf.rb")
59
+ STDERR.puts "Failed to configure"
60
+ break
61
+ end
62
+ end
63
+ unless system(MAKE)
64
+ STDERR.puts 'Failed to ' + MAKE
65
+ break
66
+ end
67
+ end
68
+
69
+ Rake::TestTask.new do |t|
70
+ t.pattern = 'test/*_test.rb'
71
+ t.libs << "."
72
+ end
73
+
74
+ task :test => [:build] do
75
+ in_ext()
76
+ end
77
+
78
+ desc 'Clean sigar extension'
79
+ task :clean do
80
+ in_ext()
81
+ system(MAKE + ' clean') if File.exists? "Makefile"
82
+ end
83
+
84
+ desc 'Dist Clean sigar extension'
85
+ task :distclean do
86
+ in_ext()
87
+ system(MAKE + ' distclean') if File.exists? "Makefile"
88
+ end
89
+
90
+ desc 'Run sigar examples (test)'
91
+ task :examples => [:build] do
92
+ in_ext()
93
+ Dir["examples/*.rb"].each do |file|
94
+ cmd = "ruby -I. #{file}"
95
+ print cmd + "\n"
96
+ system(cmd)
97
+ end
98
+ end
99
+
100
+ desc "create a gemspec file"
101
+ task :make_spec do
102
+ File.open("#{GEM}.gemspec", "w") do |file|
103
+ file.puts spec.to_ruby
104
+ end
105
+ end
@@ -0,0 +1,310 @@
1
+ #
2
+ # Copyright (c) 2009 Hyperic, Inc.
3
+ # Copyright (c) 2009 SpringSource, Inc.
4
+ # Copyright (c) 2009 VMware, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ package SigarBuild;
20
+
21
+ use strict;
22
+ use Config;
23
+ use Exporter;
24
+ use File::Basename qw(basename);
25
+ use File::Copy qw(copy);
26
+ use File::Spec ();
27
+ use POSIX ();
28
+
29
+ use vars qw(@ISA @EXPORT);
30
+ @ISA = qw(Exporter);
31
+ @EXPORT = qw(cppflags ldflags libs os src inline_src version_file);
32
+
33
+ sub archname {
34
+ my $os = lc $^O;
35
+ my $vers = $Config{osvers};
36
+ my $arch = $Config{archname};
37
+
38
+ if ($os =~ /win32/) {
39
+ return 'x86-winnt';
40
+ }
41
+ elsif ($os =~ /linux/) {
42
+ if ($arch =~ /_64/) {
43
+ return 'amd64-linux';
44
+ }
45
+ else {
46
+ return 'x86-linux';
47
+ }
48
+ }
49
+ elsif ($os =~ /hpux/) {
50
+ if ($vers =~ /11\./) {
51
+ return 'pa-hpux-11';
52
+ }
53
+ }
54
+ elsif ($os =~ /aix/) {
55
+ return 'ppc-aix-5';
56
+ }
57
+ elsif ($os =~ /solaris/) {
58
+ if ($arch =~ /sun4/) {
59
+ return 'sparc-solaris';
60
+ }
61
+ elsif ($arch =~ /.86/) {
62
+ return 'x86-solaris';
63
+ }
64
+ }
65
+ elsif ($os =~ /darwin/) {
66
+ return 'universal-macosx';
67
+ }
68
+ elsif ($os =~ /freebsd/) {
69
+ if ($arch =~ /.86/) {
70
+ if($vers =~ /6\../ ) {
71
+ return 'x86-freebsd-6';
72
+ }
73
+ }
74
+ elsif ($arch =~ /amd64/) {
75
+ if ($vers =~ /6\../ ) {
76
+ return 'amd64-freebsd-6';
77
+ }
78
+ }
79
+ }
80
+
81
+ return '';
82
+ }
83
+
84
+ sub flags {
85
+ my $os = lc $^O;
86
+ my $is_win32 = 0;
87
+ my (@cppflags, @ldflags, @libs);
88
+ if ($os =~ /(win32)/) {
89
+ $os = $1;
90
+ $is_win32 = 1;
91
+ @cppflags = ('-DWIN32', '-D_CRT_SECURE_NO_DEPRECATE');
92
+ @libs = qw(kernel32 user32 advapi32 ws2_32 netapi32 shell32 pdh version comsupp wbemuuid);
93
+ }
94
+ elsif ($os =~ /(linux)/) {
95
+ $os = $1;
96
+ }
97
+ elsif ($os =~ /(hpux)/) {
98
+ $os = $1;
99
+ @libs = qw(nsl nm);
100
+ }
101
+ elsif ($os =~ /(aix)/) {
102
+ $os = $1;
103
+ @libs = qw(odm cfg perfstat);
104
+ }
105
+ elsif ($os =~ /(solaris)/) {
106
+ $os = $1;
107
+ @libs = qw(nsl socket kstat);
108
+ }
109
+ elsif ($os =~ /(darwin)/) {
110
+ $os = $1;
111
+ my(@sdks) = reverse sort </Developer/SDKs/MacOSX10.*.sdk>;
112
+ my $sdk;
113
+ if (@sdks == 0) {
114
+ die
115
+ "Xcode Developer Tools not installed\n".
116
+ "Download from http://developer.apple.com/technology/xcode.html";
117
+ }
118
+ else {
119
+ #print "Available SDKs...\n(*) " . join("\n ", @sdks) . "\n";
120
+ $sdk = $sdks[0];
121
+ }
122
+ @cppflags = ('-DDARWIN',
123
+ "-I/Developer/Headers/FlatCarbon -isysroot $sdk");
124
+ @ldflags = ("-Wl,-syslibroot,$sdk",
125
+ '-framework CoreServices',
126
+ '-framework IOKit');
127
+ if (-e "/usr/local/libproc.h") {
128
+ push @cppflags, '-DDARWIN_HAS_LIBPROC_H';
129
+ }
130
+ }
131
+ elsif ($os =~ /bsd/) {
132
+ $os = 'darwin';
133
+ @libs = qw(kvm);
134
+ }
135
+
136
+ push @cppflags,
137
+ '-I../../include',
138
+ "-I../../src/os/$os";
139
+
140
+ unless ($is_win32) {
141
+ push @cppflags, '-U_FILE_OFFSET_BITS';
142
+ }
143
+
144
+ my(@src) = (<../../src/*.c>, <../../src/os/$os/*.c>, <../../src/os/$os/*.cpp>);
145
+
146
+ return {
147
+ is_win32 => $is_win32,
148
+ os => $os,
149
+ libs => \@libs,
150
+ cppflags => \@cppflags,
151
+ ldflags => \@ldflags,
152
+ src => \@src,
153
+ };
154
+ }
155
+
156
+ #perl -Mlib=.. -MSigarBuild -e cppflags
157
+ sub cppflags {
158
+ print join ' ', @{ flags()->{cppflags} };
159
+ }
160
+
161
+ sub ldflags {
162
+ print join ' ', @{ flags()->{ldflags} };
163
+ }
164
+
165
+ sub libs {
166
+ print join ' ', @{ flags()->{libs} };
167
+ }
168
+
169
+ sub os {
170
+ print flags()->{os};
171
+ }
172
+
173
+ sub src {
174
+ print join ' ', @{ flags()->{src} };
175
+ }
176
+
177
+ sub inline_src {
178
+ my $stdout = @_ ? 0 : 1;
179
+ my $flags = shift || flags();
180
+ my $src = $flags->{src};
181
+ my $dir = $flags->{build_dir} || $ARGV[0];
182
+ my(@files);
183
+ #unlink symlinks incase of nfs shared dir...
184
+ for my $file (grep { -l } <*.c>) {
185
+ unlink $file;
186
+ }
187
+ for my $file (@$src) {
188
+ my $cf = basename $file;
189
+ #sigar.c -> libsigar.c else
190
+ #sigar.o and perl Sigar.o clash on case insensitive filesystems
191
+ $cf = 'libsigar.c' if $cf eq 'sigar.c';
192
+ if ($dir) {
193
+ $cf = join '/', $dir, $cf;
194
+ $file = File::Spec->rel2abs($file);
195
+ }
196
+ push @files, $cf;
197
+ if ($flags->{is_win32}) {
198
+ copy($file, $cf);
199
+ }
200
+ else {
201
+ symlink($file, $cf) unless -e $cf;
202
+ }
203
+ }
204
+ if ($stdout) {
205
+ print join ' ', @files;
206
+ }
207
+ else {
208
+ return @files;
209
+ }
210
+ }
211
+
212
+ sub scm_revision {
213
+ my $rev;
214
+ $rev = `git rev-parse --short HEAD`;
215
+ if ($rev) {
216
+ chomp $rev;
217
+ }
218
+ else {
219
+ $rev = "exported";
220
+ }
221
+ return $rev;
222
+ }
223
+
224
+ sub build_date {
225
+ return POSIX::strftime("%m/%d/%Y %I:%M %p", localtime);
226
+ }
227
+
228
+ sub find_file {
229
+ my $file = shift;
230
+ for my $dir (qw(../.. .. .)) {
231
+ my $pfile = "$dir/$file";
232
+ return $pfile if -e $pfile;
233
+ }
234
+ return $file;
235
+ }
236
+
237
+ sub version_properties {
238
+ my $props = {};
239
+ my $file = $_[0] || find_file('version.properties');
240
+ open my $fh, $file or die "open $file: $!";
241
+ while (<$fh>) {
242
+ chomp;
243
+ my($key,$val) = split '=';
244
+ next unless $key and defined $val;
245
+ $props->{$key} = $val;
246
+ }
247
+ close $fh;
248
+
249
+ $props->{'scm.revision'} = scm_revision();
250
+
251
+ $props->{'build.date'} = build_date();
252
+
253
+ $props->{'version'} =
254
+ join '.', map $props->{"version.$_"}, qw(major minor maint);
255
+
256
+ $props->{'version.build'} = $ENV{BUILD_NUMBER} || '0';
257
+
258
+ $props->{'version.string'} =
259
+ join '.', $props->{'version'}, $props->{'version.build'};
260
+
261
+ return $props;
262
+ }
263
+
264
+ sub version_file {
265
+ local $_;
266
+ my($source, $dest, %filters);
267
+ my(@args) = @_ ? @_ : @ARGV;
268
+ for (@args) {
269
+ if (/=/) {
270
+ my($key,$val) = split '=', $_, 2;
271
+ $filters{$key} = $val;
272
+ }
273
+ else {
274
+ if ($source) {
275
+ $dest = $_;
276
+ }
277
+ else {
278
+ $source = $_;
279
+ }
280
+ }
281
+ }
282
+ unless ($source) {
283
+ $dest = 'sigar_version.c';
284
+ $source = find_file("src/$dest.in");
285
+ }
286
+ my $props = version_properties();
287
+ while (my($key,$val) = each %$props) {
288
+ $key = uc $key;
289
+ $key =~ s/\./_/;
290
+ $filters{$key} = $val;
291
+ }
292
+ my $re = join '|', keys %filters;
293
+ open my $in, $source or die "open $source: $!";
294
+ my $out;
295
+ if ($dest) {
296
+ open $out, '>', $dest or die "open $dest: $!";
297
+ }
298
+ else {
299
+ $out = \*STDOUT;
300
+ }
301
+ while (<$in>) {
302
+ s/\@\@($re)\@\@/$filters{$1}/go;
303
+ print $out $_;
304
+ }
305
+ close $in;
306
+ close $out if $dest;
307
+ }
308
+
309
+ 1;
310
+ __END__
@@ -0,0 +1,2978 @@
1
+ #
2
+ # Copyright (c) 2007-2009 Hyperic, Inc.
3
+ # Copyright (c) 2009 SpringSource, Inc.
4
+ # Copyright (c) 2009-2010 VMware, Inc.
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ #extension source generator for all bindings
20
+ package SigarWrapper;
21
+
22
+ use strict;
23
+ use Cwd;
24
+ use Exporter;
25
+ use File::Path;
26
+ use IO::File ();
27
+
28
+ use vars qw(@ISA @EXPORT);
29
+ @ISA = qw(Exporter);
30
+ @EXPORT = qw(generate);
31
+
32
+ my %platforms = (
33
+ A => "AIX",
34
+ D => "Darwin",
35
+ F => "FreeBSD",
36
+ H => "HPUX",
37
+ L => "Linux",
38
+ S => "Solaris",
39
+ W => "Win32",
40
+ );
41
+
42
+ my %has_name_arg = map { $_, 1 } qw(FileSystemUsage DiskUsage
43
+ FileAttrs DirStat DirUsage
44
+ NetInterfaceConfig NetInterfaceStat);
45
+
46
+ my %proc_no_arg = map { $_, 1 } qw(stat);
47
+
48
+ my %get_not_impl = map { $_, 1 } qw(net_address net_route net_connection net_stat cpu_perc
49
+ arp who cpu_info file_system); #list funcs only
50
+
51
+ sub supported_platforms {
52
+ my $p = shift;
53
+ return 'Undocumented' unless $p;
54
+ if ($p eq '*') {
55
+ return 'All';
56
+ }
57
+
58
+ my @platforms;
59
+ for (split //, $p) {
60
+ push @platforms, $platforms{$_};
61
+ }
62
+
63
+ return join ", ", @platforms;
64
+ }
65
+
66
+ sub hash {
67
+ return unpack("%32C*", shift) % 65535;
68
+ }
69
+
70
+ my $nfs_v2 = [
71
+ {
72
+ name => 'null', type => 'Long',
73
+ },
74
+ {
75
+ name => 'getattr', type => 'Long',
76
+ },
77
+ {
78
+ name => 'setattr', type => 'Long',
79
+ },
80
+ {
81
+ name => 'root', type => 'Long',
82
+ },
83
+ {
84
+ name => 'lookup', type => 'Long',
85
+ },
86
+ {
87
+ name => 'readlink', type => 'Long',
88
+ },
89
+ {
90
+ name => 'read', type => 'Long',
91
+ },
92
+ {
93
+ name => 'writecache', type => 'Long',
94
+ },
95
+ {
96
+ name => 'write', type => 'Long',
97
+ },
98
+ {
99
+ name => 'create', type => 'Long',
100
+ },
101
+ {
102
+ name => 'remove', type => 'Long',
103
+ },
104
+ {
105
+ name => 'rename', type => 'Long',
106
+ },
107
+ {
108
+ name => 'link', type => 'Long',
109
+ },
110
+ {
111
+ name => 'symlink', type => 'Long',
112
+ },
113
+ {
114
+ name => 'mkdir', type => 'Long',
115
+ },
116
+ {
117
+ name => 'rmdir', type => 'Long',
118
+ },
119
+ {
120
+ name => 'readdir', type => 'Long',
121
+ },
122
+ {
123
+ name => 'fsstat', type => 'Long',
124
+ },
125
+ ];
126
+
127
+ my $nfs_v3 = [
128
+ {
129
+ name => 'null', type => 'Long',
130
+ },
131
+ {
132
+ name => 'getattr', type => 'Long',
133
+ },
134
+ {
135
+ name => 'setattr', type => 'Long',
136
+ },
137
+ {
138
+ name => 'lookup', type => 'Long',
139
+ },
140
+ {
141
+ name => 'access', type => 'Long',
142
+ },
143
+ {
144
+ name => 'readlink', type => 'Long',
145
+ },
146
+ {
147
+ name => 'read', type => 'Long',
148
+ },
149
+ {
150
+ name => 'write', type => 'Long',
151
+ },
152
+ {
153
+ name => 'create', type => 'Long',
154
+ },
155
+ {
156
+ name => 'mkdir', type => 'Long',
157
+ },
158
+ {
159
+ name => 'symlink', type => 'Long',
160
+ },
161
+ {
162
+ name => 'mknod', type => 'Long',
163
+ },
164
+ {
165
+ name => 'remove', type => 'Long',
166
+ },
167
+ {
168
+ name => 'rmdir', type => 'Long',
169
+ },
170
+ {
171
+ name => 'rename', type => 'Long',
172
+ },
173
+ {
174
+ name => 'link', type => 'Long',
175
+ },
176
+ {
177
+ name => 'readdir', type => 'Long',
178
+ },
179
+ {
180
+ name => 'readdirplus', type => 'Long',
181
+ },
182
+ {
183
+ name => 'fsstat', type => 'Long',
184
+ },
185
+ {
186
+ name => 'fsinfo', type => 'Long',
187
+ },
188
+ {
189
+ name => 'pathconf', type => 'Long',
190
+ },
191
+ {
192
+ name => 'commit', type => 'Long',
193
+ },
194
+ ];
195
+
196
+ use vars qw(%classes %cmds);
197
+
198
+ %classes = (
199
+ Mem => [
200
+ {
201
+ name => 'total', type => 'Long',
202
+ desc => 'Total system memory',
203
+ plat => '*',
204
+ cmd => {
205
+ AIX => 'lsattr -El sys0 -a realmem',
206
+ Darwin => '',
207
+ FreeBSD => '',
208
+ HPUX => '',
209
+ Linux => 'free',
210
+ Solaris => '',
211
+ Win32 => 'taskman',
212
+ },
213
+ },
214
+ {
215
+ name => 'ram', type => 'Long',
216
+ desc => 'System Random Access Memory (in MB)',
217
+ plat => '*',
218
+ cmd => {
219
+ AIX => 'lsattr -El sys0 -a realmem',
220
+ Darwin => '',
221
+ FreeBSD => '',
222
+ HPUX => '',
223
+ Linux => 'cat /proc/mtrr | head -1',
224
+ Solaris => '',
225
+ Win32 => '',
226
+ },
227
+ },
228
+ {
229
+ name => 'used', type => 'Long',
230
+ desc => 'Total used system memory',
231
+ plat => '*',
232
+ cmd => {
233
+ AIX => '',
234
+ Darwin => '',
235
+ FreeBSD => '',
236
+ HPUX => '',
237
+ Linux => 'free',
238
+ Solaris => '',
239
+ Win32 => 'taskman',
240
+ },
241
+ },
242
+ {
243
+ name => 'free', type => 'Long',
244
+ desc => 'Total free system memory (e.g. Linux plus cached)',
245
+ plat => '*',
246
+ cmd => {
247
+ AIX => '',
248
+ Darwin => '',
249
+ FreeBSD => '',
250
+ HPUX => '',
251
+ Linux => 'free',
252
+ Solaris => '',
253
+ Win32 => 'taskman',
254
+ },
255
+ },
256
+ {
257
+ name => 'actual_used', type => 'Long',
258
+ desc => 'Actual total used system memory (e.g. Linux minus buffers)',
259
+ plat => '*',
260
+ cmd => {
261
+ AIX => '',
262
+ Darwin => '',
263
+ FreeBSD => '',
264
+ HPUX => '',
265
+ Linux => 'free',
266
+ Solaris => '',
267
+ Win32 => 'taskman',
268
+ },
269
+ },
270
+ {
271
+ name => 'actual_free', type => 'Long',
272
+ desc => 'Actual total free system memory',
273
+ plat => '*',
274
+ cmd => {
275
+ AIX => '',
276
+ Darwin => '',
277
+ FreeBSD => '',
278
+ HPUX => '',
279
+ Linux => 'free',
280
+ Solaris => '',
281
+ Win32 => 'taskman',
282
+ },
283
+ },
284
+ {
285
+ name => 'used_percent', type => 'Double',
286
+ desc => 'Percent total used system memory',
287
+ plat => '*',
288
+ cmd => {
289
+ AIX => '',
290
+ Darwin => '',
291
+ FreeBSD => '',
292
+ HPUX => '',
293
+ Linux => 'free',
294
+ Solaris => '',
295
+ Win32 => 'taskman',
296
+ },
297
+ },
298
+ {
299
+ name => 'free_percent', type => 'Double',
300
+ desc => 'Percent total free system memory',
301
+ plat => '*',
302
+ cmd => {
303
+ AIX => '',
304
+ Darwin => '',
305
+ FreeBSD => '',
306
+ HPUX => '',
307
+ Linux => 'free',
308
+ Solaris => '',
309
+ Win32 => 'taskman',
310
+ },
311
+ },
312
+ ],
313
+ Swap => [
314
+ {
315
+ name => 'total', type => 'Long',
316
+ desc => 'Total system swap',
317
+ plat => '*',
318
+ cmd => {
319
+ AIX => 'lsps -s',
320
+ Darwin => 'sysctl vm.swapusage',
321
+ FreeBSD => '',
322
+ HPUX => '',
323
+ Linux => 'free',
324
+ Solaris => 'swap -s',
325
+ Win32 => '',
326
+ },
327
+ },
328
+ {
329
+ name => 'used', type => 'Long',
330
+ desc => 'Total used system swap',
331
+ plat => '*',
332
+ cmd => {
333
+ AIX => 'lsps -s',
334
+ Darwin => '',
335
+ FreeBSD => '',
336
+ HPUX => '',
337
+ Linux => 'free',
338
+ Solaris => 'swap -s',
339
+ Win32 => '',
340
+ },
341
+ },
342
+ {
343
+ name => 'free', type => 'Long',
344
+ desc => 'Total free system swap',
345
+ plat => '*',
346
+ cmd => {
347
+ AIX => '',
348
+ Darwin => '',
349
+ FreeBSD => '',
350
+ HPUX => '',
351
+ Linux => 'free',
352
+ Solaris => 'swap -s',
353
+ Win32 => '',
354
+ },
355
+ },
356
+ {
357
+ name => 'page_in', type => 'Long',
358
+ desc => 'Pages in',
359
+ plat => '*',
360
+ cmd => {
361
+ AIX => '',
362
+ Darwin => '',
363
+ FreeBSD => '',
364
+ HPUX => '',
365
+ Linux => 'vmstat',
366
+ Solaris => 'vmstat',
367
+ Win32 => '',
368
+ },
369
+ },
370
+ {
371
+ name => 'page_out', type => 'Long',
372
+ desc => 'Pages out',
373
+ plat => '*',
374
+ cmd => {
375
+ AIX => '',
376
+ Darwin => '',
377
+ FreeBSD => '',
378
+ HPUX => '',
379
+ Linux => 'vmstat',
380
+ Solaris => 'vmstat',
381
+ Win32 => '',
382
+ },
383
+ },
384
+ ],
385
+ Cpu => [
386
+ {
387
+ name => 'user', type => 'Long',
388
+ desc => 'Total system cpu user time',
389
+ plat => '*'
390
+ },
391
+ {
392
+ name => 'sys', type => 'Long',
393
+ desc => 'Total system cpu kernel time',
394
+ plat => '*'
395
+ },
396
+ {
397
+ name => 'nice', type => 'Long',
398
+ desc => 'Total system cpu nice time',
399
+ plat => 'DFHL'
400
+ },
401
+ {
402
+ name => 'idle', type => 'Long',
403
+ desc => 'Total system cpu idle time',
404
+ plat => '*'
405
+ },
406
+ {
407
+ name => 'wait', type => 'Long',
408
+ desc => 'Total system cpu io wait time',
409
+ plat => 'ALHS'
410
+ },
411
+ {
412
+ name => 'irq', type => 'Long',
413
+ desc => 'Total system cpu time servicing interrupts',
414
+ plat => 'FLHW'
415
+ },
416
+ {
417
+ name => 'soft_irq', type => 'Long',
418
+ desc => 'Total system cpu time servicing softirqs',
419
+ plat => 'L'
420
+ },
421
+ {
422
+ name => 'stolen', type => 'Long',
423
+ desc => 'Total system cpu involuntary wait time',
424
+ plat => 'L'
425
+ },
426
+ {
427
+ name => 'total', type => 'Long',
428
+ desc => 'Total system cpu time',
429
+ plat => '*'
430
+ },
431
+ ],
432
+ CpuPerc => [
433
+ {
434
+ name => 'user', type => 'Double',
435
+ desc => 'Percent system cpu user time',
436
+ plat => '*'
437
+ },
438
+ {
439
+ name => 'sys', type => 'Double',
440
+ desc => 'Percent system cpu kernel time',
441
+ plat => '*'
442
+ },
443
+ {
444
+ name => 'nice', type => 'Double',
445
+ desc => 'Percent system cpu nice time',
446
+ plat => 'DFHL'
447
+ },
448
+ {
449
+ name => 'idle', type => 'Double',
450
+ desc => 'Percent system cpu idle time',
451
+ plat => '*'
452
+ },
453
+ {
454
+ name => 'wait', type => 'Double',
455
+ desc => 'Percent system cpu io wait time',
456
+ plat => 'ALHS'
457
+ },
458
+ {
459
+ name => 'irq', type => 'Double',
460
+ desc => 'Percent system cpu time servicing interrupts',
461
+ plat => 'FLHW'
462
+ },
463
+ {
464
+ name => 'soft_irq', type => 'Double',
465
+ desc => 'Percent system cpu time servicing softirqs',
466
+ plat => 'L'
467
+ },
468
+ {
469
+ name => 'stolen', type => 'Double',
470
+ desc => 'Percent system cpu involuntary wait time',
471
+ plat => 'L'
472
+ },
473
+ {
474
+ name => 'combined', type => 'Double',
475
+ desc => 'Sum of User + Sys + Nice + Wait',
476
+ plat => '*'
477
+ },
478
+ ],
479
+ CpuInfo => [
480
+ {
481
+ name => 'vendor', type => 'String',
482
+ desc => 'CPU vendor id',
483
+ plat => '*'
484
+ },
485
+ {
486
+ name => 'model', type => 'String',
487
+ desc => 'CPU model',
488
+ plat => '*'
489
+ },
490
+ {
491
+ name => 'mhz', type => 'Int',
492
+ desc => 'Current CPU speed',
493
+ plat => '*'
494
+ },
495
+ {
496
+ name => 'mhz_max', type => 'Int',
497
+ desc => 'Maximum CPU speed',
498
+ plat => 'DL'
499
+ },
500
+ {
501
+ name => 'mhz_min', type => 'Int',
502
+ desc => 'Maximum CPU speed',
503
+ plat => 'DL'
504
+ },
505
+ {
506
+ name => 'cache_size', type => 'Long',
507
+ desc => 'CPU cache size',
508
+ plat => 'ADL'
509
+ },
510
+ {
511
+ name => 'total_cores', type => 'Int',
512
+ desc => 'Total CPU cores (logical)',
513
+ },
514
+ {
515
+ name => 'total_sockets', type => 'Int',
516
+ desc => 'Total CPU sockets (physical)',
517
+ },
518
+ {
519
+ name => 'cores_per_socket', type => 'Int',
520
+ desc => 'Number of CPU cores per CPU socket',
521
+ },
522
+ ],
523
+ Uptime => [
524
+ {
525
+ name => 'uptime', type => 'Double',
526
+ desc => 'Time since machine started in seconds',
527
+ plat => '*'
528
+ },
529
+ ],
530
+ ProcMem => [
531
+ {
532
+ name => 'size', type => 'Long',
533
+ desc => 'Total process virtual memory',
534
+ plat => '*'
535
+ },
536
+ {
537
+ name => 'resident', type => 'Long',
538
+ desc => 'Total process resident memory',
539
+ plat => '*'
540
+ },
541
+ {
542
+ name => 'share', type => 'Long',
543
+ desc => 'Total process shared memory',
544
+ plat => 'AHLS'
545
+ },
546
+ {
547
+ name => 'minor_faults', type => 'Long',
548
+ desc => 'non i/o page faults',
549
+ plat => 'AHLS'
550
+ },
551
+ {
552
+ name => 'major_faults', type => 'Long',
553
+ desc => 'i/o page faults',
554
+ plat => 'AHLS'
555
+ },
556
+ {
557
+ name => 'page_faults', type => 'Long',
558
+ desc => 'Total number of page faults',
559
+ plat => 'ADHLSW'
560
+ },
561
+ ],
562
+ ProcCred => [
563
+ {
564
+ name => 'uid', type => 'Long',
565
+ desc => 'Process user id',
566
+ plat => 'ADFHLS'
567
+ },
568
+ {
569
+ name => 'gid', type => 'Long',
570
+ desc => 'Process group id',
571
+ plat => 'ADFHLS'
572
+ },
573
+ {
574
+ name => 'euid', type => 'Long',
575
+ desc => 'Process effective user id',
576
+ plat => 'ADFHLS'
577
+ },
578
+ {
579
+ name => 'egid', type => 'Long',
580
+ desc => 'Process effective group id',
581
+ plat => 'ADFHLS'
582
+ },
583
+ ],
584
+ ProcCredName => [
585
+ {
586
+ name => 'user', type => 'String',
587
+ desc => 'Process owner user name',
588
+ plat => '*'
589
+ },
590
+ {
591
+ name => 'group', type => 'String',
592
+ desc => 'Process owner group name',
593
+ plat => '*'
594
+ },
595
+ ],
596
+ ProcTime => [
597
+ {
598
+ name => 'start_time', type => 'Long',
599
+ desc => 'Time process was started in seconds',
600
+ plat => '*'
601
+ },
602
+ {
603
+ name => 'user', type => 'Long',
604
+ desc => 'Process cpu user time',
605
+ plat => '*'
606
+ },
607
+ {
608
+ name => 'sys', type => 'Long',
609
+ desc => 'Process cpu kernel time',
610
+ plat => '*'
611
+ },
612
+ {
613
+ name => 'total', type => 'Long',
614
+ desc => 'Process cpu time (sum of User and Sys)',
615
+ plat => '*'
616
+ },
617
+ ],
618
+ ProcCpu => [
619
+ {
620
+ name => 'percent', type => 'Double',
621
+ desc => 'Process cpu usage',
622
+ plat => '*'
623
+ },
624
+ {
625
+ name => 'last_time', type => 'Long',
626
+ desc => '',
627
+ plat => '*'
628
+ },
629
+ ],
630
+ ProcState => [
631
+ {
632
+ name => 'state', type => 'Char',
633
+ desc => 'Process state (Running, Zombie, etc.)',
634
+ plat => '*'
635
+ },
636
+ {
637
+ name => 'name', type => 'String',
638
+ desc => 'Name of the process program',
639
+ plat => '*'
640
+ },
641
+ {
642
+ name => 'ppid', type => 'Long',
643
+ desc => 'Process parent process id',
644
+ plat => '*'
645
+ },
646
+ {
647
+ name => 'tty', type => 'Int',
648
+ desc => 'Device number of rocess controling terminal',
649
+ plat => 'AHLS'
650
+ },
651
+ {
652
+ name => 'nice', type => 'Int',
653
+ desc => 'Nice value of process',
654
+ plat => 'ADFHLS'
655
+ },
656
+ {
657
+ name => 'priority', type => 'Int',
658
+ desc => 'Kernel scheduling priority of process',
659
+ plat => 'DFHLSW'
660
+ },
661
+ {
662
+ name => 'threads', type => 'Long',
663
+ desc => 'Number of active threads',
664
+ plat => 'ADHLSW'
665
+ },
666
+ {
667
+ name => 'processor', type => 'Int',
668
+ desc => 'Processor number last run on',
669
+ plat => 'AHLS'
670
+ },
671
+ ],
672
+ ProcFd => [
673
+ {
674
+ name => 'total', type => 'Long',
675
+ desc => 'Total number of open file descriptors',
676
+ plat => 'AHLSW'
677
+ },
678
+ ],
679
+ ProcStat => [
680
+ {
681
+ name => 'total', type => 'Long',
682
+ desc => 'Total number of processes',
683
+ plat => '*'
684
+ },
685
+ {
686
+ name => 'idle', type => 'Long',
687
+ desc => 'Total number of processes in idle state',
688
+ plat => '*'
689
+ },
690
+ {
691
+ name => 'running', type => 'Long',
692
+ desc => 'Total number of processes in run state',
693
+ plat => '*'
694
+ },
695
+ {
696
+ name => 'sleeping', type => 'Long',
697
+ desc => 'Total number of processes in sleep state',
698
+ plat => '*'
699
+ },
700
+ {
701
+ name => 'stopped', type => 'Long',
702
+ desc => 'Total number of processes in stop state',
703
+ plat => '*'
704
+ },
705
+ {
706
+ name => 'zombie', type => 'Long',
707
+ desc => 'Total number of processes in zombie state',
708
+ plat => '*'
709
+ },
710
+ {
711
+ name => 'threads', type => 'Long',
712
+ desc => 'Total number of threads',
713
+ plat => '*'
714
+ },
715
+ ],
716
+ ProcExe => [
717
+ {
718
+ name => 'name', type => 'String',
719
+ desc => 'Name of process executable',
720
+ plat => 'FLSW',
721
+ cmd => {
722
+ AIX => '',
723
+ Darwin => '',
724
+ FreeBSD => '',
725
+ HPUX => '',
726
+ Linux => 'ls -l /proc/$$/exe',
727
+ Solaris => '',
728
+ Win32 => '',
729
+ },
730
+ },
731
+ {
732
+ name => 'cwd', type => 'String',
733
+ desc => 'Name of process current working directory',
734
+ plat => 'LSW',
735
+ cmd => {
736
+ AIX => '',
737
+ Darwin => '',
738
+ FreeBSD => '',
739
+ HPUX => '',
740
+ Linux => 'ls -l /proc/$$/cwd',
741
+ Solaris => '',
742
+ Win32 => '',
743
+ },
744
+ },
745
+ ],
746
+ ThreadCpu => [
747
+ {
748
+ name => 'user', type => 'Long',
749
+ desc => 'Thread cpu user time',
750
+ plat => 'AHLSW'
751
+ },
752
+ {
753
+ name => 'sys', type => 'Long',
754
+ desc => 'Thread cpu kernel time',
755
+ plat => 'AHLSW'
756
+ },
757
+ {
758
+ name => 'total', type => 'Long',
759
+ desc => 'Thread cpu time (sum of User and Sys)',
760
+ plat => 'AHLSW'
761
+ },
762
+ ],
763
+ FileSystem => [
764
+ {
765
+ name => 'dir_name', type => 'String',
766
+ desc => 'Directory name',
767
+ plat => '*'
768
+ },
769
+ {
770
+ name => 'dev_name', type => 'String',
771
+ desc => 'Device name',
772
+ plat => '*'
773
+ },
774
+ {
775
+ name => 'type_name', type => 'String',
776
+ desc => 'File system generic type name',
777
+ plat => '*'
778
+ },
779
+ {
780
+ name => 'sys_type_name', type => 'String',
781
+ desc => 'File system os specific type name',
782
+ plat => '*'
783
+ },
784
+ {
785
+ name => 'options', type => 'String',
786
+ desc => 'File system mount options',
787
+ plat => '*'
788
+ },
789
+ {
790
+ name => 'type', type => 'Int',
791
+ desc => 'File system type',
792
+ plat => '*'
793
+ },
794
+ {
795
+ name => 'flags', type => 'Long',
796
+ desc => 'File system flags',
797
+ plat => '*'
798
+ },
799
+ ],
800
+ FileSystemUsage => [
801
+ {
802
+ name => 'total', type => 'Long',
803
+ desc => 'Total Kbytes of filesystem',
804
+ plat => '*'
805
+ },
806
+ {
807
+ name => 'free', type => 'Long',
808
+ desc => 'Total free Kbytes on filesystem',
809
+ plat => '*'
810
+ },
811
+ {
812
+ name => 'used', type => 'Long',
813
+ desc => 'Total used Kbytes on filesystem',
814
+ plat => '*'
815
+ },
816
+ {
817
+ name => 'avail', type => 'Long',
818
+ desc => 'Total free Kbytes on filesystem available to caller',
819
+ plat => '*'
820
+ },
821
+ {
822
+ name => 'files', type => 'Long',
823
+ desc => 'Total number of file nodes on the filesystem',
824
+ plat => 'ADFHLS'
825
+ },
826
+ {
827
+ name => 'free_files', type => 'Long',
828
+ desc => 'Number of free file nodes on the filesystem',
829
+ plat => 'ADFHLS'
830
+ },
831
+ {
832
+ name => 'disk_reads', type => 'Long',
833
+ desc => 'Number of physical disk reads',
834
+ plat => 'AFHLSW'
835
+ },
836
+ {
837
+ name => 'disk_writes', type => 'Long',
838
+ desc => 'Number of physical disk writes',
839
+ plat => 'AFHLSW'
840
+ },
841
+ {
842
+ name => 'disk_read_bytes', type => 'Long',
843
+ desc => 'Number of physical disk bytes read',
844
+ plat => ''
845
+ },
846
+ {
847
+ name => 'disk_write_bytes', type => 'Long',
848
+ desc => 'Number of physical disk bytes written',
849
+ plat => ''
850
+ },
851
+ {
852
+ name => 'disk_queue', type => 'Double',
853
+ desc => '',
854
+ plat => ''
855
+ },
856
+ {
857
+ name => 'disk_service_time', type => 'Double',
858
+ desc => '',
859
+ plat => ''
860
+ },
861
+ {
862
+ name => 'use_percent', type => 'Double',
863
+ desc => 'Percent of disk used',
864
+ plat => '*'
865
+ },
866
+ ],
867
+ DiskUsage => [
868
+ {
869
+ name => 'reads', type => 'Long',
870
+ desc => 'Number of physical disk reads',
871
+ plat => 'AFHLSW'
872
+ },
873
+ {
874
+ name => 'writes', type => 'Long',
875
+ desc => 'Number of physical disk writes',
876
+ plat => 'AFHLSW'
877
+ },
878
+ {
879
+ name => 'read_bytes', type => 'Long',
880
+ desc => 'Number of physical disk bytes read',
881
+ plat => ''
882
+ },
883
+ {
884
+ name => 'write_bytes', type => 'Long',
885
+ desc => 'Number of physical disk bytes written',
886
+ plat => ''
887
+ },
888
+ {
889
+ name => 'queue', type => 'Double',
890
+ desc => '',
891
+ plat => ''
892
+ },
893
+ {
894
+ name => 'service_time', type => 'Double',
895
+ desc => '',
896
+ plat => ''
897
+ },
898
+ ],
899
+ FileAttrs => [
900
+ {
901
+ name => 'permissions', type => 'Long',
902
+ },
903
+ {
904
+ name => 'type', type => 'Int',
905
+ },
906
+ {
907
+ name => 'uid', type => 'Long',
908
+ },
909
+ {
910
+ name => 'gid', type => 'Long',
911
+ },
912
+ {
913
+ name => 'inode', type => 'Long',
914
+ },
915
+ {
916
+ name => 'device', type => 'Long',
917
+ },
918
+ {
919
+ name => 'nlink', type => 'Long',
920
+ },
921
+ {
922
+ name => 'size', type => 'Long',
923
+ },
924
+ {
925
+ name => 'atime', type => 'Long',
926
+ },
927
+ {
928
+ name => 'ctime', type => 'Long',
929
+ },
930
+ {
931
+ name => 'mtime', type => 'Long',
932
+ },
933
+ ],
934
+ DirStat => [
935
+ {
936
+ name => 'total', type => 'Long',
937
+ },
938
+ {
939
+ name => 'files', type => 'Long',
940
+ },
941
+ {
942
+ name => 'subdirs', type => 'Long',
943
+ },
944
+ {
945
+ name => 'symlinks', type => 'Long',
946
+ },
947
+ {
948
+ name => 'chrdevs', type => 'Long',
949
+ },
950
+ {
951
+ name => 'blkdevs', type => 'Long',
952
+ },
953
+ {
954
+ name => 'sockets', type => 'Long',
955
+ },
956
+ {
957
+ name => 'disk_usage', type => 'Long',
958
+ },
959
+ ],
960
+ NetInfo => [
961
+ {
962
+ name => 'default_gateway', type => 'String',
963
+ desc => '',
964
+ plat => ''
965
+ },
966
+ {
967
+ name => 'default_gateway_interface', type => 'String',
968
+ desc => '',
969
+ plat => ''
970
+ },
971
+ {
972
+ name => 'host_name', type => 'String',
973
+ desc => '',
974
+ plat => ''
975
+ },
976
+ {
977
+ name => 'domain_name', type => 'String',
978
+ desc => '',
979
+ plat => ''
980
+ },
981
+ {
982
+ name => 'primary_dns', type => 'String',
983
+ desc => '',
984
+ plat => ''
985
+ },
986
+ {
987
+ name => 'secondary_dns', type => 'String',
988
+ desc => '',
989
+ plat => ''
990
+ },
991
+ ],
992
+ NetRoute => [
993
+ {
994
+ name => 'destination', type => 'NetAddress',
995
+ desc => '',
996
+ plat => 'HLW'
997
+ },
998
+ {
999
+ name => 'gateway', type => 'NetAddress',
1000
+ desc => '',
1001
+ plat => 'HLW'
1002
+ },
1003
+ {
1004
+ name => 'flags', type => 'Long',
1005
+ desc => '',
1006
+ plat => 'L'
1007
+ },
1008
+ {
1009
+ name => 'refcnt', type => 'Long',
1010
+ desc => '',
1011
+ plat => 'L'
1012
+ },
1013
+ {
1014
+ name => 'use', type => 'Long',
1015
+ desc => '',
1016
+ plat => 'L'
1017
+ },
1018
+ {
1019
+ name => 'metric', type => 'Long',
1020
+ desc => '',
1021
+ plat => 'L'
1022
+ },
1023
+ {
1024
+ name => 'mask', type => 'NetAddress',
1025
+ desc => '',
1026
+ plat => 'HL'
1027
+ },
1028
+ {
1029
+ name => 'mtu', type => 'Long',
1030
+ desc => '',
1031
+ plat => 'L'
1032
+ },
1033
+ {
1034
+ name => 'window', type => 'Long',
1035
+ desc => '',
1036
+ plat => 'L'
1037
+ },
1038
+ {
1039
+ name => 'irtt', type => 'Long',
1040
+ desc => '',
1041
+ plat => 'L'
1042
+ },
1043
+ {
1044
+ name => 'ifname', type => 'String',
1045
+ desc => '',
1046
+ plat => 'L'
1047
+ },
1048
+ ],
1049
+ NetInterfaceConfig => [
1050
+ {
1051
+ name => 'name', type => 'String',
1052
+ desc => '',
1053
+ plat => '*'
1054
+ },
1055
+ {
1056
+ name => 'hwaddr', type => 'NetAddress',
1057
+ desc => '',
1058
+ plat => '*'
1059
+ },
1060
+ {
1061
+ name => 'type', type => 'String',
1062
+ desc => '',
1063
+ plat => '*'
1064
+ },
1065
+ {
1066
+ name => 'description', type => 'String',
1067
+ desc => '',
1068
+ plat => '*'
1069
+ },
1070
+ {
1071
+ name => 'address', type => 'NetAddress',
1072
+ desc => '',
1073
+ plat => '*'
1074
+ },
1075
+ {
1076
+ name => 'address6', type => 'NetAddress',
1077
+ desc => '',
1078
+ },
1079
+ {
1080
+ name => 'prefix6_length', type => 'Int',
1081
+ desc => '',
1082
+ },
1083
+ {
1084
+ name => 'scope6', type => 'Int',
1085
+ desc => '',
1086
+ },
1087
+ {
1088
+ name => 'destination', type => 'NetAddress',
1089
+ desc => '',
1090
+ plat => '*'
1091
+ },
1092
+ {
1093
+ name => 'broadcast', type => 'NetAddress',
1094
+ desc => '',
1095
+ plat => '*'
1096
+ },
1097
+ {
1098
+ name => 'netmask', type => 'NetAddress',
1099
+ desc => '',
1100
+ plat => '*'
1101
+ },
1102
+ {
1103
+ name => 'flags', type => 'Long',
1104
+ desc => '',
1105
+ plat => '*'
1106
+ },
1107
+ {
1108
+ name => 'mtu', type => 'Long',
1109
+ desc => '',
1110
+ plat => 'DFL'
1111
+ },
1112
+ {
1113
+ name => 'metric', type => 'Long',
1114
+ desc => '',
1115
+ plat => 'DFL'
1116
+ },
1117
+ {
1118
+ name => 'tx_queue_len', type => 'Int',
1119
+ desc => '',
1120
+ plat => 'L'
1121
+ },
1122
+ ],
1123
+ NetInterfaceStat => [
1124
+ {
1125
+ name => 'rx_bytes', type => 'Long',
1126
+ desc => '',
1127
+ plat => '*'
1128
+ },
1129
+ {
1130
+ name => 'rx_packets', type => 'Long',
1131
+ desc => '',
1132
+ plat => '*'
1133
+ },
1134
+ {
1135
+ name => 'rx_errors', type => 'Long',
1136
+ desc => '',
1137
+ plat => '*'
1138
+ },
1139
+ {
1140
+ name => 'rx_dropped', type => 'Long',
1141
+ desc => '',
1142
+ plat => ''
1143
+ },
1144
+ {
1145
+ name => 'rx_overruns', type => 'Long',
1146
+ desc => '',
1147
+ plat => ''
1148
+ },
1149
+ {
1150
+ name => 'rx_frame', type => 'Long',
1151
+ desc => '',
1152
+ plat => ''
1153
+ },
1154
+ {
1155
+ name => 'tx_bytes', type => 'Long',
1156
+ desc => '',
1157
+ plat => '*'
1158
+ },
1159
+ {
1160
+ name => 'tx_packets', type => 'Long',
1161
+ desc => '',
1162
+ plat => '*'
1163
+ },
1164
+ {
1165
+ name => 'tx_errors', type => 'Long',
1166
+ desc => '*',
1167
+ plat => ''
1168
+ },
1169
+ {
1170
+ name => 'tx_dropped', type => 'Long',
1171
+ desc => '',
1172
+ plat => ''
1173
+ },
1174
+ {
1175
+ name => 'tx_overruns', type => 'Long',
1176
+ desc => '',
1177
+ plat => ''
1178
+ },
1179
+ {
1180
+ name => 'tx_collisions', type => 'Long',
1181
+ desc => '',
1182
+ plat => ''
1183
+ },
1184
+ {
1185
+ name => 'tx_carrier', type => 'Long',
1186
+ desc => '',
1187
+ plat => ''
1188
+ },
1189
+ {
1190
+ name => 'speed', type => 'Long',
1191
+ desc => '',
1192
+ plat => ''
1193
+ },
1194
+ ],
1195
+ NetConnection => [
1196
+ {
1197
+ name => 'local_port', type => 'Long',
1198
+ desc => '',
1199
+ plat => 'LFSW'
1200
+ },
1201
+ {
1202
+ name => 'local_address', type => 'NetAddress',
1203
+ desc => '',
1204
+ plat => 'LFSW'
1205
+ },
1206
+ {
1207
+ name => 'remote_port', type => 'Long',
1208
+ desc => '',
1209
+ plat => 'LFSW'
1210
+ },
1211
+ {
1212
+ name => 'remote_address', type => 'NetAddress',
1213
+ desc => '',
1214
+ plat => 'LFSW'
1215
+ },
1216
+ {
1217
+ name => 'type', type => 'Int',
1218
+ desc => '',
1219
+ plat => 'LFSW'
1220
+ },
1221
+ {
1222
+ name => 'state', type => 'Int',
1223
+ desc => '',
1224
+ plat => 'LFSW'
1225
+ },
1226
+ {
1227
+ name => 'send_queue', type => 'Long',
1228
+ desc => '',
1229
+ plat => 'LFS'
1230
+ },
1231
+ {
1232
+ name => 'receive_queue', type => 'Long',
1233
+ desc => '',
1234
+ plat => 'LFS'
1235
+ },
1236
+ ],
1237
+ #only for jfieldId cache/setters
1238
+ NetStat => [
1239
+ {
1240
+ name => 'tcp_inbound_total', type => 'Int',
1241
+ },
1242
+ {
1243
+ name => 'tcp_outbound_total', type => 'Int',
1244
+ },
1245
+ {
1246
+ name => 'all_inbound_total', type => 'Int',
1247
+ },
1248
+ {
1249
+ name => 'all_outbound_total', type => 'Int',
1250
+ },
1251
+ ],
1252
+ Tcp => [
1253
+ {
1254
+ name => 'active_opens', type => 'Long',
1255
+ desc => '',
1256
+ plat => ''
1257
+ },
1258
+ {
1259
+ name => 'passive_opens', type => 'Long',
1260
+ desc => '',
1261
+ plat => ''
1262
+ },
1263
+ {
1264
+ name => 'attempt_fails', type => 'Long',
1265
+ desc => '',
1266
+ plat => ''
1267
+ },
1268
+ {
1269
+ name => 'estab_resets', type => 'Long',
1270
+ desc => '',
1271
+ plat => ''
1272
+ },
1273
+ {
1274
+ name => 'curr_estab', type => 'Long',
1275
+ desc => '',
1276
+ plat => ''
1277
+ },
1278
+ {
1279
+ name => 'in_segs', type => 'Long',
1280
+ desc => '',
1281
+ plat => ''
1282
+ },
1283
+ {
1284
+ name => 'out_segs', type => 'Long',
1285
+ desc => '',
1286
+ plat => ''
1287
+ },
1288
+ {
1289
+ name => 'retrans_segs', type => 'Long',
1290
+ desc => '',
1291
+ plat => ''
1292
+ },
1293
+ {
1294
+ name => 'in_errs', type => 'Long',
1295
+ desc => '',
1296
+ plat => ''
1297
+ },
1298
+ {
1299
+ name => 'out_rsts', type => 'Long',
1300
+ desc => '',
1301
+ plat => ''
1302
+ },
1303
+ ],
1304
+ NfsClientV2 => $nfs_v2,
1305
+ NfsServerV2 => $nfs_v2,
1306
+ NfsClientV3 => $nfs_v3,
1307
+ NfsServerV3 => $nfs_v3,
1308
+ ResourceLimit => [
1309
+ {
1310
+ name => 'cpu_cur',
1311
+ },
1312
+ {
1313
+ name => 'cpu_max',
1314
+ },
1315
+ {
1316
+ name => 'file_size_cur',
1317
+ },
1318
+ {
1319
+ name => 'file_size_max',
1320
+ },
1321
+ {
1322
+ name => 'pipe_size_max',
1323
+ },
1324
+ {
1325
+ name => 'pipe_size_cur',
1326
+ },
1327
+ {
1328
+ name => 'data_cur',
1329
+ },
1330
+ {
1331
+ name => 'data_max',
1332
+ },
1333
+ {
1334
+ name => 'stack_cur',
1335
+ },
1336
+ {
1337
+ name => 'stack_max',
1338
+ },
1339
+ {
1340
+ name => 'core_cur',
1341
+ },
1342
+ {
1343
+ name => 'core_max',
1344
+ },
1345
+ {
1346
+ name => 'memory_cur',
1347
+ },
1348
+ {
1349
+ name => 'memory_max',
1350
+ },
1351
+ {
1352
+ name => 'processes_cur',
1353
+ },
1354
+ {
1355
+ name => 'processes_max',
1356
+ },
1357
+ {
1358
+ name => 'open_files_cur',
1359
+ },
1360
+ {
1361
+ name => 'open_files_max',
1362
+ },
1363
+ {
1364
+ name => 'virtual_memory_cur',
1365
+ },
1366
+ {
1367
+ name => 'virtual_memory_max',
1368
+ },
1369
+ ],
1370
+ SysInfo => [
1371
+ {
1372
+ name => 'name', type => 'String',
1373
+ desc => '',
1374
+ plat => '*'
1375
+ },
1376
+ {
1377
+ name => 'version', type => 'String',
1378
+ desc => '',
1379
+ plat => '*'
1380
+ },
1381
+ {
1382
+ name => 'arch', type => 'String',
1383
+ desc => '',
1384
+ plat => '*'
1385
+ },
1386
+ {
1387
+ name => 'machine', type => 'String',
1388
+ desc => '',
1389
+ plat => '*'
1390
+ },
1391
+ {
1392
+ name => 'description', type => 'String',
1393
+ desc => '',
1394
+ plat => '*'
1395
+ },
1396
+ {
1397
+ name => 'patch_level', type => 'String',
1398
+ desc => '',
1399
+ plat => 'W'
1400
+ },
1401
+ {
1402
+ name => 'vendor', type => 'String',
1403
+ desc => '',
1404
+ plat => '*'
1405
+ },
1406
+ {
1407
+ name => 'vendor_version', type => 'String',
1408
+ desc => '',
1409
+ plat => '*'
1410
+ },
1411
+ {
1412
+ name => 'vendor_name', type => 'String',
1413
+ desc => '',
1414
+ plat => '*'
1415
+ },
1416
+ {
1417
+ name => 'vendor_code_name', type => 'String',
1418
+ desc => '',
1419
+ plat => '*'
1420
+ },
1421
+ ],
1422
+ Arp => [
1423
+ {
1424
+ name => 'ifname', type => 'String',
1425
+ desc => '',
1426
+ plat => '*'
1427
+ },
1428
+ {
1429
+ name => 'hwaddr', type => 'NetAddress',
1430
+ desc => '',
1431
+ plat => '*'
1432
+ },
1433
+ {
1434
+ name => 'type', type => 'String',
1435
+ desc => '',
1436
+ plat => '*'
1437
+ },
1438
+ {
1439
+ name => 'address', type => 'NetAddress',
1440
+ desc => '',
1441
+ plat => '*'
1442
+ },
1443
+ {
1444
+ name => 'flags', type => 'Long',
1445
+ desc => '',
1446
+ plat => '*'
1447
+ },
1448
+ ],
1449
+ Who => [
1450
+ {
1451
+ name => 'user', type => 'String',
1452
+ desc => '',
1453
+ plat => ''
1454
+ },
1455
+ {
1456
+ name => 'device', type => 'String',
1457
+ desc => '',
1458
+ plat => ''
1459
+ },
1460
+ {
1461
+ name => 'host', type => 'String',
1462
+ desc => '',
1463
+ plat => ''
1464
+ },
1465
+ {
1466
+ name => 'time', type => 'Long',
1467
+ desc => '',
1468
+ plat => ''
1469
+ },
1470
+ ],
1471
+ );
1472
+
1473
+ $classes{DirUsage} = $classes{DirStat};
1474
+
1475
+ my(%extends) = (
1476
+ ProcCpu => 'ProcTime',
1477
+ );
1478
+
1479
+ while (my($subclass, $superclass) = each %extends) {
1480
+ push @{ $classes{$subclass} }, @{ $classes{$superclass} };
1481
+ }
1482
+
1483
+ %cmds = (
1484
+ Mem => {
1485
+ AIX => 'top',
1486
+ Darwin => 'top',
1487
+ FreeBSD => 'top',
1488
+ HPUX => 'top',
1489
+ Linux => 'top',
1490
+ Solaris => 'top',
1491
+ Win32 => 'taskman',
1492
+ },
1493
+ Swap => {
1494
+ AIX => 'top',
1495
+ Darwin => 'top',
1496
+ FreeBSD => 'top',
1497
+ HPUX => 'top',
1498
+ Linux => 'top',
1499
+ Solaris => 'top',
1500
+ Win32 => 'taskman',
1501
+ },
1502
+ Cpu => {
1503
+ AIX => 'top',
1504
+ Darwin => 'top',
1505
+ FreeBSD => 'top',
1506
+ HPUX => 'top',
1507
+ Linux => 'top',
1508
+ Solaris => 'top',
1509
+ Win32 => 'taskman',
1510
+ },
1511
+ CpuInfo => {
1512
+ AIX => 'lsattr -El proc0',
1513
+ Darwin => '',
1514
+ FreeBSD => '',
1515
+ HPUX => '',
1516
+ Linux => 'cat /proc/cpuinfo',
1517
+ Solaris => 'psrinfo -v',
1518
+ Win32 => '',
1519
+ },
1520
+ Uptime => {
1521
+ AIX => 'uptime',
1522
+ Darwin => 'uptime',
1523
+ FreeBSD => 'uptime',
1524
+ HPUX => 'uptime',
1525
+ Linux => 'uptime',
1526
+ Solaris => 'uptime',
1527
+ Win32 => '',
1528
+ },
1529
+ ProcMem => {
1530
+ AIX => 'top, ps',
1531
+ Darwin => 'top, ps',
1532
+ FreeBSD => 'top, ps',
1533
+ HPUX => 'top, ps',
1534
+ Linux => 'top, ps',
1535
+ Solaris => 'top, ps',
1536
+ Win32 => 'taskman',
1537
+ },
1538
+ ProcCred => {
1539
+ AIX => 'top, ps',
1540
+ Darwin => 'top, ps',
1541
+ FreeBSD => 'top, ps',
1542
+ HPUX => 'top, ps',
1543
+ Linux => 'top, ps',
1544
+ Solaris => 'top, ps',
1545
+ Win32 => 'taskman',
1546
+ },
1547
+ ProcTime => {
1548
+ AIX => 'top, ps',
1549
+ Darwin => 'top, ps',
1550
+ FreeBSD => 'top, ps',
1551
+ HPUX => 'top, ps',
1552
+ Linux => 'top, ps',
1553
+ Solaris => 'top, ps',
1554
+ Win32 => 'taskman',
1555
+ },
1556
+ ProcState => {
1557
+ AIX => 'top, ps',
1558
+ Darwin => 'top, ps',
1559
+ FreeBSD => 'top, ps',
1560
+ HPUX => 'top, ps',
1561
+ Linux => 'top, ps',
1562
+ Solaris => 'top, ps',
1563
+ Win32 => 'taskman',
1564
+ },
1565
+ ProcFd => {
1566
+ AIX => 'lsof',
1567
+ Darwin => 'lsof',
1568
+ FreeBSD => 'lsof',
1569
+ HPUX => 'lsof',
1570
+ Linux => 'lsof',
1571
+ Solaris => 'lsof',
1572
+ Win32 => '',
1573
+ },
1574
+ ProcStat => {
1575
+ AIX => 'top, ps',
1576
+ Darwin => 'top, ps',
1577
+ FreeBSD => 'top, ps',
1578
+ HPUX => 'top, ps',
1579
+ Linux => 'top, ps',
1580
+ Solaris => 'top, ps',
1581
+ Win32 => 'taskman',
1582
+ },
1583
+ FileSystemUsage => {
1584
+ AIX => 'df',
1585
+ Darwin => 'df',
1586
+ FreeBSD => 'df',
1587
+ HPUX => 'df',
1588
+ Linux => 'df',
1589
+ Solaris => 'df',
1590
+ Win32 => '',
1591
+ },
1592
+ NetRoute => {
1593
+ AIX => '',
1594
+ Darwin => '',
1595
+ FreeBSD => '',
1596
+ HPUX => '',
1597
+ Linux => 'route -n',
1598
+ Solaris => '',
1599
+ Win32 => '',
1600
+ },
1601
+ NetInterfaceConfig => {
1602
+ AIX => '',
1603
+ Darwin => '',
1604
+ FreeBSD => '',
1605
+ HPUX => '',
1606
+ Linux => 'ifconfig',
1607
+ Solaris => 'ifconfig -a',
1608
+ Win32 => '',
1609
+ },
1610
+ NetInterfaceStat => {
1611
+ AIX => '',
1612
+ Darwin => '',
1613
+ FreeBSD => '',
1614
+ HPUX => '/usr/sbin/lanadmin -g mibstats 0, netstat -i',
1615
+ Linux => 'ifconfig',
1616
+ Solaris => '',
1617
+ Win32 => '',
1618
+ },
1619
+ NetConnection => {
1620
+ AIX => '',
1621
+ Darwin => '',
1622
+ FreeBSD => '',
1623
+ HPUX => '',
1624
+ Linux => 'netstat',
1625
+ Solaris => '',
1626
+ Win32 => '',
1627
+ },
1628
+ Tcp => {
1629
+ Linux => 'cat /proc/net/snmp',
1630
+ Solaris => 'netstat -s -P tcp',
1631
+ },
1632
+ );
1633
+
1634
+ sub warning_comment {
1635
+ my $self = shift;
1636
+
1637
+ return "WARNING: this file was generated by $0
1638
+ on $self->{timestamp}.
1639
+ Any changes made here will be LOST.";
1640
+ }
1641
+
1642
+ sub c_warning_comment {
1643
+ my $self = shift;
1644
+ my $comment = $self->warning_comment;
1645
+ $comment =~ s/^/ * /mg;
1646
+ return <<EOF
1647
+ /*****************************************************
1648
+ $comment
1649
+ *****************************************************/
1650
+ EOF
1651
+ }
1652
+
1653
+ sub erl_warning_comment {
1654
+ my $self = shift;
1655
+ my $comment = $self->warning_comment;
1656
+ $comment =~ s/^/% /mg;
1657
+ "$comment\n";
1658
+ }
1659
+
1660
+ sub generate {
1661
+ my($lang, $dir) = @_ ? @_ : @ARGV;
1662
+
1663
+ my $mtime = (stat __FILE__)[9];
1664
+
1665
+ my $cwd = cwd();
1666
+ unless (-d $dir) {
1667
+ die "Invalid build directory '$dir'";
1668
+ }
1669
+
1670
+ chdir $dir;
1671
+ my(%param) = (
1672
+ build_dir => $dir,
1673
+ mtime => $mtime,
1674
+ );
1675
+
1676
+ my $package = __PACKAGE__ . "::$lang";
1677
+ eval "require $package";
1678
+
1679
+ unless ($package->can('new')) {
1680
+ die "unsupported language: $lang";
1681
+ }
1682
+ $@ = '';
1683
+
1684
+ my $wrapper = $package->new(%param);
1685
+ unless ($wrapper->uptodate($wrapper->sources)) {
1686
+ eval {
1687
+ $wrapper->start();
1688
+
1689
+ my $mappings = $wrapper->get_mappings;
1690
+ for my $func (@$mappings) {
1691
+ $wrapper->generate_class($func);
1692
+ }
1693
+
1694
+ $wrapper->finish;
1695
+ };
1696
+ }
1697
+ die $@ if $@;
1698
+ chdir $cwd;
1699
+ }
1700
+
1701
+ sub new {
1702
+ my $class = shift;
1703
+ return bless {
1704
+ timestamp => scalar localtime,
1705
+ @_
1706
+ }, $class;
1707
+ }
1708
+
1709
+ sub uptodate {
1710
+ my $self = shift;
1711
+ for my $file (@_) {
1712
+ my $mtime = (stat $file)[9];
1713
+ if ($mtime > $self->{mtime}) {
1714
+ print "$file up-to-date\n";
1715
+ }
1716
+ else {
1717
+ print "$file needs update\n";
1718
+ return 0;
1719
+ }
1720
+ }
1721
+ return 1;
1722
+ }
1723
+
1724
+ my(%warning_comment) =
1725
+ ((map { $_ => \&c_warning_comment } qw(c h java)),
1726
+ (map { $_ => \&erl_warning_comment } qw(erl hrl)));
1727
+
1728
+ sub create {
1729
+ my($self, $file) = @_;
1730
+ my $handle = SigarWrapper::File->create($file);
1731
+ if ($file =~ /\.(\w+)$/) {
1732
+ my $comment = $warning_comment{$1};
1733
+ $handle->print($self->$comment()) if $comment;
1734
+ }
1735
+ return $self->{files}->{$file} = $handle;
1736
+ }
1737
+
1738
+ sub start {
1739
+ }
1740
+
1741
+ sub finish {
1742
+ my $self = shift;
1743
+ while (my($file, $handle) = each %{ $self->{files} }) {
1744
+ next unless $handle->opened;
1745
+ if ($handle->close) {
1746
+ #print "closing $file\n";
1747
+ }
1748
+ else {
1749
+ warn "close($file): $!";
1750
+ }
1751
+ }
1752
+ }
1753
+
1754
+ my @mappings;
1755
+
1756
+ sub get_mappings {
1757
+ if (@mappings != 0) {
1758
+ return \@mappings;
1759
+ }
1760
+
1761
+ while (my($name, $fields) = each %classes) {
1762
+ #example: FileSystemUsage -> file_system_usage
1763
+ (my $cname = $name) =~ s/([a-z])([A-Z])/$1_$2/g;
1764
+ $cname = lc $cname;
1765
+
1766
+ my $func = {
1767
+ name => $name,
1768
+ cname => $cname,
1769
+ };
1770
+ push @mappings, $func;
1771
+
1772
+ if (($cname =~ /^proc_(\w+)/ and !$proc_no_arg{$1}) ||
1773
+ ($cname =~ /^thread_cpu/))
1774
+ {
1775
+ $func->{num_args} = 1;
1776
+ $func->{arg_type} = 'sigar_pid_t';
1777
+ $func->{arg} = 'pid';
1778
+ $func->{is_proc} = 1;
1779
+ }
1780
+ elsif ($has_name_arg{$name}) {
1781
+ $func->{num_args} = 1;
1782
+ $func->{arg_type} = 'const char *';
1783
+ $func->{arg} = 'name';
1784
+ }
1785
+ else {
1786
+ $func->{num_args} = 0;
1787
+ }
1788
+
1789
+ if ($get_not_impl{$cname}) {
1790
+ $func->{has_get} = 0;
1791
+ }
1792
+ else {
1793
+ $func->{has_get} = 1;
1794
+ }
1795
+
1796
+ my $sigar_prefix = $func->{sigar_prefix} = join '_', 'sigar', $cname;
1797
+
1798
+ $func->{sigar_function} = join '_', $sigar_prefix, 'get';
1799
+
1800
+ $func->{sigar_type} = join '_', $sigar_prefix, 't';
1801
+
1802
+ $func->{fields} = $fields;
1803
+
1804
+ for my $field (@$fields) {
1805
+ $field->{type} ||= 'Long';
1806
+ }
1807
+ }
1808
+
1809
+ return \@mappings;
1810
+ }
1811
+
1812
+ package SigarWrapper::File;
1813
+
1814
+ use vars qw(@ISA);
1815
+ @ISA = qw(IO::File);
1816
+
1817
+ my $DEVNULL = '/dev/null';
1818
+ my $has_dev_null = -e $DEVNULL;
1819
+
1820
+ sub println {
1821
+ shift->print(@_, "\n");
1822
+ }
1823
+
1824
+ sub create {
1825
+ my($class, $file) = @_;
1826
+
1827
+ my $handle = $class->SUPER::new($file || devnull(), "w") or die "open $file: $!";
1828
+ print "generating $file\n" if $file;
1829
+ return $handle;
1830
+ }
1831
+
1832
+ sub devnull {
1833
+ if ($has_dev_null) {
1834
+ return $DEVNULL;
1835
+ }
1836
+ else {
1837
+ return "./nul"; #win32 /dev/null equiv
1838
+ }
1839
+ }
1840
+
1841
+ package SigarWrapper::Java;
1842
+
1843
+ use vars qw(@ISA);
1844
+ @ISA = qw(SigarWrapper);
1845
+
1846
+ my %field_types = (
1847
+ Long => "J",
1848
+ Double => "D",
1849
+ Int => "I",
1850
+ Char => "C",
1851
+ String => "Ljava/lang/String;",
1852
+ );
1853
+
1854
+ my %init = (
1855
+ String => 'null',
1856
+ );
1857
+
1858
+ my %type = (
1859
+ String => 'String',
1860
+ );
1861
+
1862
+ #alias
1863
+ for my $j (\%field_types, \%init, \%type) {
1864
+ $j->{'NetAddress'} = $j->{'String'};
1865
+ }
1866
+
1867
+ #XXX kinda ugly having this here
1868
+ #will consider moving elsewhere if there
1869
+ #are more cases like this.
1870
+ my %extra_code = (
1871
+ FileSystem => <<'EOF',
1872
+ public static final int TYPE_UNKNOWN = 0;
1873
+ public static final int TYPE_NONE = 1;
1874
+ public static final int TYPE_LOCAL_DISK = 2;
1875
+ public static final int TYPE_NETWORK = 3;
1876
+ public static final int TYPE_RAM_DISK = 4;
1877
+ public static final int TYPE_CDROM = 5;
1878
+ public static final int TYPE_SWAP = 6;
1879
+
1880
+ public String toString() {
1881
+ return this.getDirName();
1882
+ }
1883
+ EOF
1884
+ NetConnection => <<'EOF',
1885
+ public native String getTypeString();
1886
+
1887
+ public native static String getStateString(int state);
1888
+
1889
+ public String getStateString() {
1890
+ return getStateString(this.state);
1891
+ }
1892
+ EOF
1893
+ Mem => <<'EOF',
1894
+ public String toString() {
1895
+ return
1896
+ "Mem: " +
1897
+ (this.total / 1024) + "K av, " +
1898
+ (this.used / 1024) + "K used, " +
1899
+ (this.free / 1024) + "K free";
1900
+ }
1901
+ EOF
1902
+ ResourceLimit => <<'EOF',
1903
+ public static native long INFINITY();
1904
+ EOF
1905
+ Swap => <<'EOF',
1906
+ public String toString() {
1907
+ return
1908
+ "Swap: " +
1909
+ (this.total / 1024) + "K av, " +
1910
+ (this.used / 1024) + "K used, " +
1911
+ (this.free / 1024) + "K free";
1912
+ }
1913
+ EOF
1914
+ ProcState => <<'EOF',
1915
+ public static final char SLEEP = 'S';
1916
+ public static final char RUN = 'R';
1917
+ public static final char STOP = 'T';
1918
+ public static final char ZOMBIE = 'Z';
1919
+ public static final char IDLE = 'D';
1920
+ EOF
1921
+ ProcMem => <<'EOF',
1922
+ /**
1923
+ * @deprecated
1924
+ * @see #getResident()
1925
+ */
1926
+ public long getRss() { return getResident(); }
1927
+ /**
1928
+ * @deprecated
1929
+ * @see #getSize()
1930
+ */
1931
+ public long getVsize() { return getSize(); }
1932
+ EOF
1933
+ );
1934
+
1935
+ sub new {
1936
+ my $class = shift;
1937
+ my $self = $class->SUPER::new(@_);
1938
+ $self->{jsrc} = 'org/hyperic/sigar';
1939
+ return $self;
1940
+ }
1941
+
1942
+ my $jni_file = 'javasigar_generated';
1943
+
1944
+ sub sources {
1945
+ return map { "$jni_file.$_" } qw(c h);
1946
+ }
1947
+
1948
+ sub start {
1949
+ my $self = shift;
1950
+ $self->SUPER::start;
1951
+ my $jsrc = $self->{jsrc};
1952
+ File::Path::mkpath([$jsrc], 0, 0755) unless -d $jsrc;
1953
+ $self->{package} = 'org.hyperic.sigar';
1954
+
1955
+ $self->{cfh} = $self->create("$jni_file.c");
1956
+ my $hfh = $self->{hfh} = $self->create("$jni_file.h");
1957
+
1958
+ my %field_cache;
1959
+ my $i = 0;
1960
+ while (my($class, $fields) = each %SigarWrapper::classes) {
1961
+ next if $field_cache{$class}++;
1962
+ print $hfh "#define JSIGAR_FIELDS_\U$class $i\n";
1963
+ $i++;
1964
+ my $n = 0;
1965
+ for my $field (@$fields) {
1966
+ my $name = $field->{name};
1967
+ print $hfh "# define JSIGAR_FIELDS_\U${class}_${name} $n\n";
1968
+ $n++;
1969
+ }
1970
+ print $hfh "# define JSIGAR_FIELDS_\U${class}_MAX $n\n";
1971
+ }
1972
+ print $hfh "#define JSIGAR_FIELDS_MAX $i\n";
1973
+ }
1974
+
1975
+ sub jname {
1976
+ my $jname = shift;
1977
+ #special case for nfs
1978
+ return $jname eq 'null' ? "_$jname" : $jname;
1979
+ }
1980
+
1981
+ #using mega-method pattern here
1982
+ sub generate_class {
1983
+ my($self, $func) = @_;
1984
+
1985
+ my $cfh = $self->{cfh};
1986
+ my $hfh = $self->{hfh};
1987
+
1988
+ my $class = $func->{name};
1989
+ my $cname = $func->{cname};
1990
+
1991
+ my $java_class = "$self->{package}.$class";
1992
+ (my $jni_prefix = "Java.$java_class") =~ s/\./_/g;
1993
+
1994
+ my $args_proto = "";
1995
+ my $args = "";
1996
+ my $decl_string = "";
1997
+ my $get_string = "";
1998
+ my $release_string = "";
1999
+
2000
+ my $jname = lcfirst $class;
2001
+
2002
+ if ($func->{num_args} == 1) {
2003
+ $args = " $func->{arg}, ";
2004
+ if ($func->{is_proc}) {
2005
+ $args_proto = ", jlong pid";
2006
+ }
2007
+ else {
2008
+ $args_proto = ", jstring jname";
2009
+ $decl_string = "const char *name;";
2010
+ $get_string = "name = jname ? JENV->GetStringUTFChars(env, jname, 0) : NULL;";
2011
+ $release_string = "if (jname) JENV->ReleaseStringUTFChars(env, jname, name);";
2012
+ }
2013
+ }
2014
+
2015
+ my $nativefunc = join '_', $jni_prefix, 'gather';
2016
+
2017
+ my $proto = join "\n",
2018
+ "JNIEXPORT void JNICALL $nativefunc",
2019
+ "(JNIEnv *env, jobject obj, jobject sigar_obj$args_proto)";
2020
+
2021
+ my $jfh = $self->create_jfile($class);
2022
+
2023
+ print $cfh <<EOF if $func->{has_get};
2024
+
2025
+ $proto;
2026
+
2027
+ $proto
2028
+ {
2029
+ $func->{sigar_type} s;
2030
+ int status;
2031
+ jclass cls = JENV->GetObjectClass(env, obj);
2032
+ $decl_string
2033
+ dSIGAR_VOID;
2034
+
2035
+ $get_string
2036
+
2037
+ status = $func->{sigar_function}(sigar,${args}&s);
2038
+
2039
+ $release_string
2040
+
2041
+ if (status != SIGAR_OK) {
2042
+ sigar_throw_error(env, jsigar, status);
2043
+ return;
2044
+ }
2045
+
2046
+ EOF
2047
+
2048
+ my $jargs_proto = 'Sigar sigar';
2049
+ my $jargs = 'sigar';
2050
+
2051
+ if ($func->{is_proc}) {
2052
+ $jargs_proto .= ', long pid';
2053
+ $jargs .= ", pid";
2054
+ }
2055
+ elsif ($func->{num_args} == 1) {
2056
+ $jargs_proto .= ', String name';
2057
+ $jargs .= ", name";
2058
+ }
2059
+
2060
+ my $cache_field_ids = 1;
2061
+
2062
+ my $uid = 0;
2063
+
2064
+ for my $field (@{ $func->{fields} }) {
2065
+ $uid +=
2066
+ SigarWrapper::hash($field->{type}) +
2067
+ SigarWrapper::hash($field->{name});
2068
+ }
2069
+
2070
+ print $jfh <<EOF;
2071
+ package $self->{package};
2072
+
2073
+ import java.util.HashMap;
2074
+ import java.util.Map;
2075
+
2076
+ /**
2077
+ * $class sigar class.
2078
+ */
2079
+ public class $class implements java.io.Serializable {
2080
+
2081
+ private static final long serialVersionUID = ${uid}L;
2082
+
2083
+ public $class() { }
2084
+
2085
+ public native void gather($jargs_proto) throws SigarException;
2086
+
2087
+ /**
2088
+ * This method is not intended to be called directly.
2089
+ * use Sigar.get$class() instead.
2090
+ * \@exception SigarException on failure.
2091
+ * \@see $self->{package}.Sigar#get$class
2092
+ */
2093
+ static $class fetch($jargs_proto) throws SigarException {
2094
+ $class $jname = new $class();
2095
+ $jname.gather($jargs);
2096
+ return $jname;
2097
+ }
2098
+
2099
+ EOF
2100
+
2101
+ my(@copy, @tostring);
2102
+ my $setter = "JAVA_SIGAR_SET_FIELDS_\U$class";
2103
+ my $getter = "JAVA_SIGAR_GET_FIELDS_\U$class";
2104
+ my @setter = ("\#define $setter(cls, obj, s)");
2105
+ my @getter = ("\#define $getter(obj, s)");
2106
+ my $init_define = "JAVA_SIGAR_INIT_FIELDS_\U$class";
2107
+ my $field_class_ix = "JSIGAR_FIELDS_\U$class";
2108
+ my $field_class_ix = "JSIGAR_FIELDS_\U$class";
2109
+ my $field_class_max = $field_class_ix . '_MAX';
2110
+ my $field_class = "jsigar->fields[$field_class_ix]";
2111
+
2112
+ my @init_fields = ("#define $init_define(cls)",
2113
+ " if (!$field_class) {",
2114
+ " $field_class = ",
2115
+ " malloc(sizeof(*$field_class));",
2116
+ " $field_class->classref = ",
2117
+ " (jclass)JENV->NewGlobalRef(env, cls);",
2118
+ " $field_class->ids = ",
2119
+ " malloc($field_class_max *",
2120
+ " sizeof(*$field_class->ids));");
2121
+
2122
+ for my $field (@{ $func->{fields} }) {
2123
+ my $type = $field->{type};
2124
+ my $name = $field->{name};
2125
+ my $member = $field->{member} || $name;
2126
+ my $desc = $field->{desc} || $name;
2127
+ (my $jname = $name) =~ s/_(\w)/\u$1/g;
2128
+ my $getter = "get\u$jname";
2129
+ $jname = jname($jname);
2130
+ my $sig = qq("$field_types{$type}");
2131
+ my $set = "JENV->Set${type}Field";
2132
+ my $get = "JENV->Get${type}Field";
2133
+
2134
+ my $field_ix = $field_class_ix . "_\U$name";
2135
+ my $get_id = qq|JENV->GetFieldID(env, cls, "$jname", $sig)|;
2136
+ my $id_cache = "$field_class->ids[$field_ix]";
2137
+
2138
+ my $id_lookup = $cache_field_ids ?
2139
+ $id_cache : $get_id;
2140
+
2141
+ push @init_fields,
2142
+ " $id_cache = ",
2143
+ " $get_id;";
2144
+
2145
+ push @setter,
2146
+ qq| $set(env, obj, $id_lookup, s.$member);|;
2147
+ push @getter,
2148
+ qq| s.$member = $get(env, obj, $id_lookup);|;
2149
+
2150
+ my $init = $init{$type} || '0';
2151
+ my $jtype = $type{$type} || lcfirst($type);
2152
+ my $platforms = SigarWrapper::supported_platforms($field->{plat});
2153
+
2154
+ print $jfh " $jtype $jname = $init;\n\n";
2155
+ push @copy, " copy.$jname = this.$jname;\n";
2156
+ push @tostring, $jname;
2157
+
2158
+ #documentation
2159
+ print $jfh " /**\n";
2160
+ print $jfh " * Get the $desc.<p>\n";
2161
+ print $jfh " * Supported Platforms: $platforms.\n";
2162
+ print $jfh " * <p>\n";
2163
+ if (my $cmd = ($field->{cmd} || $SigarWrapper::cmds{$class})) {
2164
+ print $jfh " * System equivalent commands:<ul>\n";
2165
+ for my $p (sort keys %$cmd) {
2166
+ print $jfh " * <li> $p: <code>$cmd->{$p}</code><br>\n";
2167
+ }
2168
+ print $jfh " * </ul>\n";
2169
+ }
2170
+ print $jfh " * \@return $desc\n";
2171
+ print $jfh " */\n";
2172
+
2173
+ print $jfh " public $jtype $getter() { return $jname; }\n";
2174
+ }
2175
+
2176
+ print $jfh "\n void copyTo($class copy) {\n", @copy, " }\n";
2177
+
2178
+ my $code = $extra_code{$class};
2179
+ if ($code) {
2180
+ print $jfh $code;
2181
+ }
2182
+
2183
+ my $num_fields = @tostring;
2184
+ print $jfh "\n public Map toMap() {\n";
2185
+ print $jfh " Map map = new HashMap();\n";
2186
+ for (my $i=0; $i<$num_fields; $i++) {
2187
+ my $jfield = $tostring[$i];
2188
+ my $sfield = "str${jfield}";
2189
+ print $jfh " String $sfield = \n";
2190
+ print $jfh " String.valueOf(this.$jfield);\n";
2191
+ print $jfh qq{ if (!"-1".equals($sfield))\n};
2192
+ print $jfh qq{ map.put("\u$jfield", $sfield);\n};
2193
+ }
2194
+ print $jfh " return map;\n";
2195
+ print $jfh " }\n";
2196
+
2197
+ if (!$code or $code !~ /toString/) {
2198
+ print $jfh "\n public String toString() {\n";
2199
+ print $jfh " return toMap().toString();\n";
2200
+ print $jfh " }\n";
2201
+ }
2202
+
2203
+ push @init_fields, " }";
2204
+
2205
+ if ($cache_field_ids) {
2206
+ print $hfh join(' \\' . "\n", @init_fields), "\n\n";
2207
+ print $cfh "\n\n $init_define(cls);\n\n" if $func->{has_get};
2208
+ }
2209
+ else {
2210
+ print $hfh "#define $init_define(cls)\n";
2211
+ }
2212
+
2213
+ print $hfh join(' \\' . "\n", @setter), "\n\n";
2214
+ print $hfh join(' \\' . "\n", @getter), "\n\n";
2215
+ print $cfh "\n\n $setter(cls, obj, s);" if $func->{has_get};
2216
+
2217
+ print $cfh "\n}\n" if $func->{has_get};
2218
+ print $jfh "\n}\n";
2219
+
2220
+ close $jfh;
2221
+ }
2222
+
2223
+ sub finish {
2224
+ my $self = shift;
2225
+ $self->SUPER::finish;
2226
+ }
2227
+
2228
+ sub create_jfile {
2229
+ my($self, $name) = @_;
2230
+ my $jsrc = $self->{jsrc};
2231
+ my $jfile = "$jsrc/$name.java";
2232
+ if (-e "../../src/$jsrc/$name.java") {
2233
+ print "skipping $jfile\n";
2234
+ #dont generate .java if already exists
2235
+ $jfile = undef;
2236
+ }
2237
+ return $self->create($jfile);
2238
+ }
2239
+
2240
+ package SigarWrapper::Perl;
2241
+
2242
+ use vars qw(@ISA);
2243
+ @ISA = qw(SigarWrapper);
2244
+
2245
+ my %field_types = (
2246
+ Long => "sigar_uint64_t",
2247
+ Double => "double",
2248
+ Int => "IV",
2249
+ Char => "char",
2250
+ String => "char *",
2251
+ NetAddress => "Sigar::NetAddress",
2252
+ );
2253
+
2254
+ my $xs_file = 'Sigar_generated.xs';
2255
+
2256
+ sub sources {
2257
+ return $xs_file;
2258
+ }
2259
+
2260
+ sub start {
2261
+ my $self = shift;
2262
+ $self->SUPER::start;
2263
+ $self->{xfh} = $self->create($xs_file);
2264
+ }
2265
+
2266
+ sub generate_class {
2267
+ my($self, $func) = @_;
2268
+
2269
+ my $fh = $self->{xfh};
2270
+ my $class = $func->{name};
2271
+ my $cname = $func->{cname};
2272
+ my $perl_class = "Sigar::$class";
2273
+ my $proto = 'VALUE obj';
2274
+ my $args = 'sigar';
2275
+
2276
+ if ($func->{num_args} == 1) {
2277
+ $args .= ", $func->{arg}";
2278
+ }
2279
+
2280
+ print $fh "\nMODULE = Sigar PACKAGE = Sigar PREFIX = sigar_\n\n";
2281
+
2282
+ print $fh <<EOF if $func->{has_get};
2283
+ $perl_class
2284
+ $cname($args)
2285
+ Sigar sigar
2286
+ EOF
2287
+ if ($func->{arg}) {
2288
+ print $fh " $func->{arg_type} $func->{arg}\n" if $func->{has_get};
2289
+ }
2290
+
2291
+ print $fh <<EOF if $func->{has_get};
2292
+
2293
+ PREINIT:
2294
+ int status;
2295
+
2296
+ CODE:
2297
+ RETVAL = safemalloc(sizeof(*RETVAL));
2298
+ if ((status = $func->{sigar_function}($args, RETVAL)) != SIGAR_OK) {
2299
+ SIGAR_CROAK(sigar, "$cname");
2300
+ }
2301
+
2302
+ OUTPUT:
2303
+ RETVAL
2304
+ EOF
2305
+
2306
+ print $fh <<EOF;
2307
+
2308
+ MODULE = Sigar PACKAGE = $perl_class PREFIX = sigar_
2309
+
2310
+ void
2311
+ DESTROY(obj)
2312
+ $perl_class obj
2313
+
2314
+ CODE:
2315
+ safefree(obj);
2316
+
2317
+ EOF
2318
+
2319
+ for my $field (@{ $func->{fields} }) {
2320
+ my $name = $field->{name};
2321
+ my $type = $field_types{ $field->{type} };
2322
+
2323
+ print $fh <<EOF;
2324
+ $type
2325
+ $name($cname)
2326
+ $perl_class $cname
2327
+
2328
+ CODE:
2329
+ RETVAL = $cname->$name;
2330
+
2331
+ OUTPUT:
2332
+ RETVAL
2333
+
2334
+ EOF
2335
+ }
2336
+ }
2337
+
2338
+ sub finish {
2339
+ my $self = shift;
2340
+ $self->SUPER::finish;
2341
+ }
2342
+
2343
+ package SigarWrapper::Ruby;
2344
+
2345
+ use vars qw(@ISA);
2346
+ @ISA = qw(SigarWrapper);
2347
+
2348
+ my %field_types = (
2349
+ Long => "rb_ll2inum",
2350
+ Double => "rb_float_new",
2351
+ Int => "rb_int2inum",
2352
+ Char => "CHR2FIX",
2353
+ String => "rb_str_new2",
2354
+ NetAddress => "rb_sigar_net_address_to_s",
2355
+ );
2356
+
2357
+ my $rx_file = 'rbsigar_generated.rx';
2358
+
2359
+ sub sources {
2360
+ return $rx_file;
2361
+ }
2362
+
2363
+ sub start {
2364
+ my $self = shift;
2365
+ $self->SUPER::start;
2366
+ $self->{cfh} = $self->create($rx_file);
2367
+ }
2368
+
2369
+ sub add_method {
2370
+ my($self, $class, $name) = @_;
2371
+ push @{ $self->{methods}->{$class} }, $name;
2372
+ }
2373
+
2374
+ sub generate_class {
2375
+ my($self, $func) = @_;
2376
+
2377
+ my $fh = $self->{cfh};
2378
+ my $class = $func->{name};
2379
+ my $cname = $func->{cname};
2380
+ my $ruby_class = "rb_cSigar$class";
2381
+ my $proto = 'VALUE obj';
2382
+ my $args = 'sigar';
2383
+
2384
+ if ($func->{num_args} == 1) {
2385
+ my $arg_type;
2386
+ if ($func->{is_proc}) {
2387
+ $arg_type = 'OBJ2PID';
2388
+ }
2389
+ else {
2390
+ $arg_type = 'StringValuePtr';
2391
+ }
2392
+ $proto .= ", VALUE $func->{arg}";
2393
+ $args .= ", $arg_type($func->{arg})";
2394
+ }
2395
+
2396
+ print $fh <<EOF if $func->{has_get};
2397
+ static VALUE $ruby_class;
2398
+
2399
+ static VALUE rb_sigar_$cname($proto)
2400
+ {
2401
+ SIGAR_GET;
2402
+
2403
+ int status;
2404
+ $func->{sigar_type} *RETVAL = malloc(sizeof(*RETVAL));
2405
+
2406
+ if ((status = $func->{sigar_function}($args, RETVAL)) != SIGAR_OK) {
2407
+ free(RETVAL);
2408
+ rb_raise(rb_eArgError, "%s", sigar_strerror(sigar, status));
2409
+ return Qnil;
2410
+ }
2411
+
2412
+ return Data_Wrap_Struct($ruby_class, 0, rb_sigar_free, RETVAL);
2413
+ }
2414
+ EOF
2415
+
2416
+ for my $field (@{ $func->{fields} }) {
2417
+ my $name = $field->{name};
2418
+ my $type = $field_types{ $field->{type} };
2419
+
2420
+ $self->add_method($class, $name);
2421
+
2422
+ print $fh <<EOF;
2423
+ static VALUE rb_sigar_${class}_${name}(VALUE self)
2424
+ {
2425
+ $func->{sigar_type} *$cname;
2426
+ Data_Get_Struct(self, $func->{sigar_type}, $cname);
2427
+ return $type($cname->$name);
2428
+ }
2429
+ EOF
2430
+ }
2431
+ }
2432
+
2433
+ sub finish {
2434
+ my $self = shift;
2435
+
2436
+ my $fh = $self->{cfh};
2437
+
2438
+ print $fh "static void rb_sigar_define_module_methods(VALUE rclass)\n{\n";
2439
+
2440
+ my $mappings = SigarWrapper::get_mappings();
2441
+
2442
+ for my $func (@$mappings) {
2443
+ my $name = $func->{cname};
2444
+ my $args = $func->{num_args};
2445
+ next unless $func->{has_get};
2446
+ print $fh qq{ rb_define_method(rclass, "$name", rb_sigar_$name, $args);\n};
2447
+ }
2448
+
2449
+ for my $class (sort keys %{ $self->{methods} }) {
2450
+ my $rclass = "rb_cSigar$class";
2451
+ print $fh qq{ $rclass = rb_define_class_under(rclass, "$class", rb_cObject);\n};
2452
+ for my $method (@{ $self->{methods}->{$class} }) {
2453
+ print $fh qq{ rb_define_method($rclass, "$method", rb_sigar_${class}_$method, 0);\n};
2454
+ }
2455
+ }
2456
+
2457
+ print $fh "}\n";
2458
+
2459
+ $self->SUPER::finish;
2460
+ }
2461
+
2462
+ package SigarWrapper::PHP;
2463
+
2464
+ use vars qw(@ISA);
2465
+ @ISA = qw(SigarWrapper);
2466
+
2467
+ my %field_types = (
2468
+ Long => "RETURN_LONG",
2469
+ Double => "RETURN_DOUBLE",
2470
+ Int => "RETURN_LONG",
2471
+ Char => "RETURN_LONG",
2472
+ String => "PHP_SIGAR_RETURN_STRING",
2473
+ NetAddress => "PHP_SIGAR_RETURN_NETADDR",
2474
+ );
2475
+
2476
+ my $php_file = 'php_sigar_generated.c';
2477
+
2478
+ sub sources {
2479
+ return $php_file;
2480
+ }
2481
+
2482
+ sub start {
2483
+ my $self = shift;
2484
+ $self->SUPER::start;
2485
+ $self->{cfh} = $self->create($php_file);
2486
+ }
2487
+
2488
+ sub generate_class {
2489
+ my($self, $func) = @_;
2490
+
2491
+ my $cfh = $self->{cfh};
2492
+ my $class = $func->{name};
2493
+ my $cname = $func->{cname};
2494
+ my $php_class = "Sigar::$class";
2495
+ my $parse_args = "";
2496
+ my $vars = "";
2497
+ my $args = 'sigar';
2498
+ my $arginfo = $args;
2499
+
2500
+ if ($func->{num_args} == 1) {
2501
+ if ($func->{is_proc}) {
2502
+ $parse_args = 'zSIGAR_PARSE_PID;';
2503
+ $arginfo .= '_pid';
2504
+ $vars = "long $func->{arg};\n";
2505
+ }
2506
+ else {
2507
+ $parse_args .= 'zSIGAR_PARSE_NAME;';
2508
+ $arginfo .= '_name';
2509
+ $vars = "char *$func->{arg}; int $func->{arg}_len;\n";
2510
+ }
2511
+ $args .= ", $func->{arg}";
2512
+ }
2513
+
2514
+ my $prefix = "php_$func->{sigar_prefix}_";
2515
+ my $functions = $prefix . 'functions';
2516
+ my $handlers = $prefix . 'object_handlers';
2517
+ my $init = $prefix . 'init';
2518
+
2519
+ my $ctor = $prefix . 'new';
2520
+
2521
+ my(@functions);
2522
+
2523
+ for my $field (@{ $func->{fields} }) {
2524
+ my $name = $field->{name};
2525
+ my $type = $field_types{ $field->{type} };
2526
+ my $method = $prefix . $name;
2527
+
2528
+ push @functions, { name => $name, me => $method };
2529
+ print $cfh <<EOF;
2530
+ static PHP_FUNCTION($method)
2531
+ {
2532
+ $func->{sigar_type} *$cname = ($func->{sigar_type} *)zSIGAR_OBJ;
2533
+ $type($cname->$name);
2534
+ }
2535
+ EOF
2536
+ }
2537
+
2538
+ print $cfh <<EOF;
2539
+ static zend_object_handlers $handlers;
2540
+
2541
+ static zend_object_value $ctor(zend_class_entry *class_type TSRMLS_DC)
2542
+ {
2543
+ return php_sigar_ctor(php_sigar_obj_dtor,
2544
+ &$handlers,
2545
+ NULL,
2546
+ class_type);
2547
+ }
2548
+
2549
+ static zend_function_entry ${functions}[] = {
2550
+ EOF
2551
+
2552
+ for my $func (@functions) {
2553
+ print $cfh " PHP_ME_MAPPING($func->{name}, $func->{me}, NULL)\n";
2554
+ }
2555
+
2556
+ print $cfh <<EOF;
2557
+ {NULL, NULL, NULL}
2558
+ };
2559
+ EOF
2560
+
2561
+ print $cfh <<EOF;
2562
+ static void $init(void)
2563
+ {
2564
+ zend_class_entry ce;
2565
+
2566
+ PHP_SIGAR_INIT_HANDLERS($handlers);
2567
+ INIT_CLASS_ENTRY(ce, "$php_class", $functions);
2568
+ ce.create_object = $ctor;
2569
+ zend_register_internal_class(&ce TSRMLS_CC);
2570
+ }
2571
+ EOF
2572
+
2573
+ print $cfh <<EOF if $func->{has_get};
2574
+ static PHP_FUNCTION($func->{sigar_function})
2575
+ {
2576
+ int status;
2577
+ zSIGAR;
2578
+
2579
+ $func->{sigar_type} *RETVAL = emalloc(sizeof(*RETVAL));
2580
+ $vars
2581
+ $parse_args
2582
+
2583
+ if ((status = $func->{sigar_function}($args, RETVAL)) != SIGAR_OK) {
2584
+ efree(RETVAL);
2585
+ RETURN_FALSE;
2586
+ }
2587
+ else {
2588
+ php_sigar_obj_new("$php_class", return_value)->ptr = RETVAL;
2589
+ }
2590
+ }
2591
+ EOF
2592
+ }
2593
+
2594
+ sub finish {
2595
+ my $self = shift;
2596
+
2597
+ my $mappings = $self->get_mappings;
2598
+ my $cfh = $self->{cfh};
2599
+ my $nl = '\\' . "\n";
2600
+
2601
+ print $cfh "#define PHP_SIGAR_FUNCTIONS $nl";
2602
+ for my $func (@$mappings) {
2603
+ next unless $func->{has_get};
2604
+ #XXX PHP_ME_MAPPING has another arg in 5.2
2605
+ print $cfh " PHP_ME_MAPPING($func->{cname}, $func->{sigar_function}, NULL)";
2606
+ if ($func == $mappings->[-1]) {
2607
+ print $cfh "\n";
2608
+ }
2609
+ else {
2610
+ print $cfh $nl;
2611
+ }
2612
+ }
2613
+
2614
+ print $cfh "#define PHP_SIGAR_INIT $nl";
2615
+ for my $func (@$mappings) {
2616
+ print $cfh " php_$func->{sigar_prefix}_init()";
2617
+ if ($func == $mappings->[-1]) {
2618
+ print $cfh "\n";
2619
+ }
2620
+ else {
2621
+ print $cfh ";$nl";
2622
+ }
2623
+ }
2624
+
2625
+ $self->SUPER::finish;
2626
+ }
2627
+
2628
+ package SigarWrapper::Python;
2629
+
2630
+ use vars qw(@ISA);
2631
+ @ISA = qw(SigarWrapper);
2632
+
2633
+ my %field_types = (
2634
+ Long => "PyLong_FromUnsignedLongLong",
2635
+ Double => "PyFloat_FromDouble",
2636
+ Int => "PyInt_FromLong",
2637
+ Char => "PySigarInt_FromChar",
2638
+ String => "PyString_FromString",
2639
+ NetAddress => "PySigarString_FromNetAddr",
2640
+ );
2641
+
2642
+ my $c_file = '_sigar_generated.c';
2643
+
2644
+ sub sources {
2645
+ return $c_file;
2646
+ }
2647
+
2648
+ sub start {
2649
+ my $self = shift;
2650
+ $self->SUPER::start;
2651
+ $self->{cfh} = $self->create($c_file);
2652
+ }
2653
+
2654
+ sub pyclass {
2655
+ my $class = shift;
2656
+ return "Sigar.$class";
2657
+ }
2658
+
2659
+ sub pytype {
2660
+ my $class = shift;
2661
+ return 'pysigar_PySigar' . $class . 'Type';
2662
+ }
2663
+
2664
+ sub generate_class {
2665
+ my($self, $func) = @_;
2666
+
2667
+ my $cfh = $self->{cfh};
2668
+ my $pyclass = pyclass($func->{name});
2669
+ my $pytype = pytype($func->{name});
2670
+ my $cname = $func->{cname};
2671
+ my $parse_args = "";
2672
+ my $vars = "";
2673
+ my $args = 'sigar';
2674
+
2675
+ if ($func->{num_args} == 1) {
2676
+ if ($func->{is_proc}) {
2677
+ $parse_args = 'PySigar_ParsePID;';
2678
+ $vars = "long $func->{arg};\n";
2679
+ }
2680
+ else {
2681
+ $parse_args .= 'PySigar_ParseName;';
2682
+ $vars = "char *$func->{arg}; int $func->{arg}_len;\n";
2683
+ }
2684
+ $args .= ", $func->{arg}";
2685
+ }
2686
+
2687
+ my $prefix = "py$func->{sigar_prefix}_";
2688
+ my $methods = $prefix . 'methods';
2689
+ my $dtor = 'pysigar_free';
2690
+
2691
+ for my $field (@{ $func->{fields} }) {
2692
+ my $name = $field->{name};
2693
+ my $type = $field_types{ $field->{type} };
2694
+ my $method = $prefix . $name;
2695
+
2696
+ print $cfh <<EOF;
2697
+ static PyObject *$method(PyObject *self, PyObject *args)
2698
+ {
2699
+ $func->{sigar_type} *$cname = ($func->{sigar_type} *)PySIGAR_OBJ->ptr;
2700
+ return $type($cname->$name);
2701
+ }
2702
+ EOF
2703
+ }
2704
+
2705
+ print $cfh "static PyMethodDef $methods [] = {\n";
2706
+ for my $field (@{ $func->{fields} }) {
2707
+ my $name = $field->{name};
2708
+ print $cfh qq( { "$name", ${prefix}$name, METH_NOARGS, "$name" },\n);
2709
+ }
2710
+ print $cfh " {NULL}\n};\n";
2711
+
2712
+ print $cfh <<EOF;
2713
+ static PyTypeObject $pytype = {
2714
+ PyObject_HEAD_INIT(NULL)
2715
+ 0, /*ob_size*/
2716
+ "$pyclass", /*tp_name*/
2717
+ sizeof(PySigarObject), /*tp_basicsize*/
2718
+ 0, /*tp_itemsize*/
2719
+ pysigar_free, /*tp_dealloc*/
2720
+ 0, /*tp_print*/
2721
+ 0, /*tp_getattr*/
2722
+ 0, /*tp_setattr*/
2723
+ 0, /*tp_compare*/
2724
+ 0, /*tp_repr*/
2725
+ 0, /*tp_as_number*/
2726
+ 0, /*tp_as_sequence*/
2727
+ 0, /*tp_as_mapping*/
2728
+ 0, /*tp_hash */
2729
+ 0, /*tp_call*/
2730
+ 0, /*tp_str*/
2731
+ 0, /*tp_getattro*/
2732
+ 0, /*tp_setattro*/
2733
+ 0, /*tp_as_buffer*/
2734
+ PySigar_TPFLAGS, /*tp_flags*/
2735
+ 0, /*tp_doc*/
2736
+ 0, /*tp_traverse*/
2737
+ 0, /*tp_clear*/
2738
+ 0, /*tp_richcompare*/
2739
+ 0, /*tp_weaklistoffset*/
2740
+ 0, /*tp_iter*/
2741
+ 0, /*tp_iternext*/
2742
+ $methods, /*tp_methods*/
2743
+ 0, /*tp_members*/
2744
+ 0, /*tp_getset*/
2745
+ 0, /*tp_base*/
2746
+ 0, /*tp_dict*/
2747
+ 0, /*tp_descr_get*/
2748
+ 0, /*tp_descr_set*/
2749
+ 0, /*tp_dictoffset*/
2750
+ 0, /*tp_init*/
2751
+ 0, /*tp_alloc*/
2752
+ 0 /*tp_new*/
2753
+ };
2754
+ EOF
2755
+
2756
+ print $cfh <<EOF if $func->{has_get};
2757
+ static PyObject *py$func->{sigar_function}(PyObject *self, PyObject *args)
2758
+ {
2759
+ int status;
2760
+ sigar_t *sigar = PySIGAR;
2761
+ $func->{sigar_type} *RETVAL = malloc(sizeof(*RETVAL));
2762
+ $vars
2763
+ $parse_args
2764
+
2765
+ if ((status = $func->{sigar_function}($args, RETVAL)) != SIGAR_OK) {
2766
+ free(RETVAL);
2767
+ PySigar_Croak();
2768
+ return NULL;
2769
+ }
2770
+ else {
2771
+ PyObject *self = PySigar_new($pytype);
2772
+ PySIGAR_OBJ->ptr = RETVAL;
2773
+ return self;
2774
+ }
2775
+ }
2776
+ EOF
2777
+ }
2778
+
2779
+ sub finish {
2780
+ my $self = shift;
2781
+
2782
+ my $mappings = $self->get_mappings;
2783
+ my $cfh = $self->{cfh};
2784
+ my $nl = '\\' . "\n";
2785
+
2786
+ print $cfh "#define PY_SIGAR_METHODS $nl";
2787
+ for my $func (@$mappings) {
2788
+ next unless $func->{has_get};
2789
+ my $arginfo = $func->{num_args} ? 'METH_VARARGS' : 'METH_NOARGS';
2790
+ print $cfh qq( {"$func->{cname}", py$func->{sigar_function}, $arginfo, NULL},);
2791
+ if ($func == $mappings->[-1]) {
2792
+ print $cfh "\n";
2793
+ }
2794
+ else {
2795
+ print $cfh $nl;
2796
+ }
2797
+ }
2798
+
2799
+ print $cfh "#define PY_SIGAR_ADD_TYPES $nl";
2800
+ for my $func (@$mappings) {
2801
+ my $pyclass = pyclass($func->{name});
2802
+ my $pytype = pytype($func->{name});
2803
+ print $cfh qq{ PySigar_AddType("$pyclass", $pytype)};
2804
+ if ($func == $mappings->[-1]) {
2805
+ print $cfh "\n";
2806
+ }
2807
+ else {
2808
+ print $cfh ";$nl";
2809
+ }
2810
+ }
2811
+
2812
+ $self->SUPER::finish;
2813
+ }
2814
+
2815
+ package SigarWrapper::Erlang;
2816
+
2817
+ use vars qw(@ISA);
2818
+ @ISA = qw(SigarWrapper);
2819
+
2820
+ my %field_types = (
2821
+ Long => "esigar_encode_ulonglong",
2822
+ Double => "esigar_encode_double",
2823
+ Int => "esigar_encode_long",
2824
+ Char => "esigar_encode_char",
2825
+ String => "esigar_encode_string",
2826
+ NetAddress => "esigar_encode_netaddr",
2827
+ );
2828
+
2829
+ my $c_file = 'priv/gen/sigar_drv_gen.c';
2830
+ my $h_file = 'priv/gen/sigar.hrl';
2831
+ my $g_file = 'priv/gen/sigar_gen.hrl';
2832
+
2833
+ sub sources {
2834
+ return $c_file;
2835
+ }
2836
+
2837
+ sub start {
2838
+ my $self = shift;
2839
+ $self->SUPER::start;
2840
+ $self->{cfh} = $self->create($c_file);
2841
+ $self->{hfh} = $self->create($h_file);
2842
+ $self->{gfh} = $self->create($g_file);
2843
+ }
2844
+
2845
+ sub generate_class {
2846
+ my($self, $func) = @_;
2847
+
2848
+ my $cfh = $self->{cfh};
2849
+ my $cname = $func->{cname};
2850
+ my $parse_args = "";
2851
+ my $vars = "";
2852
+ my $args = 'sigar';
2853
+
2854
+ if ($func->{num_args} == 1) {
2855
+ if ($func->{is_proc}) {
2856
+ $parse_args = 'pid = esigar_pid_get(sigar, bytes);';
2857
+ $vars = "long $func->{arg};\n";
2858
+ }
2859
+ else {
2860
+ $parse_args .= 'name = bytes;';
2861
+ $vars = "char *$func->{arg};\n";
2862
+ }
2863
+ $args .= ", $func->{arg}";
2864
+ }
2865
+
2866
+ my $encoder = "esigar_encode_$cname";
2867
+ my $n = scalar @{ $func->{fields} };
2868
+
2869
+ print $cfh <<EOF;
2870
+ static void $encoder(ei_x_buff *x,
2871
+ $func->{sigar_type} *$cname)
2872
+ {
2873
+ ei_x_encode_list_header(x, $n);
2874
+ EOF
2875
+
2876
+ for my $field (@{ $func->{fields} }) {
2877
+ my $name = $field->{name};
2878
+ my $type = $field_types{ $field->{type} };
2879
+
2880
+ print $cfh qq{ $type(x, "$name", $cname->$name);\n};
2881
+ }
2882
+
2883
+ print $cfh " ei_x_encode_empty_list(x);\n}\n\n";
2884
+
2885
+ print $cfh <<EOF if $func->{has_get};
2886
+ static int e$func->{sigar_function}(ErlDrvPort port, sigar_t *sigar, char *bytes)
2887
+ {
2888
+ int status;
2889
+ ei_x_buff x;
2890
+ $func->{sigar_type} $cname;
2891
+ $vars
2892
+ $parse_args
2893
+
2894
+ ESIGAR_NEW(&x);
2895
+ if ((status = $func->{sigar_function}($args, &$cname)) == SIGAR_OK) {
2896
+ ESIGAR_OK(&x);
2897
+
2898
+ $encoder(&x, &$cname);
2899
+
2900
+ ESIGAR_SEND(port, &x);
2901
+ }
2902
+ else {
2903
+ ESIGAR_ERROR(&x, sigar, status);
2904
+ }
2905
+ return status;
2906
+ }
2907
+ EOF
2908
+ }
2909
+
2910
+ my(@nongens) =
2911
+ qw{net_interface_list net_route_list net_connection_list
2912
+ file_system_list cpu_info_list arp_list who_list
2913
+ loadavg};
2914
+
2915
+ sub finish {
2916
+ my $self = shift;
2917
+
2918
+ my $mappings = $self->get_mappings;
2919
+ my $cfh = $self->{cfh};
2920
+ my $hfh = $self->{hfh};
2921
+ my $gfh = $self->{gfh};
2922
+ my $ncmd = 1;
2923
+
2924
+ for my $ngen (@nongens) {
2925
+ my $cmd = uc $ngen;
2926
+ print $cfh "#define ESIGAR_$cmd $ncmd\n";
2927
+ print $hfh "-define($cmd, $ncmd).\n";
2928
+ $ncmd++;
2929
+ }
2930
+
2931
+ for my $func (@$mappings) {
2932
+ next unless $func->{has_get};
2933
+ my $name = $func->{cname};
2934
+ my $cmd = uc $name;
2935
+ my $nargs = 1 + $func->{num_args};
2936
+ print $cfh "#define ESIGAR_$cmd $ncmd\n";
2937
+ print $hfh "-define($cmd, $ncmd).\n";
2938
+ print $hfh "-export([$name/$nargs]).\n";
2939
+ $ncmd++;
2940
+ }
2941
+
2942
+ print $cfh <<EOF;
2943
+
2944
+ static int esigar_dispatch(ErlDrvPort port, sigar_t *sigar, int cmd, char *bytes) {
2945
+ switch (cmd) {
2946
+ EOF
2947
+ for my $func (@$mappings) {
2948
+ next unless $func->{has_get};
2949
+ my $name = $func->{cname};
2950
+ my $cmd = uc $name;
2951
+ my $arg = "";
2952
+ if ($func->{num_args}) {
2953
+ $arg = ", Arg";
2954
+ }
2955
+
2956
+ print $gfh <<EOF;
2957
+ $name({sigar, S}$arg) ->
2958
+ do_command(S, ?$cmd$arg).
2959
+
2960
+ EOF
2961
+ print $cfh <<EOF
2962
+ case ESIGAR_$cmd:
2963
+ return e$func->{sigar_function}(port, sigar, bytes);
2964
+ EOF
2965
+ }
2966
+ print $cfh <<EOF;
2967
+ default:
2968
+ esigar_notimpl(port, sigar, cmd);
2969
+ return SIGAR_ENOTIMPL;
2970
+ }
2971
+ }
2972
+ EOF
2973
+
2974
+ $self->SUPER::finish;
2975
+ }
2976
+
2977
+ 1;
2978
+ __END__