sigar 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -22,7 +22,7 @@ spec = Gem::Specification.new do |s|
22
22
  s.name = GEM
23
23
  # s.version = props['version.major'] + '.' + props['version.minor'] + '.' + props['version.maint']
24
24
  # '0.7.x' until the sigar-1.7.0 release
25
- s.version = '0' + '.' + props['version.minor'] + '.' + '1'
25
+ s.version = '0' + '.' + props['version.minor'] + '.' + '2'
26
26
  s.summary = props['project.summary']
27
27
  s.description = s.summary
28
28
  s.author = props['project.author']
@@ -34,7 +34,7 @@ spec = Gem::Specification.new do |s|
34
34
  s.files =
35
35
  %w(LICENSE NOTICE README Rakefile version.properties) +
36
36
  %w(bindings/SigarWrapper.pm bindings/SigarBuild.pm) +
37
- Dir.glob("bindings/ruby/**/*") +
37
+ `git ls-files -- bindings/ruby/*`.split("\n") +
38
38
  Dir.glob("include/*.h") +
39
39
  Dir.glob("src/**/*.[ch]") +
40
40
  Dir.glob("src/**/*.in")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sigar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -25,8 +25,6 @@ files:
25
25
  - version.properties
26
26
  - bindings/SigarWrapper.pm
27
27
  - bindings/SigarBuild.pm
28
- - bindings/ruby/darwin_sigar.c
29
- - bindings/ruby/darwin_sigar.o
30
28
  - bindings/ruby/examples/arp.rb
31
29
  - bindings/ruby/examples/cpu_info.rb
32
30
  - bindings/ruby/examples/df.rb
@@ -41,29 +39,7 @@ files:
41
39
  - bindings/ruby/examples/version.rb
42
40
  - bindings/ruby/examples/who.rb
43
41
  - bindings/ruby/extconf.rb
44
- - bindings/ruby/Makefile
45
42
  - bindings/ruby/rbsigar.c
46
- - bindings/ruby/rbsigar.o
47
- - bindings/ruby/rbsigar_generated.rx
48
- - bindings/ruby/sigar.bundle
49
- - bindings/ruby/sigar.c
50
- - bindings/ruby/sigar.o
51
- - bindings/ruby/sigar_cache.c
52
- - bindings/ruby/sigar_cache.o
53
- - bindings/ruby/sigar_fileinfo.c
54
- - bindings/ruby/sigar_fileinfo.o
55
- - bindings/ruby/sigar_format.c
56
- - bindings/ruby/sigar_format.o
57
- - bindings/ruby/sigar_getline.c
58
- - bindings/ruby/sigar_getline.o
59
- - bindings/ruby/sigar_ptql.c
60
- - bindings/ruby/sigar_ptql.o
61
- - bindings/ruby/sigar_signal.c
62
- - bindings/ruby/sigar_signal.o
63
- - bindings/ruby/sigar_util.c
64
- - bindings/ruby/sigar_util.o
65
- - bindings/ruby/sigar_version.c
66
- - bindings/ruby/sigar_version.o
67
43
  - bindings/ruby/test/cpu_test.rb
68
44
  - bindings/ruby/test/file_system_test.rb
69
45
  - bindings/ruby/test/helper.rb
@@ -1,187 +0,0 @@
1
-
2
- SHELL = /bin/sh
3
-
4
- #### Start of system configuration section. ####
5
-
6
- srcdir = .
7
- topdir = /Users/dougm/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1
8
- hdrdir = /Users/dougm/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1
9
- arch_hdrdir = /Users/dougm/.rvm/rubies/ruby-1.9.2-p290/include/ruby-1.9.1/$(arch)
10
- VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
11
- prefix = $(DESTDIR)/Users/dougm/.rvm/rubies/ruby-1.9.2-p290
12
- rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
13
- exec_prefix = $(prefix)
14
- vendorhdrdir = $(rubyhdrdir)/vendor_ruby
15
- sitehdrdir = $(rubyhdrdir)/site_ruby
16
- rubyhdrdir = $(includedir)/$(RUBY_BASE_NAME)-$(ruby_version)
17
- vendordir = $(rubylibprefix)/vendor_ruby
18
- sitedir = $(rubylibprefix)/site_ruby
19
- ridir = $(datarootdir)/$(RI_BASE_NAME)
20
- mandir = $(datarootdir)/man
21
- localedir = $(datarootdir)/locale
22
- libdir = $(exec_prefix)/lib
23
- psdir = $(docdir)
24
- pdfdir = $(docdir)
25
- dvidir = $(docdir)
26
- htmldir = $(docdir)
27
- infodir = $(datarootdir)/info
28
- docdir = $(datarootdir)/doc/$(PACKAGE)
29
- oldincludedir = $(DESTDIR)/usr/include
30
- includedir = $(prefix)/include
31
- localstatedir = $(prefix)/var
32
- sharedstatedir = $(prefix)/com
33
- sysconfdir = $(prefix)/etc
34
- datadir = $(datarootdir)
35
- datarootdir = $(prefix)/share
36
- libexecdir = $(exec_prefix)/libexec
37
- sbindir = $(exec_prefix)/sbin
38
- bindir = $(exec_prefix)/bin
39
- rubylibdir = $(rubylibprefix)/$(ruby_version)
40
- archdir = $(rubylibdir)/$(arch)
41
- sitelibdir = $(sitedir)/$(ruby_version)
42
- sitearchdir = $(sitelibdir)/$(sitearch)
43
- vendorlibdir = $(vendordir)/$(ruby_version)
44
- vendorarchdir = $(vendorlibdir)/$(sitearch)
45
-
46
- CC = /usr/bin/gcc-4.2
47
- CXX = g++
48
- LIBRUBY = $(LIBRUBY_SO)
49
- LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
50
- LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
51
- LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static
52
- OUTFLAG = -o
53
- COUTFLAG = -o
54
-
55
- RUBY_EXTCONF_H =
56
- cflags = $(optflags) $(debugflags) $(warnflags)
57
- optflags = -O3
58
- debugflags = -ggdb
59
- warnflags = -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wshorten-64-to-32 -Wno-long-long
60
- CFLAGS = -fno-common $(cflags) -fno-common -pipe
61
- INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
62
- DEFS =
63
- CPPFLAGS = -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE $(DEFS) $(cppflags) -DDARWIN_HAS_LIBPROC_H -DDARWIN -I../../include -I../../src/os/darwin -U_FILE_OFFSET_BITS -DRB_HAS_RE_ERROR -DRB_RUBY_19
64
- CXXFLAGS = $(CFLAGS) $(cxxflags)
65
- ldflags = -L. -framework CoreServices -framework IOKit
66
- dldflags = -Wl,-undefined,dynamic_lookup -Wl,-multiply_defined,suppress -Wl,-flat_namespace
67
- ARCH_FLAG =
68
- DLDFLAGS = $(ldflags) $(dldflags)
69
- LDSHARED = $(CC) -dynamic -bundle
70
- LDSHAREDXX = $(CXX) -dynamic -bundle
71
- AR = ar
72
- EXEEXT =
73
-
74
- RUBY_BASE_NAME = ruby
75
- RUBY_INSTALL_NAME = ruby
76
- RUBY_SO_NAME = ruby.1.9.1
77
- arch = x86_64-darwin10.8.0
78
- sitearch = $(arch)
79
- ruby_version = 1.9.1
80
- ruby = /Users/dougm/.rvm/rubies/ruby-1.9.2-p290/bin/ruby
81
- RUBY = $(ruby)
82
- RM = rm -f
83
- RM_RF = $(RUBY) -run -e rm -- -rf
84
- RMDIRS = $(RUBY) -run -e rmdir -- -p
85
- MAKEDIRS = /usr/local/bin/gmkdir -p
86
- INSTALL = /usr/local/bin/ginstall -c
87
- INSTALL_PROG = $(INSTALL) -m 0755
88
- INSTALL_DATA = $(INSTALL) -m 644
89
- COPY = cp
90
-
91
- #### End of system configuration section. ####
92
-
93
- preload =
94
-
95
- libpath = . $(libdir)
96
- LIBPATH = -L. -L$(libdir)
97
- DEFFILE =
98
-
99
- CLEANFILES = mkmf.log
100
- DISTCLEANFILES = rbsigar_generated.rx sigar_version.c sigar.c sigar_cache.c sigar_fileinfo.c sigar_format.c sigar_getline.c sigar_ptql.c sigar_signal.c sigar_util.c darwin_sigar.c
101
- DISTCLEANDIRS =
102
-
103
- extout =
104
- extout_prefix =
105
- target_prefix =
106
- LOCAL_LIBS =
107
- LIBS = $(LIBRUBYARG_SHARED) -lpthread -ldl -lobjc
108
- SRCS = darwin_sigar.c rbsigar.c sigar.c sigar_cache.c sigar_fileinfo.c sigar_format.c sigar_getline.c sigar_ptql.c sigar_signal.c sigar_util.c sigar_version.c
109
- OBJS = darwin_sigar.o rbsigar.o sigar.o sigar_cache.o sigar_fileinfo.o sigar_format.o sigar_getline.o sigar_ptql.o sigar_signal.o sigar_util.o sigar_version.o
110
- TARGET = sigar
111
- DLLIB = $(TARGET).bundle
112
- EXTSTATIC =
113
- STATIC_LIB =
114
-
115
- BINDIR = $(bindir)
116
- RUBYCOMMONDIR = $(sitedir)$(target_prefix)
117
- RUBYLIBDIR = $(sitelibdir)$(target_prefix)
118
- RUBYARCHDIR = $(sitearchdir)$(target_prefix)
119
- HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
120
- ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
121
-
122
- TARGET_SO = $(DLLIB)
123
- CLEANLIBS = $(TARGET).bundle
124
- CLEANOBJS = *.o *.bak
125
-
126
- all: $(DLLIB)
127
- static: $(STATIC_LIB)
128
- .PHONY: all install static install-so install-rb
129
- .PHONY: clean clean-so clean-rb
130
-
131
- clean-rb-default::
132
- clean-rb::
133
- clean-so::
134
- clean: clean-so clean-rb-default clean-rb
135
- @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES)
136
-
137
- distclean-rb-default::
138
- distclean-rb::
139
- distclean-so::
140
- distclean: clean distclean-so distclean-rb-default distclean-rb
141
- @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
142
- @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
143
- @-$(RMDIRS) $(DISTCLEANDIRS)
144
-
145
- realclean: distclean
146
- install: install-so install-rb
147
-
148
- install-so: $(RUBYARCHDIR)
149
- install-so: $(RUBYARCHDIR)/$(DLLIB)
150
- $(RUBYARCHDIR)/$(DLLIB): $(DLLIB)
151
- @-$(MAKEDIRS) $(@D)
152
- $(INSTALL_PROG) $(DLLIB) $(@D)
153
- install-rb: pre-install-rb install-rb-default
154
- install-rb-default: pre-install-rb-default
155
- pre-install-rb: Makefile
156
- pre-install-rb-default: Makefile
157
- $(RUBYARCHDIR):
158
- $(MAKEDIRS) $@
159
-
160
- site-install: site-install-so site-install-rb
161
- site-install-so: install-so
162
- site-install-rb: install-rb
163
-
164
- .SUFFIXES: .c .m .cc .cxx .cpp .C .o
165
-
166
- .cc.o:
167
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
168
-
169
- .cxx.o:
170
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
171
-
172
- .cpp.o:
173
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
174
-
175
- .C.o:
176
- $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
177
-
178
- .c.o:
179
- $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
180
-
181
- $(DLLIB): $(OBJS) Makefile
182
- @-$(RM) $(@)
183
- $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
184
-
185
-
186
-
187
- $(OBJS): $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
@@ -1,3711 +0,0 @@
1
- /*
2
- * Copyright (c) 2004-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
- #include "sigar.h"
20
- #include "sigar_private.h"
21
- #include "sigar_util.h"
22
- #include "sigar_os.h"
23
-
24
- #include <sys/param.h>
25
- #include <sys/mount.h>
26
- #if !(defined(__FreeBSD__) && (__FreeBSD_version >= 800000))
27
- #include <nfs/rpcv2.h>
28
- #endif
29
- #include <nfs/nfsproto.h>
30
-
31
- #ifdef DARWIN
32
- #include <dlfcn.h>
33
- #include <mach/mach_init.h>
34
- #include <mach/message.h>
35
- #include <mach/kern_return.h>
36
- #include <mach/mach_host.h>
37
- #include <mach/mach_traps.h>
38
- #include <mach/mach_port.h>
39
- #include <mach/task.h>
40
- #include <mach/thread_act.h>
41
- #include <mach/thread_info.h>
42
- #include <mach/vm_map.h>
43
- #if !defined(HAVE_SHARED_REGION_H) && defined(__MAC_10_5) /* see Availability.h */
44
- # define HAVE_SHARED_REGION_H /* suckit autoconf */
45
- #endif
46
- #ifdef HAVE_SHARED_REGION_H
47
- #include <mach/shared_region.h> /* does not exist in 10.4 SDK */
48
- #else
49
- #include <mach/shared_memory_server.h> /* deprecated in Leopard */
50
- #endif
51
- #include <mach-o/dyld.h>
52
- #define __OPENTRANSPORTPROVIDERS__
53
- #include <CoreServices/CoreServices.h>
54
- #include <CoreFoundation/CoreFoundation.h>
55
- #include <IOKit/IOBSD.h>
56
- #include <IOKit/IOKitLib.h>
57
- #include <IOKit/IOTypes.h>
58
- #include <IOKit/storage/IOBlockStorageDriver.h>
59
- #else
60
- #include <sys/dkstat.h>
61
- #include <sys/types.h>
62
- #include <sys/param.h>
63
- #include <sys/user.h>
64
- #include <sys/vmmeter.h>
65
- #include <fcntl.h>
66
- #include <stdio.h>
67
- #endif
68
-
69
- #if defined(__FreeBSD__) && (__FreeBSD_version >= 500013)
70
- #define SIGAR_FREEBSD5_NFSSTAT
71
- #include <nfsclient/nfs.h>
72
- #include <nfsserver/nfs.h>
73
- #else
74
- #include <nfs/nfs.h>
75
- #endif
76
-
77
- #include <sys/ioctl.h>
78
- #include <sys/mount.h>
79
- #include <sys/resource.h>
80
- #include <sys/stat.h>
81
- #include <sys/socket.h>
82
- #include <sys/sockio.h>
83
-
84
- #include <net/if.h>
85
- #include <net/if_dl.h>
86
- #include <net/if_types.h>
87
- #include <net/route.h>
88
- #include <netinet/in.h>
89
- #include <netinet/if_ether.h>
90
-
91
- #include <dirent.h>
92
- #include <errno.h>
93
-
94
- #include <sys/socketvar.h>
95
- #include <netinet/in.h>
96
- #include <netinet/in_systm.h>
97
- #include <netinet/ip.h>
98
- #include <netinet/in_pcb.h>
99
- #include <netinet/tcp.h>
100
- #include <netinet/tcp_timer.h>
101
- #ifdef __NetBSD__
102
- #include <netinet/ip_var.h>
103
- #include <sys/lwp.h>
104
- #include <sys/mount.h>
105
- #define SRUN LSRUN
106
- #define SSLEEP LSSLEEP
107
- #define SDEAD LSDEAD
108
- #define SONPROC LSONPROC
109
- #define SSUSPENDED LSSUSPENDED
110
- #include <sys/sched.h>
111
- #endif
112
- #include <netinet/tcp_var.h>
113
- #include <netinet/tcp_fsm.h>
114
-
115
- #define NMIB(mib) (sizeof(mib)/sizeof(mib[0]))
116
-
117
- #ifdef __FreeBSD__
118
- # if (__FreeBSD_version >= 500013)
119
- # define SIGAR_FREEBSD5
120
- # else
121
- # define SIGAR_FREEBSD4
122
- # endif
123
- #endif
124
-
125
- #if defined(SIGAR_FREEBSD5)
126
-
127
- #define KI_FD ki_fd
128
- #define KI_PID ki_pid
129
- #define KI_PPID ki_ppid
130
- #define KI_PRI ki_pri.pri_user
131
- #define KI_NICE ki_nice
132
- #define KI_COMM ki_comm
133
- #define KI_STAT ki_stat
134
- #define KI_UID ki_ruid
135
- #define KI_GID ki_rgid
136
- #define KI_EUID ki_svuid
137
- #define KI_EGID ki_svgid
138
- #define KI_SIZE ki_size
139
- #define KI_RSS ki_rssize
140
- #define KI_TSZ ki_tsize
141
- #define KI_DSZ ki_dsize
142
- #define KI_SSZ ki_ssize
143
- #define KI_FLAG ki_flag
144
- #define KI_START ki_start
145
-
146
- #elif defined(DARWIN) || defined(SIGAR_FREEBSD4) || defined(__OpenBSD__) || defined(__NetBSD__)
147
-
148
- #define KI_FD kp_proc.p_fd
149
- #define KI_PID kp_proc.p_pid
150
- #define KI_PPID kp_eproc.e_ppid
151
- #define KI_PRI kp_proc.p_priority
152
- #define KI_NICE kp_proc.p_nice
153
- #define KI_COMM kp_proc.p_comm
154
- #define KI_STAT kp_proc.p_stat
155
- #define KI_UID kp_eproc.e_pcred.p_ruid
156
- #define KI_GID kp_eproc.e_pcred.p_rgid
157
- #define KI_EUID kp_eproc.e_pcred.p_svuid
158
- #define KI_EGID kp_eproc.e_pcred.p_svgid
159
- #define KI_SIZE XXX
160
- #define KI_RSS kp_eproc.e_vm.vm_rssize
161
- #define KI_TSZ kp_eproc.e_vm.vm_tsize
162
- #define KI_DSZ kp_eproc.e_vm.vm_dsize
163
- #define KI_SSZ kp_eproc.e_vm.vm_ssize
164
- #define KI_FLAG kp_eproc.e_flag
165
- #define KI_START kp_proc.p_starttime
166
-
167
- #endif
168
-
169
- #ifndef DARWIN
170
-
171
- #define PROCFS_STATUS(status) \
172
- ((((status) != SIGAR_OK) && !sigar->proc_mounted) ? \
173
- SIGAR_ENOTIMPL : status)
174
-
175
- static int get_koffsets(sigar_t *sigar)
176
- {
177
- int i;
178
- struct nlist klist[] = {
179
- { "_cp_time" },
180
- { "_cnt" },
181
- #if defined(__OpenBSD__) || defined(__NetBSD__)
182
- { "_tcpstat" },
183
- { "_tcbtable" },
184
- #endif
185
- { NULL }
186
- };
187
-
188
- if (!sigar->kmem) {
189
- return SIGAR_EPERM_KMEM;
190
- }
191
-
192
- kvm_nlist(sigar->kmem, klist);
193
-
194
- for (i=0; i<KOFFSET_MAX; i++) {
195
- sigar->koffsets[i] = klist[i].n_value;
196
- }
197
-
198
- return SIGAR_OK;
199
- }
200
-
201
- static int kread(sigar_t *sigar, void *data, int size, long offset)
202
- {
203
- if (!sigar->kmem) {
204
- return SIGAR_EPERM_KMEM;
205
- }
206
-
207
- if (kvm_read(sigar->kmem, offset, data, size) != size) {
208
- return errno;
209
- }
210
-
211
- return SIGAR_OK;
212
- }
213
- #endif
214
-
215
- int sigar_os_open(sigar_t **sigar)
216
- {
217
- int mib[2];
218
- int ncpu;
219
- size_t len;
220
- struct timeval boottime;
221
- #ifndef DARWIN
222
- struct stat sb;
223
- #endif
224
-
225
- len = sizeof(ncpu);
226
- mib[0] = CTL_HW;
227
- mib[1] = HW_NCPU;
228
- if (sysctl(mib, NMIB(mib), &ncpu, &len, NULL, 0) < 0) {
229
- return errno;
230
- }
231
-
232
- len = sizeof(boottime);
233
- mib[0] = CTL_KERN;
234
- mib[1] = KERN_BOOTTIME;
235
- if (sysctl(mib, NMIB(mib), &boottime, &len, NULL, 0) < 0) {
236
- return errno;
237
- }
238
-
239
- *sigar = malloc(sizeof(**sigar));
240
-
241
- #ifdef DARWIN
242
- (*sigar)->mach_port = mach_host_self();
243
- # ifdef DARWIN_HAS_LIBPROC_H
244
- if (((*sigar)->libproc = dlopen("/usr/lib/libproc.dylib", 0))) {
245
- (*sigar)->proc_pidinfo = dlsym((*sigar)->libproc, "proc_pidinfo");
246
- (*sigar)->proc_pidfdinfo = dlsym((*sigar)->libproc, "proc_pidfdinfo");
247
- }
248
- # endif
249
- #else
250
- (*sigar)->kmem = kvm_open(NULL, NULL, NULL, O_RDONLY, NULL);
251
- if (stat("/proc/curproc", &sb) < 0) {
252
- (*sigar)->proc_mounted = 0;
253
- }
254
- else {
255
- (*sigar)->proc_mounted = 1;
256
- }
257
- #endif
258
-
259
- #ifndef DARWIN
260
- get_koffsets(*sigar);
261
- #endif
262
-
263
- (*sigar)->ncpu = ncpu;
264
- (*sigar)->lcpu = -1;
265
- (*sigar)->argmax = 0;
266
- (*sigar)->boot_time = boottime.tv_sec; /* XXX seems off a bit */
267
-
268
- (*sigar)->pagesize = getpagesize();
269
- #ifdef __FreeBSD__
270
- (*sigar)->ticks = 100; /* sysconf(_SC_CLK_TCK) == 128 !? */
271
- #else
272
- (*sigar)->ticks = sysconf(_SC_CLK_TCK);
273
- #endif
274
- (*sigar)->last_pid = -1;
275
-
276
- (*sigar)->pinfo = NULL;
277
-
278
- return SIGAR_OK;
279
- }
280
-
281
- int sigar_os_close(sigar_t *sigar)
282
- {
283
- if (sigar->pinfo) {
284
- free(sigar->pinfo);
285
- }
286
- #ifndef DARWIN
287
- if (sigar->kmem) {
288
- kvm_close(sigar->kmem);
289
- }
290
- #endif
291
- free(sigar);
292
- return SIGAR_OK;
293
- }
294
-
295
- char *sigar_os_error_string(sigar_t *sigar, int err)
296
- {
297
- switch (err) {
298
- case SIGAR_EPERM_KMEM:
299
- return "Failed to open /dev/kmem for reading";
300
- case SIGAR_EPROC_NOENT:
301
- return "/proc filesystem is not mounted";
302
- default:
303
- return NULL;
304
- }
305
- }
306
-
307
- /* ARG_MAX in FreeBSD 6.0 == 262144, which blows up the stack */
308
- #define SIGAR_ARG_MAX 65536
309
-
310
- #ifdef DARWIN
311
- static size_t sigar_argmax_get(sigar_t *sigar)
312
- {
313
- #ifdef KERN_ARGMAX
314
- int mib[] = { CTL_KERN, KERN_ARGMAX };
315
- size_t size = sizeof(sigar->argmax);
316
-
317
- if (sigar->argmax != 0) {
318
- return sigar->argmax;
319
- }
320
- if (sysctl(mib, NMIB(mib), &sigar->argmax, &size, NULL, 0) == 0) {
321
- return sigar->argmax;
322
- }
323
- #endif
324
- return SIGAR_ARG_MAX;
325
- }
326
- #endif /* DARWIN */
327
-
328
- #if defined(DARWIN)
329
- static int sigar_vmstat(sigar_t *sigar, vm_statistics_data_t *vmstat)
330
- {
331
- kern_return_t status;
332
- mach_msg_type_number_t count = sizeof(*vmstat) / sizeof(integer_t);
333
-
334
- status = host_statistics(sigar->mach_port, HOST_VM_INFO,
335
- (host_info_t)vmstat, &count);
336
-
337
- if (status == KERN_SUCCESS) {
338
- return SIGAR_OK;
339
- }
340
- else {
341
- return errno;
342
- }
343
- }
344
- #elif defined(__FreeBSD__)
345
- static int sigar_vmstat(sigar_t *sigar, struct vmmeter *vmstat)
346
- {
347
- int status;
348
- size_t size = sizeof(unsigned int);
349
-
350
- status = kread(sigar, vmstat, sizeof(*vmstat),
351
- sigar->koffsets[KOFFSET_VMMETER]);
352
-
353
- if (status == SIGAR_OK) {
354
- return SIGAR_OK;
355
- }
356
-
357
- SIGAR_ZERO(vmstat);
358
-
359
- /* derived from src/usr.bin/vmstat/vmstat.c */
360
- /* only collect the ones we actually use */
361
- #define GET_VM_STATS(cat, name, used) \
362
- if (used) sysctlbyname("vm.stats." #cat "." #name, &vmstat->name, &size, NULL, 0)
363
-
364
- /* sys */
365
- GET_VM_STATS(sys, v_swtch, 0);
366
- GET_VM_STATS(sys, v_trap, 0);
367
- GET_VM_STATS(sys, v_syscall, 0);
368
- GET_VM_STATS(sys, v_intr, 0);
369
- GET_VM_STATS(sys, v_soft, 0);
370
-
371
- /* vm */
372
- GET_VM_STATS(vm, v_vm_faults, 0);
373
- GET_VM_STATS(vm, v_cow_faults, 0);
374
- GET_VM_STATS(vm, v_cow_optim, 0);
375
- GET_VM_STATS(vm, v_zfod, 0);
376
- GET_VM_STATS(vm, v_ozfod, 0);
377
- GET_VM_STATS(vm, v_swapin, 1);
378
- GET_VM_STATS(vm, v_swapout, 1);
379
- GET_VM_STATS(vm, v_swappgsin, 0);
380
- GET_VM_STATS(vm, v_swappgsout, 0);
381
- GET_VM_STATS(vm, v_vnodein, 1);
382
- GET_VM_STATS(vm, v_vnodeout, 1);
383
- GET_VM_STATS(vm, v_vnodepgsin, 0);
384
- GET_VM_STATS(vm, v_vnodepgsout, 0);
385
- GET_VM_STATS(vm, v_intrans, 0);
386
- GET_VM_STATS(vm, v_reactivated, 0);
387
- GET_VM_STATS(vm, v_pdwakeups, 0);
388
- GET_VM_STATS(vm, v_pdpages, 0);
389
- GET_VM_STATS(vm, v_dfree, 0);
390
- GET_VM_STATS(vm, v_pfree, 0);
391
- GET_VM_STATS(vm, v_tfree, 0);
392
- GET_VM_STATS(vm, v_page_size, 0);
393
- GET_VM_STATS(vm, v_page_count, 0);
394
- GET_VM_STATS(vm, v_free_reserved, 0);
395
- GET_VM_STATS(vm, v_free_target, 0);
396
- GET_VM_STATS(vm, v_free_min, 0);
397
- GET_VM_STATS(vm, v_free_count, 1);
398
- GET_VM_STATS(vm, v_wire_count, 0);
399
- GET_VM_STATS(vm, v_active_count, 0);
400
- GET_VM_STATS(vm, v_inactive_target, 0);
401
- GET_VM_STATS(vm, v_inactive_count, 1);
402
- GET_VM_STATS(vm, v_cache_count, 1);
403
- GET_VM_STATS(vm, v_cache_min, 0);
404
- GET_VM_STATS(vm, v_cache_max, 0);
405
- GET_VM_STATS(vm, v_pageout_free_min, 0);
406
- GET_VM_STATS(vm, v_interrupt_free_min, 0);
407
- GET_VM_STATS(vm, v_forks, 0);
408
- GET_VM_STATS(vm, v_vforks, 0);
409
- GET_VM_STATS(vm, v_rforks, 0);
410
- GET_VM_STATS(vm, v_kthreads, 0);
411
- GET_VM_STATS(vm, v_forkpages, 0);
412
- GET_VM_STATS(vm, v_vforkpages, 0);
413
- GET_VM_STATS(vm, v_rforkpages, 0);
414
- GET_VM_STATS(vm, v_kthreadpages, 0);
415
- #undef GET_VM_STATS
416
-
417
- return SIGAR_OK;
418
- }
419
- #elif defined(__OpenBSD__) || defined(__NetBSD__)
420
- static int sigar_vmstat(sigar_t *sigar, struct uvmexp *vmstat)
421
- {
422
- size_t size = sizeof(*vmstat);
423
- int mib[] = { CTL_VM, VM_UVMEXP };
424
- if (sysctl(mib, NMIB(mib), vmstat, &size, NULL, 0) < 0) {
425
- return errno;
426
- }
427
- else {
428
- return SIGAR_OK;
429
- }
430
- }
431
- #endif
432
-
433
- int sigar_mem_get(sigar_t *sigar, sigar_mem_t *mem)
434
- {
435
- sigar_uint64_t kern = 0;
436
- #ifdef DARWIN
437
- vm_statistics_data_t vmstat;
438
- uint64_t mem_total;
439
- #else
440
- unsigned long mem_total;
441
- #endif
442
- #if defined(__FreeBSD__)
443
- struct vmmeter vmstat;
444
- #elif defined(__OpenBSD__) || defined(__NetBSD__)
445
- struct uvmexp vmstat;
446
- #endif
447
- int mib[2];
448
- size_t len;
449
- int status;
450
-
451
- mib[0] = CTL_HW;
452
-
453
- mib[1] = HW_PAGESIZE;
454
- len = sizeof(sigar->pagesize);
455
- if (sysctl(mib, NMIB(mib), &sigar->pagesize, &len, NULL, 0) < 0) {
456
- return errno;
457
- }
458
-
459
- #ifdef DARWIN
460
- mib[1] = HW_MEMSIZE;
461
- #else
462
- mib[1] = HW_PHYSMEM;
463
- #endif
464
- len = sizeof(mem_total);
465
- if (sysctl(mib, NMIB(mib), &mem_total, &len, NULL, 0) < 0) {
466
- return errno;
467
- }
468
-
469
- mem->total = mem_total;
470
-
471
- #if defined(DARWIN)
472
- if ((status = sigar_vmstat(sigar, &vmstat)) != SIGAR_OK) {
473
- return status;
474
- }
475
-
476
- mem->free = vmstat.free_count;
477
- mem->free *= sigar->pagesize;
478
- kern = vmstat.inactive_count;
479
- kern *= sigar->pagesize;
480
- #elif defined(__FreeBSD__)
481
- if ((status = sigar_vmstat(sigar, &vmstat)) == SIGAR_OK) {
482
- kern = vmstat.v_cache_count + vmstat.v_inactive_count;
483
- kern *= sigar->pagesize;
484
- mem->free = vmstat.v_free_count;
485
- mem->free *= sigar->pagesize;
486
- }
487
- #elif defined(__OpenBSD__) || defined(__NetBSD__)
488
- if ((status = sigar_vmstat(sigar, &vmstat)) != SIGAR_OK) {
489
- return status;
490
- }
491
- mem->free = vmstat.free;
492
- kern = vmstat.inactive;
493
- # if defined(__OpenBSD__)
494
- kern += vmstat.vnodepages + vmstat.vtextpages;
495
- # elif defined(__NetBSD__)
496
- kern += vmstat.filepages + vmstat.execpages;
497
- # endif
498
- kern *= sigar->pagesize;
499
- #endif
500
-
501
- mem->used = mem->total - mem->free;
502
-
503
- mem->actual_free = mem->free + kern;
504
- mem->actual_used = mem->used - kern;
505
-
506
- sigar_mem_calc_ram(sigar, mem);
507
-
508
- return SIGAR_OK;
509
- }
510
-
511
- #define SWI_MAXMIB 3
512
-
513
- #ifdef SIGAR_FREEBSD5
514
- /* code in this function is based on FreeBSD 5.3 kvm_getswapinfo.c */
515
- static int getswapinfo_sysctl(struct kvm_swap *swap_ary,
516
- int swap_max)
517
- {
518
- int ti, ttl;
519
- size_t mibi, len, size;
520
- int soid[SWI_MAXMIB];
521
- struct xswdev xsd;
522
- struct kvm_swap tot;
523
- int unswdev, dmmax;
524
-
525
- /* XXX this can be optimized by using os_open */
526
- size = sizeof(dmmax);
527
- if (sysctlbyname("vm.dmmax", &dmmax, &size, NULL, 0) == -1) {
528
- return errno;
529
- }
530
-
531
- mibi = SWI_MAXMIB - 1;
532
- if (sysctlnametomib("vm.swap_info", soid, &mibi) == -1) {
533
- return errno;
534
- }
535
-
536
- bzero(&tot, sizeof(tot));
537
- for (unswdev = 0;; unswdev++) {
538
- soid[mibi] = unswdev;
539
- len = sizeof(xsd);
540
- if (sysctl(soid, mibi + 1, &xsd, &len, NULL, 0) == -1) {
541
- if (errno == ENOENT) {
542
- break;
543
- }
544
- return errno;
545
- }
546
- #if 0
547
- if (len != sizeof(xsd)) {
548
- _kvm_err(kd, kd->program, "struct xswdev has unexpected "
549
- "size; kernel and libkvm out of sync?");
550
- return -1;
551
- }
552
- if (xsd.xsw_version != XSWDEV_VERSION) {
553
- _kvm_err(kd, kd->program, "struct xswdev version "
554
- "mismatch; kernel and libkvm out of sync?");
555
- return -1;
556
- }
557
- #endif
558
- ttl = xsd.xsw_nblks - dmmax;
559
- if (unswdev < swap_max - 1) {
560
- bzero(&swap_ary[unswdev], sizeof(swap_ary[unswdev]));
561
- swap_ary[unswdev].ksw_total = ttl;
562
- swap_ary[unswdev].ksw_used = xsd.xsw_used;
563
- swap_ary[unswdev].ksw_flags = xsd.xsw_flags;
564
- }
565
- tot.ksw_total += ttl;
566
- tot.ksw_used += xsd.xsw_used;
567
- }
568
-
569
- ti = unswdev;
570
- if (ti >= swap_max) {
571
- ti = swap_max - 1;
572
- }
573
- if (ti >= 0) {
574
- swap_ary[ti] = tot;
575
- }
576
-
577
- return SIGAR_OK;
578
- }
579
- #else
580
- #define getswapinfo_sysctl(swap_ary, swap_max) SIGAR_ENOTIMPL
581
- #endif
582
-
583
- #define SIGAR_FS_BLOCKS_TO_BYTES(val, bsize) ((val * bsize) >> 1)
584
-
585
- #ifdef DARWIN
586
- #define VM_DIR "/private/var/vm"
587
- #define SWAPFILE "swapfile"
588
-
589
- static int sigar_swap_fs_get(sigar_t *sigar, sigar_swap_t *swap) /* <= 10.3 */
590
- {
591
- DIR *dirp;
592
- struct dirent *ent;
593
- char swapfile[SSTRLEN(VM_DIR) + SSTRLEN("/") + SSTRLEN(SWAPFILE) + 12];
594
- struct stat swapstat;
595
- struct statfs vmfs;
596
- sigar_uint64_t val, bsize;
597
-
598
- swap->used = swap->total = swap->free = 0;
599
-
600
- if (!(dirp = opendir(VM_DIR))) {
601
- return errno;
602
- }
603
-
604
- /* looking for "swapfile0", "swapfile1", etc. */
605
- while ((ent = readdir(dirp))) {
606
- char *ptr = swapfile;
607
-
608
- if ((ent->d_namlen < SSTRLEN(SWAPFILE)+1) || /* n/a, see comment above */
609
- (ent->d_namlen > SSTRLEN(SWAPFILE)+11)) /* ensure no overflow */
610
- {
611
- continue;
612
- }
613
-
614
- if (!strnEQ(ent->d_name, SWAPFILE, SSTRLEN(SWAPFILE))) {
615
- continue;
616
- }
617
-
618
- /* sprintf(swapfile, "%s/%s", VM_DIR, ent->d_name) */
619
-
620
- memcpy(ptr, VM_DIR, SSTRLEN(VM_DIR));
621
- ptr += SSTRLEN(VM_DIR);
622
-
623
- *ptr++ = '/';
624
-
625
- memcpy(ptr, ent->d_name, ent->d_namlen+1);
626
-
627
- if (stat(swapfile, &swapstat) < 0) {
628
- continue;
629
- }
630
-
631
- swap->used += swapstat.st_size;
632
- }
633
-
634
- closedir(dirp);
635
-
636
- if (statfs(VM_DIR, &vmfs) < 0) {
637
- return errno;
638
- }
639
-
640
- bsize = vmfs.f_bsize / 512;
641
- val = vmfs.f_bfree;
642
- swap->total = SIGAR_FS_BLOCKS_TO_BYTES(val, bsize) + swap->used;
643
-
644
- swap->free = swap->total - swap->used;
645
-
646
- return SIGAR_OK;
647
- }
648
-
649
- static int sigar_swap_sysctl_get(sigar_t *sigar, sigar_swap_t *swap)
650
-
651
- {
652
- #ifdef VM_SWAPUSAGE /* => 10.4 */
653
- struct xsw_usage sw_usage;
654
- size_t size = sizeof(sw_usage);
655
- int mib[] = { CTL_VM, VM_SWAPUSAGE };
656
-
657
- if (sysctl(mib, NMIB(mib), &sw_usage, &size, NULL, 0) != 0) {
658
- return errno;
659
- }
660
-
661
- swap->total = sw_usage.xsu_total;
662
- swap->used = sw_usage.xsu_used;
663
- swap->free = sw_usage.xsu_avail;
664
-
665
- return SIGAR_OK;
666
- #else
667
- return SIGAR_ENOTIMPL; /* <= 10.3 */
668
- #endif
669
- }
670
- #endif /* DARWIN */
671
-
672
- int sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap)
673
- {
674
- int status;
675
- #if defined(DARWIN)
676
- vm_statistics_data_t vmstat;
677
-
678
- if (sigar_swap_sysctl_get(sigar, swap) != SIGAR_OK) {
679
- status = sigar_swap_fs_get(sigar, swap); /* <= 10.3 */
680
- if (status != SIGAR_OK) {
681
- return status;
682
- }
683
- }
684
-
685
- if ((status = sigar_vmstat(sigar, &vmstat)) != SIGAR_OK) {
686
- return status;
687
- }
688
- swap->page_in = vmstat.pageins;
689
- swap->page_out = vmstat.pageouts;
690
- #elif defined(__FreeBSD__)
691
- struct kvm_swap kswap[1];
692
- struct vmmeter vmstat;
693
-
694
- if (getswapinfo_sysctl(kswap, 1) != SIGAR_OK) {
695
- if (!sigar->kmem) {
696
- return SIGAR_EPERM_KMEM;
697
- }
698
-
699
- if (kvm_getswapinfo(sigar->kmem, kswap, 1, 0) < 0) {
700
- return errno;
701
- }
702
- }
703
-
704
- if (kswap[0].ksw_total == 0) {
705
- swap->total = 0;
706
- swap->used = 0;
707
- swap->free = 0;
708
- return SIGAR_OK;
709
- }
710
-
711
- swap->total = kswap[0].ksw_total * sigar->pagesize;
712
- swap->used = kswap[0].ksw_used * sigar->pagesize;
713
- swap->free = swap->total - swap->used;
714
-
715
- if ((status = sigar_vmstat(sigar, &vmstat)) == SIGAR_OK) {
716
- swap->page_in = vmstat.v_swapin + vmstat.v_vnodein;
717
- swap->page_out = vmstat.v_swapout + vmstat.v_vnodeout;
718
- }
719
- else {
720
- swap->page_in = swap->page_out = -1;
721
- }
722
- #elif defined(__OpenBSD__) || defined(__NetBSD__)
723
- struct uvmexp vmstat;
724
-
725
- if ((status = sigar_vmstat(sigar, &vmstat)) != SIGAR_OK) {
726
- return status;
727
- }
728
- swap->total = vmstat.swpages * sigar->pagesize;
729
- swap->used = vmstat.swpginuse * sigar->pagesize;
730
- swap->free = swap->total - swap->used;
731
- swap->page_in = vmstat.pageins;
732
- swap->page_out = vmstat.pdpageouts;
733
- #endif
734
-
735
- return SIGAR_OK;
736
- }
737
-
738
- #ifndef KERN_CPTIME
739
- #define KERN_CPTIME KERN_CP_TIME
740
- #endif
741
-
742
- #if defined(__NetBSD__)
743
- typedef uint64_t cp_time_t;
744
- #else
745
- typedef unsigned long cp_time_t;
746
- #endif
747
-
748
- int sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
749
- {
750
- #if defined(DARWIN)
751
- kern_return_t status;
752
- mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
753
- host_cpu_load_info_data_t cpuload;
754
-
755
- status = host_statistics(sigar->mach_port, HOST_CPU_LOAD_INFO,
756
- (host_info_t)&cpuload, &count);
757
-
758
- if (status != KERN_SUCCESS) {
759
- return errno;
760
- }
761
-
762
- cpu->user = SIGAR_TICK2MSEC(cpuload.cpu_ticks[CPU_STATE_USER]);
763
- cpu->sys = SIGAR_TICK2MSEC(cpuload.cpu_ticks[CPU_STATE_SYSTEM]);
764
- cpu->idle = SIGAR_TICK2MSEC(cpuload.cpu_ticks[CPU_STATE_IDLE]);
765
- cpu->nice = SIGAR_TICK2MSEC(cpuload.cpu_ticks[CPU_STATE_NICE]);
766
- cpu->wait = 0; /*N/A*/
767
- cpu->irq = 0; /*N/A*/
768
- cpu->soft_irq = 0; /*N/A*/
769
- cpu->stolen = 0; /*N/A*/
770
- cpu->total = cpu->user + cpu->nice + cpu->sys + cpu->idle;
771
-
772
- #elif defined(__FreeBSD__) || (__OpenBSD__) || defined(__NetBSD__)
773
- int status;
774
- cp_time_t cp_time[CPUSTATES];
775
- size_t size = sizeof(cp_time);
776
-
777
- # if defined(__OpenBSD__) || defined(__NetBSD__)
778
- int mib[] = { CTL_KERN, KERN_CPTIME };
779
- if (sysctl(mib, NMIB(mib), &cp_time, &size, NULL, 0) == -1) {
780
- status = errno;
781
- }
782
- # else
783
- /* try sysctl first, does not require /dev/kmem perms */
784
- if (sysctlbyname("kern.cp_time", &cp_time, &size, NULL, 0) == -1) {
785
- status = kread(sigar, &cp_time, sizeof(cp_time),
786
- sigar->koffsets[KOFFSET_CPUINFO]);
787
- }
788
- # endif
789
- else {
790
- status = SIGAR_OK;
791
- }
792
-
793
- if (status != SIGAR_OK) {
794
- return status;
795
- }
796
-
797
- cpu->user = SIGAR_TICK2MSEC(cp_time[CP_USER]);
798
- cpu->nice = SIGAR_TICK2MSEC(cp_time[CP_NICE]);
799
- cpu->sys = SIGAR_TICK2MSEC(cp_time[CP_SYS]);
800
- cpu->idle = SIGAR_TICK2MSEC(cp_time[CP_IDLE]);
801
- cpu->wait = 0; /*N/A*/
802
- cpu->irq = SIGAR_TICK2MSEC(cp_time[CP_INTR]);
803
- cpu->soft_irq = 0; /*N/A*/
804
- cpu->stolen = 0; /*N/A*/
805
- cpu->total = cpu->user + cpu->nice + cpu->sys + cpu->idle + cpu->irq;
806
- #endif
807
-
808
- return SIGAR_OK;
809
- }
810
-
811
- #if defined(__FreeBSD__) && (__FreeBSD_version >= 700000)
812
- #define HAVE_KERN_CP_TIMES /* kern.cp_times came later than 7.0, not sure exactly when */
813
- static int sigar_cp_times_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
814
- {
815
- int maxcpu, status;
816
- size_t len = sizeof(maxcpu), size;
817
- long *times;
818
-
819
- if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &len, NULL, 0) == -1) {
820
- return errno;
821
- }
822
-
823
- size = sizeof(long) * maxcpu * CPUSTATES;
824
- times = malloc(size);
825
- if (sysctlbyname("kern.cp_times", times, &size, NULL, 0) == -1) {
826
- status = errno;
827
- }
828
- else {
829
- int i, maxid = (size / CPUSTATES / sizeof(long));
830
- long *cp_time = times;
831
- status = SIGAR_OK;
832
-
833
- for (i=0; i<maxid; i++) {
834
- sigar_cpu_t *cpu;
835
-
836
- SIGAR_CPU_LIST_GROW(cpulist);
837
-
838
- cpu = &cpulist->data[cpulist->number++];
839
- cpu->user = SIGAR_TICK2MSEC(cp_time[CP_USER]);
840
- cpu->nice = SIGAR_TICK2MSEC(cp_time[CP_NICE]);
841
- cpu->sys = SIGAR_TICK2MSEC(cp_time[CP_SYS]);
842
- cpu->idle = SIGAR_TICK2MSEC(cp_time[CP_IDLE]);
843
- cpu->wait = 0; /*N/A*/
844
- cpu->irq = SIGAR_TICK2MSEC(cp_time[CP_INTR]);
845
- cpu->soft_irq = 0; /*N/A*/
846
- cpu->stolen = 0; /*N/A*/
847
- cpu->total = cpu->user + cpu->nice + cpu->sys + cpu->idle + cpu->irq;
848
- cp_time += CPUSTATES;
849
- }
850
- }
851
-
852
- free(times);
853
- return status;
854
- }
855
- #endif
856
-
857
- int sigar_cpu_list_get(sigar_t *sigar, sigar_cpu_list_t *cpulist)
858
- {
859
- #ifdef DARWIN
860
- kern_return_t status;
861
- mach_msg_type_number_t count;
862
- processor_cpu_load_info_data_t *cpuload;
863
- natural_t i, ncpu;
864
-
865
- status = host_processor_info(sigar->mach_port,
866
- PROCESSOR_CPU_LOAD_INFO,
867
- &ncpu,
868
- (processor_info_array_t*)&cpuload,
869
- &count);
870
-
871
- if (status != KERN_SUCCESS) {
872
- return errno;
873
- }
874
-
875
- sigar_cpu_list_create(cpulist);
876
-
877
- for (i=0; i<ncpu; i++) {
878
- sigar_cpu_t *cpu;
879
-
880
- SIGAR_CPU_LIST_GROW(cpulist);
881
-
882
- cpu = &cpulist->data[cpulist->number++];
883
-
884
- cpu->user = SIGAR_TICK2MSEC(cpuload[i].cpu_ticks[CPU_STATE_USER]);
885
- cpu->sys = SIGAR_TICK2MSEC(cpuload[i].cpu_ticks[CPU_STATE_SYSTEM]);
886
- cpu->idle = SIGAR_TICK2MSEC(cpuload[i].cpu_ticks[CPU_STATE_IDLE]);
887
- cpu->nice = SIGAR_TICK2MSEC(cpuload[i].cpu_ticks[CPU_STATE_NICE]);
888
- cpu->wait = 0; /*N/A*/
889
- cpu->irq = 0; /*N/A*/
890
- cpu->soft_irq = 0; /*N/A*/
891
- cpu->stolen = 0; /*N/A*/
892
- cpu->total = cpu->user + cpu->nice + cpu->sys + cpu->idle;
893
- }
894
-
895
- vm_deallocate(mach_task_self(), (vm_address_t)cpuload, count);
896
-
897
- return SIGAR_OK;
898
- #else
899
- int status, i;
900
- sigar_cpu_t *cpu;
901
-
902
- sigar_cpu_list_create(cpulist);
903
-
904
- #ifdef HAVE_KERN_CP_TIMES
905
- if ((status = sigar_cp_times_get(sigar, cpulist)) == SIGAR_OK) {
906
- return SIGAR_OK;
907
- }
908
- #endif
909
- /* XXX no multi cpu in freebsd < 7.0, howbout others?
910
- * for now just report all metrics on the 1st cpu
911
- * 0's for the rest
912
- */
913
- cpu = &cpulist->data[cpulist->number++];
914
-
915
- status = sigar_cpu_get(sigar, cpu);
916
- if (status != SIGAR_OK) {
917
- return status;
918
- }
919
-
920
- for (i=1; i<sigar->ncpu; i++) {
921
- SIGAR_CPU_LIST_GROW(cpulist);
922
-
923
- cpu = &cpulist->data[cpulist->number++];
924
- SIGAR_ZERO(cpu);
925
- }
926
-
927
- return SIGAR_OK;
928
- #endif
929
- }
930
-
931
- int sigar_uptime_get(sigar_t *sigar,
932
- sigar_uptime_t *uptime)
933
- {
934
- uptime->uptime = time(NULL) - sigar->boot_time;
935
-
936
- return SIGAR_OK;
937
- }
938
-
939
- int sigar_loadavg_get(sigar_t *sigar,
940
- sigar_loadavg_t *loadavg)
941
- {
942
- getloadavg(loadavg->loadavg, 3);
943
-
944
- return SIGAR_OK;
945
- }
946
-
947
- #if defined(DARWIN) && defined(DARWIN_HAS_LIBPROC_H)
948
-
949
- static int proc_fdinfo_get(sigar_t *sigar, sigar_pid_t pid, int *num)
950
- {
951
- int rsize;
952
- const int init_size = PROC_PIDLISTFD_SIZE * 32;
953
-
954
- if (!sigar->libproc) {
955
- return SIGAR_ENOTIMPL;
956
- }
957
-
958
- if (sigar->ifconf_len == 0) {
959
- sigar->ifconf_len = init_size;
960
- sigar->ifconf_buf = malloc(sigar->ifconf_len);
961
- }
962
-
963
- while (1) {
964
- rsize = sigar->proc_pidinfo(pid, PROC_PIDLISTFDS, 0,
965
- sigar->ifconf_buf, sigar->ifconf_len);
966
- if (rsize <= 0) {
967
- return errno;
968
- }
969
- if ((rsize + PROC_PIDLISTFD_SIZE) < sigar->ifconf_len) {
970
- break;
971
- }
972
-
973
- sigar->ifconf_len += init_size;
974
- sigar->ifconf_buf = realloc(sigar->ifconf_buf, sigar->ifconf_len);
975
- }
976
-
977
- *num = rsize / PROC_PIDLISTFD_SIZE;
978
-
979
- return SIGAR_OK;
980
- }
981
-
982
- #endif
983
-
984
- #ifndef KERN_PROC_PROC
985
- /* freebsd 4.x */
986
- #define KERN_PROC_PROC KERN_PROC_ALL
987
- #endif
988
-
989
- int sigar_os_proc_list_get(sigar_t *sigar,
990
- sigar_proc_list_t *proclist)
991
- {
992
- #if defined(DARWIN) || defined(SIGAR_FREEBSD5) || defined(__OpenBSD__) || defined(__NetBSD__)
993
- int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
994
- int i, num;
995
- size_t len;
996
- struct kinfo_proc *proc;
997
-
998
- if (sysctl(mib, NMIB(mib), NULL, &len, NULL, 0) < 0) {
999
- return errno;
1000
- }
1001
-
1002
- proc = malloc(len);
1003
-
1004
- if (sysctl(mib, NMIB(mib), proc, &len, NULL, 0) < 0) {
1005
- free(proc);
1006
- return errno;
1007
- }
1008
-
1009
- num = len/sizeof(*proc);
1010
-
1011
- for (i=0; i<num; i++) {
1012
- if (proc[i].KI_FLAG & P_SYSTEM) {
1013
- continue;
1014
- }
1015
- if (proc[i].KI_PID == 0) {
1016
- continue;
1017
- }
1018
- SIGAR_PROC_LIST_GROW(proclist);
1019
- proclist->data[proclist->number++] = proc[i].KI_PID;
1020
- }
1021
-
1022
- free(proc);
1023
-
1024
- return SIGAR_OK;
1025
- #else
1026
- int i, num;
1027
- struct kinfo_proc *proc;
1028
-
1029
- if (!sigar->kmem) {
1030
- return SIGAR_EPERM_KMEM;
1031
- }
1032
-
1033
- proc = kvm_getprocs(sigar->kmem, KERN_PROC_PROC, 0, &num);
1034
-
1035
- for (i=0; i<num; i++) {
1036
- if (proc[i].KI_FLAG & P_SYSTEM) {
1037
- continue;
1038
- }
1039
- SIGAR_PROC_LIST_GROW(proclist);
1040
- proclist->data[proclist->number++] = proc[i].KI_PID;
1041
- }
1042
- #endif
1043
-
1044
- return SIGAR_OK;
1045
- }
1046
-
1047
- static int sigar_get_pinfo(sigar_t *sigar, sigar_pid_t pid)
1048
- {
1049
- #if defined(__OpenBSD__) || defined(__NetBSD__)
1050
- int mib[] = { CTL_KERN, KERN_PROC2, KERN_PROC_PID, 0, sizeof(*sigar->pinfo), 1 };
1051
- #else
1052
- int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, 0 };
1053
- #endif
1054
- size_t len = sizeof(*sigar->pinfo);
1055
- time_t timenow = time(NULL);
1056
- mib[3] = pid;
1057
-
1058
- if (sigar->pinfo == NULL) {
1059
- sigar->pinfo = malloc(len);
1060
- }
1061
-
1062
- if (sigar->last_pid == pid) {
1063
- if ((timenow - sigar->last_getprocs) < SIGAR_LAST_PROC_EXPIRE) {
1064
- return SIGAR_OK;
1065
- }
1066
- }
1067
-
1068
- sigar->last_pid = pid;
1069
- sigar->last_getprocs = timenow;
1070
-
1071
- if (sysctl(mib, NMIB(mib), sigar->pinfo, &len, NULL, 0) < 0) {
1072
- return errno;
1073
- }
1074
-
1075
- return SIGAR_OK;
1076
- }
1077
-
1078
- #if defined(SHARED_TEXT_REGION_SIZE) && defined(SHARED_DATA_REGION_SIZE)
1079
- # define GLOBAL_SHARED_SIZE (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE) /* 10.4 SDK */
1080
- #endif
1081
-
1082
- #if defined(DARWIN) && defined(DARWIN_HAS_LIBPROC_H) && !defined(GLOBAL_SHARED_SIZE)
1083
- /* get the CPU type of the process for the given pid */
1084
- static int sigar_proc_cpu_type(sigar_t *sigar, sigar_pid_t pid, cpu_type_t *type)
1085
- {
1086
- int status;
1087
- int mib[CTL_MAXNAME];
1088
- size_t len, miblen = NMIB(mib);
1089
-
1090
- status = sysctlnametomib("sysctl.proc_cputype", mib, &miblen);
1091
- if (status != SIGAR_OK) {
1092
- return status;
1093
- }
1094
-
1095
- mib[miblen] = pid;
1096
- len = sizeof(*type);
1097
- return sysctl(mib, miblen + 1, type, &len, NULL, 0);
1098
- }
1099
-
1100
- /* shared memory region size for the given cpu_type_t */
1101
- static mach_vm_size_t sigar_shared_region_size(cpu_type_t type)
1102
- {
1103
- switch (type) {
1104
- case CPU_TYPE_ARM:
1105
- return SHARED_REGION_SIZE_ARM;
1106
- case CPU_TYPE_POWERPC:
1107
- return SHARED_REGION_SIZE_PPC;
1108
- case CPU_TYPE_POWERPC64:
1109
- return SHARED_REGION_SIZE_PPC64;
1110
- case CPU_TYPE_I386:
1111
- return SHARED_REGION_SIZE_I386;
1112
- case CPU_TYPE_X86_64:
1113
- return SHARED_REGION_SIZE_X86_64;
1114
- default:
1115
- return SHARED_REGION_SIZE_I386; /* assume 32-bit x86|ppc */
1116
- }
1117
- }
1118
- #endif /* DARWIN */
1119
-
1120
- int sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid,
1121
- sigar_proc_mem_t *procmem)
1122
- {
1123
- #if defined(DARWIN)
1124
- mach_port_t task, self = mach_task_self();
1125
- kern_return_t status;
1126
- task_basic_info_data_t info;
1127
- task_events_info_data_t events;
1128
- mach_msg_type_number_t count;
1129
- # ifdef DARWIN_HAS_LIBPROC_H
1130
- struct proc_taskinfo pti;
1131
- struct proc_regioninfo pri;
1132
-
1133
- if (sigar->libproc) {
1134
- int sz =
1135
- sigar->proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti));
1136
-
1137
- if (sz == sizeof(pti)) {
1138
- procmem->size = pti.pti_virtual_size;
1139
- procmem->resident = pti.pti_resident_size;
1140
- procmem->page_faults = pti.pti_faults;
1141
- procmem->minor_faults = SIGAR_FIELD_NOTIMPL;
1142
- procmem->major_faults = SIGAR_FIELD_NOTIMPL;
1143
- procmem->share = SIGAR_FIELD_NOTIMPL;
1144
-
1145
- sz = sigar->proc_pidinfo(pid, PROC_PIDREGIONINFO, 0, &pri, sizeof(pri));
1146
- if (sz == sizeof(pri)) {
1147
- if (pri.pri_share_mode == SM_EMPTY) {
1148
- mach_vm_size_t shared_size;
1149
- #ifdef GLOBAL_SHARED_SIZE
1150
- shared_size = GLOBAL_SHARED_SIZE; /* 10.4 SDK */
1151
- #else
1152
- cpu_type_t cpu_type;
1153
-
1154
- if (sigar_proc_cpu_type(sigar, pid, &cpu_type) == SIGAR_OK) {
1155
- shared_size = sigar_shared_region_size(cpu_type);
1156
- }
1157
- else {
1158
- shared_size = SHARED_REGION_SIZE_I386; /* assume 32-bit x86|ppc */
1159
- }
1160
- #endif
1161
- if (procmem->size > shared_size) {
1162
- procmem->size -= shared_size; /* SIGAR-123 */
1163
- }
1164
- }
1165
- }
1166
- return SIGAR_OK;
1167
- }
1168
- }
1169
- # endif
1170
-
1171
- status = task_for_pid(self, pid, &task);
1172
-
1173
- if (status != KERN_SUCCESS) {
1174
- return errno;
1175
- }
1176
-
1177
- count = TASK_BASIC_INFO_COUNT;
1178
- status = task_info(task, TASK_BASIC_INFO, (task_info_t)&info, &count);
1179
- if (status != KERN_SUCCESS) {
1180
- return errno;
1181
- }
1182
-
1183
- count = TASK_EVENTS_INFO_COUNT;
1184
- status = task_info(task, TASK_EVENTS_INFO, (task_info_t)&events, &count);
1185
- if (status == KERN_SUCCESS) {
1186
- procmem->page_faults = events.faults;
1187
- }
1188
- else {
1189
- procmem->page_faults = SIGAR_FIELD_NOTIMPL;
1190
- }
1191
-
1192
- procmem->minor_faults = SIGAR_FIELD_NOTIMPL;
1193
- procmem->major_faults = SIGAR_FIELD_NOTIMPL;
1194
-
1195
- if (task != self) {
1196
- mach_port_deallocate(self, task);
1197
- }
1198
-
1199
- procmem->size = info.virtual_size;
1200
- procmem->resident = info.resident_size;
1201
- procmem->share = SIGAR_FIELD_NOTIMPL;
1202
-
1203
- return SIGAR_OK;
1204
- #elif defined(__FreeBSD__)
1205
- int status = sigar_get_pinfo(sigar, pid);
1206
- bsd_pinfo_t *pinfo = sigar->pinfo;
1207
-
1208
- if (status != SIGAR_OK) {
1209
- return status;
1210
- }
1211
-
1212
- procmem->size =
1213
- (pinfo->KI_TSZ + pinfo->KI_DSZ + pinfo->KI_SSZ) * sigar->pagesize;
1214
-
1215
- procmem->resident = pinfo->KI_RSS * sigar->pagesize;
1216
-
1217
- procmem->share = SIGAR_FIELD_NOTIMPL;
1218
-
1219
- procmem->page_faults = SIGAR_FIELD_NOTIMPL;
1220
- procmem->minor_faults = SIGAR_FIELD_NOTIMPL;
1221
- procmem->major_faults = SIGAR_FIELD_NOTIMPL;
1222
- #elif defined(__OpenBSD__) || defined(__NetBSD__)
1223
- int status = sigar_get_pinfo(sigar, pid);
1224
- bsd_pinfo_t *pinfo = sigar->pinfo;
1225
-
1226
- if (status != SIGAR_OK) {
1227
- return status;
1228
- }
1229
-
1230
- procmem->size =
1231
- (pinfo->p_vm_tsize + pinfo->p_vm_dsize + pinfo->p_vm_ssize) * sigar->pagesize;
1232
-
1233
- procmem->resident = pinfo->p_vm_rssize * sigar->pagesize;
1234
-
1235
- procmem->share = SIGAR_FIELD_NOTIMPL;
1236
-
1237
- procmem->minor_faults = pinfo->p_uru_minflt;
1238
- procmem->major_faults = pinfo->p_uru_majflt;
1239
- procmem->page_faults = procmem->minor_faults + procmem->major_faults;
1240
- #endif
1241
- return SIGAR_OK;
1242
- }
1243
-
1244
- int sigar_proc_cred_get(sigar_t *sigar, sigar_pid_t pid,
1245
- sigar_proc_cred_t *proccred)
1246
- {
1247
- int status = sigar_get_pinfo(sigar, pid);
1248
- bsd_pinfo_t *pinfo = sigar->pinfo;
1249
-
1250
- if (status != SIGAR_OK) {
1251
- return status;
1252
- }
1253
-
1254
- #if defined(__OpenBSD__) || defined(__NetBSD__)
1255
- proccred->uid = pinfo->p_ruid;
1256
- proccred->gid = pinfo->p_rgid;
1257
- proccred->euid = pinfo->p_uid;
1258
- proccred->egid = pinfo->p_gid;
1259
- #else
1260
- proccred->uid = pinfo->KI_UID;
1261
- proccred->gid = pinfo->KI_GID;
1262
- proccred->euid = pinfo->KI_EUID;
1263
- proccred->egid = pinfo->KI_EGID;
1264
- #endif
1265
-
1266
- return SIGAR_OK;
1267
- }
1268
-
1269
- #define tv2msec(tv) \
1270
- (((sigar_uint64_t)tv.tv_sec * SIGAR_MSEC) + (((sigar_uint64_t)tv.tv_usec) / 1000))
1271
-
1272
- #ifdef DARWIN
1273
- #define tval2msec(tval) \
1274
- ((tval.seconds * SIGAR_MSEC) + (tval.microseconds / 1000))
1275
-
1276
- #define tval2nsec(tval) \
1277
- (SIGAR_SEC2NANO((tval).seconds) + SIGAR_MICROSEC2NANO((tval).microseconds))
1278
-
1279
- static int get_proc_times(sigar_t *sigar, sigar_pid_t pid, sigar_proc_time_t *time)
1280
- {
1281
- unsigned int count;
1282
- time_value_t utime = {0, 0}, stime = {0, 0};
1283
- task_basic_info_data_t ti;
1284
- task_thread_times_info_data_t tti;
1285
- task_port_t task, self;
1286
- kern_return_t status;
1287
- # ifdef DARWIN_HAS_LIBPROC_H
1288
- if (sigar->libproc) {
1289
- struct proc_taskinfo pti;
1290
- int sz =
1291
- sigar->proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti));
1292
-
1293
- if (sz == sizeof(pti)) {
1294
- time->user = SIGAR_NSEC2MSEC(pti.pti_total_user);
1295
- time->sys = SIGAR_NSEC2MSEC(pti.pti_total_system);
1296
- time->total = time->user + time->sys;
1297
- return SIGAR_OK;
1298
- }
1299
- }
1300
- # endif
1301
-
1302
- self = mach_task_self();
1303
- status = task_for_pid(self, pid, &task);
1304
- if (status != KERN_SUCCESS) {
1305
- return errno;
1306
- }
1307
-
1308
- count = TASK_BASIC_INFO_COUNT;
1309
- status = task_info(task, TASK_BASIC_INFO,
1310
- (task_info_t)&ti, &count);
1311
- if (status != KERN_SUCCESS) {
1312
- if (task != self) {
1313
- mach_port_deallocate(self, task);
1314
- }
1315
- return errno;
1316
- }
1317
-
1318
- count = TASK_THREAD_TIMES_INFO_COUNT;
1319
- status = task_info(task, TASK_THREAD_TIMES_INFO,
1320
- (task_info_t)&tti, &count);
1321
- if (status != KERN_SUCCESS) {
1322
- if (task != self) {
1323
- mach_port_deallocate(self, task);
1324
- }
1325
- return errno;
1326
- }
1327
-
1328
- time_value_add(&utime, &ti.user_time);
1329
- time_value_add(&stime, &ti.system_time);
1330
- time_value_add(&utime, &tti.user_time);
1331
- time_value_add(&stime, &tti.system_time);
1332
-
1333
- time->user = tval2msec(utime);
1334
- time->sys = tval2msec(stime);
1335
- time->total = time->user + time->sys;
1336
-
1337
- return SIGAR_OK;
1338
- }
1339
- #endif
1340
-
1341
- int sigar_proc_time_get(sigar_t *sigar, sigar_pid_t pid,
1342
- sigar_proc_time_t *proctime)
1343
- {
1344
- #ifdef SIGAR_FREEBSD4
1345
- struct user user;
1346
- #endif
1347
- int status = sigar_get_pinfo(sigar, pid);
1348
- bsd_pinfo_t *pinfo = sigar->pinfo;
1349
-
1350
- if (status != SIGAR_OK) {
1351
- return status;
1352
- }
1353
-
1354
- #if defined(DARWIN)
1355
- if ((status = get_proc_times(sigar, pid, proctime)) != SIGAR_OK) {
1356
- return status;
1357
- }
1358
- proctime->start_time = tv2msec(pinfo->KI_START);
1359
- #elif defined(SIGAR_FREEBSD5)
1360
- proctime->user = tv2msec(pinfo->ki_rusage.ru_utime);
1361
- proctime->sys = tv2msec(pinfo->ki_rusage.ru_stime);
1362
- proctime->total = proctime->user + proctime->sys;
1363
- proctime->start_time = tv2msec(pinfo->KI_START);
1364
- #elif defined(SIGAR_FREEBSD4)
1365
- if (!sigar->kmem) {
1366
- return SIGAR_EPERM_KMEM;
1367
- }
1368
-
1369
- status = kread(sigar, &user, sizeof(user),
1370
- (u_long)pinfo->kp_proc.p_addr);
1371
- if (status != SIGAR_OK) {
1372
- return status;
1373
- }
1374
-
1375
- proctime->user = tv2msec(user.u_stats.p_ru.ru_utime);
1376
- proctime->sys = tv2msec(user.u_stats.p_ru.ru_stime);
1377
- proctime->total = proctime->user + proctime->sys;
1378
- proctime->start_time = tv2msec(user.u_stats.p_start);
1379
- #elif defined(__OpenBSD__) || defined(__NetBSD__)
1380
- /* XXX *_usec */
1381
- proctime->user = pinfo->p_uutime_sec * SIGAR_MSEC;
1382
- proctime->sys = pinfo->p_ustime_sec * SIGAR_MSEC;
1383
- proctime->total = proctime->user + proctime->sys;
1384
- proctime->start_time = pinfo->p_ustart_sec * SIGAR_MSEC;
1385
- #endif
1386
-
1387
- return SIGAR_OK;
1388
- }
1389
-
1390
- #ifdef DARWIN
1391
- /* thread state mapping derived from ps.tproj */
1392
- static const char const thread_states[] = {
1393
- /*0*/ '-',
1394
- /*1*/ SIGAR_PROC_STATE_RUN,
1395
- /*2*/ SIGAR_PROC_STATE_ZOMBIE,
1396
- /*3*/ SIGAR_PROC_STATE_SLEEP,
1397
- /*4*/ SIGAR_PROC_STATE_IDLE,
1398
- /*5*/ SIGAR_PROC_STATE_STOP,
1399
- /*6*/ SIGAR_PROC_STATE_STOP,
1400
- /*7*/ '?'
1401
- };
1402
-
1403
- static int thread_state_get(thread_basic_info_data_t *info)
1404
- {
1405
- switch (info->run_state) {
1406
- case TH_STATE_RUNNING:
1407
- return 1;
1408
- case TH_STATE_UNINTERRUPTIBLE:
1409
- return 2;
1410
- case TH_STATE_WAITING:
1411
- return (info->sleep_time > 20) ? 4 : 3;
1412
- case TH_STATE_STOPPED:
1413
- return 5;
1414
- case TH_STATE_HALTED:
1415
- return 6;
1416
- default:
1417
- return 7;
1418
- }
1419
- }
1420
-
1421
- static int sigar_proc_threads_get(sigar_t *sigar, sigar_pid_t pid,
1422
- sigar_proc_state_t *procstate)
1423
- {
1424
- mach_port_t task, self = mach_task_self();
1425
- kern_return_t status;
1426
- thread_array_t threads;
1427
- mach_msg_type_number_t count, i;
1428
- int state = TH_STATE_HALTED + 1;
1429
-
1430
- status = task_for_pid(self, pid, &task);
1431
- if (status != KERN_SUCCESS) {
1432
- return errno;
1433
- }
1434
-
1435
- status = task_threads(task, &threads, &count);
1436
- if (status != KERN_SUCCESS) {
1437
- return errno;
1438
- }
1439
-
1440
- procstate->threads = count;
1441
-
1442
- for (i=0; i<count; i++) {
1443
- mach_msg_type_number_t info_count = THREAD_BASIC_INFO_COUNT;
1444
- thread_basic_info_data_t info;
1445
-
1446
- status = thread_info(threads[i], THREAD_BASIC_INFO,
1447
- (thread_info_t)&info, &info_count);
1448
- if (status == KERN_SUCCESS) {
1449
- int tstate = thread_state_get(&info);
1450
- if (tstate < state) {
1451
- state = tstate;
1452
- }
1453
- }
1454
- }
1455
-
1456
- vm_deallocate(self, (vm_address_t)threads, sizeof(thread_t) * count);
1457
-
1458
- procstate->state = thread_states[state];
1459
-
1460
- return SIGAR_OK;
1461
- }
1462
- #endif
1463
-
1464
- int sigar_proc_state_get(sigar_t *sigar, sigar_pid_t pid,
1465
- sigar_proc_state_t *procstate)
1466
- {
1467
- int status = sigar_get_pinfo(sigar, pid);
1468
- bsd_pinfo_t *pinfo = sigar->pinfo;
1469
- #if defined(__OpenBSD__) || defined(__NetBSD__)
1470
- int state = pinfo->p_stat;
1471
- #else
1472
- int state = pinfo->KI_STAT;
1473
- #endif
1474
-
1475
- if (status != SIGAR_OK) {
1476
- return status;
1477
- }
1478
-
1479
- #if defined(__OpenBSD__) || defined(__NetBSD__)
1480
- SIGAR_SSTRCPY(procstate->name, pinfo->p_comm);
1481
- procstate->ppid = pinfo->p_ppid;
1482
- procstate->priority = pinfo->p_priority;
1483
- procstate->nice = pinfo->p_nice;
1484
- procstate->tty = pinfo->p_tdev;
1485
- procstate->threads = SIGAR_FIELD_NOTIMPL;
1486
- procstate->processor = pinfo->p_cpuid;
1487
- #else
1488
- SIGAR_SSTRCPY(procstate->name, pinfo->KI_COMM);
1489
- procstate->ppid = pinfo->KI_PPID;
1490
- procstate->priority = pinfo->KI_PRI;
1491
- procstate->nice = pinfo->KI_NICE;
1492
- procstate->tty = SIGAR_FIELD_NOTIMPL; /*XXX*/
1493
- procstate->threads = SIGAR_FIELD_NOTIMPL;
1494
- procstate->processor = SIGAR_FIELD_NOTIMPL;
1495
- #endif
1496
-
1497
- #ifdef DARWIN
1498
- status = sigar_proc_threads_get(sigar, pid, procstate);
1499
- if (status == SIGAR_OK) {
1500
- return status;
1501
- }
1502
- #endif
1503
-
1504
- switch (state) {
1505
- case SIDL:
1506
- procstate->state = 'D';
1507
- break;
1508
- case SRUN:
1509
- #ifdef SONPROC
1510
- case SONPROC:
1511
- #endif
1512
- procstate->state = 'R';
1513
- break;
1514
- case SSLEEP:
1515
- procstate->state = 'S';
1516
- break;
1517
- case SSTOP:
1518
- procstate->state = 'T';
1519
- break;
1520
- case SZOMB:
1521
- procstate->state = 'Z';
1522
- break;
1523
- default:
1524
- procstate->state = '?';
1525
- break;
1526
- }
1527
-
1528
- return SIGAR_OK;
1529
- }
1530
-
1531
- #if defined(DARWIN)
1532
- typedef struct {
1533
- char *buf, *ptr, *end;
1534
- int count;
1535
- } sigar_kern_proc_args_t;
1536
-
1537
- static void sigar_kern_proc_args_destroy(sigar_kern_proc_args_t *kargs)
1538
- {
1539
- if (kargs->buf) {
1540
- free(kargs->buf);
1541
- kargs->buf = NULL;
1542
- }
1543
- }
1544
-
1545
- /* re-usable hack for use by proc_args and proc_env */
1546
- static int sigar_kern_proc_args_get(sigar_t *sigar,
1547
- sigar_pid_t pid,
1548
- char *exe,
1549
- sigar_kern_proc_args_t *kargs)
1550
- {
1551
- /*
1552
- * derived from:
1553
- * http://darwinsource.opendarwin.org/10.4.1/adv_cmds-79.1/ps.tproj/print.c
1554
- */
1555
- int mib[3], len;
1556
- size_t size = sigar_argmax_get(sigar);
1557
-
1558
- kargs->buf = malloc(size);
1559
-
1560
- mib[0] = CTL_KERN;
1561
- mib[1] = KERN_PROCARGS2;
1562
- mib[2] = pid;
1563
-
1564
- if (sysctl(mib, NMIB(mib), kargs->buf, &size, NULL, 0) < 0) {
1565
- sigar_kern_proc_args_destroy(kargs);
1566
- return errno;
1567
- }
1568
-
1569
- kargs->end = &kargs->buf[size];
1570
-
1571
- memcpy(&kargs->count, kargs->buf, sizeof(kargs->count));
1572
- kargs->ptr = kargs->buf + sizeof(kargs->count);
1573
-
1574
- len = strlen(kargs->ptr);
1575
- if (exe) {
1576
- memcpy(exe, kargs->ptr, len+1);
1577
- }
1578
- kargs->ptr += len+1;
1579
-
1580
- if (kargs->ptr == kargs->end) {
1581
- sigar_kern_proc_args_destroy(kargs);
1582
- return exe ? SIGAR_OK : ENOENT;
1583
- }
1584
-
1585
- for (; kargs->ptr < kargs->end; kargs->ptr++) {
1586
- if (*kargs->ptr != '\0') {
1587
- break; /* start of argv[0] */
1588
- }
1589
- }
1590
-
1591
- if (kargs->ptr == kargs->end) {
1592
- sigar_kern_proc_args_destroy(kargs);
1593
- return exe ? SIGAR_OK : ENOENT;
1594
- }
1595
-
1596
- return SIGAR_OK;
1597
- }
1598
-
1599
- static int kern_proc_args_skip_argv(sigar_kern_proc_args_t *kargs)
1600
- {
1601
- char *ptr = kargs->ptr;
1602
- char *end = kargs->end;
1603
- int count = kargs->count;
1604
-
1605
- /* skip over argv */
1606
- while ((ptr < end) && (count-- > 0)) {
1607
- int alen = strlen(ptr)+1;
1608
-
1609
- ptr += alen;
1610
- }
1611
-
1612
- kargs->ptr = ptr;
1613
- kargs->end = end;
1614
- kargs->count = 0;
1615
-
1616
- if (ptr >= end) {
1617
- return ENOENT;
1618
- }
1619
-
1620
- return SIGAR_OK;
1621
- }
1622
- #endif
1623
-
1624
- int sigar_os_proc_args_get(sigar_t *sigar, sigar_pid_t pid,
1625
- sigar_proc_args_t *procargs)
1626
- {
1627
- #if defined(DARWIN)
1628
- int status, count;
1629
- sigar_kern_proc_args_t kargs;
1630
- char *ptr, *end;
1631
-
1632
- status = sigar_kern_proc_args_get(sigar, pid, NULL, &kargs);
1633
- if (status != SIGAR_OK) {
1634
- return status;
1635
- }
1636
-
1637
- count = kargs.count;
1638
- ptr = kargs.ptr;
1639
- end = kargs.end;
1640
-
1641
- while ((ptr < end) && (count-- > 0)) {
1642
- int slen = strlen(ptr);
1643
- int alen = slen+1;
1644
- char *arg;
1645
-
1646
- /*
1647
- * trim trailing whitespace.
1648
- * seen w/ postgresql, probably related
1649
- * to messing with argv[0]
1650
- */
1651
- while (*(ptr + (slen-1)) == ' ') {
1652
- if (--slen <= 0) {
1653
- break;
1654
- }
1655
- }
1656
-
1657
- arg = malloc(slen+1);
1658
-
1659
- SIGAR_PROC_ARGS_GROW(procargs);
1660
- memcpy(arg, ptr, slen);
1661
- *(arg+slen) = '\0';
1662
-
1663
- procargs->data[procargs->number++] = arg;
1664
-
1665
- ptr += alen;
1666
- }
1667
-
1668
- sigar_kern_proc_args_destroy(&kargs);
1669
- return SIGAR_OK;
1670
- #elif defined(__FreeBSD__) || defined(__NetBSD__)
1671
- char buffer[SIGAR_ARG_MAX+1], *ptr=buffer;
1672
- size_t len = sizeof(buffer);
1673
- # ifdef __NetBSD__
1674
- int mib[] = { CTL_KERN, KERN_PROC_ARGS, 0, KERN_PROC_ARGV };
1675
- mib[2] = pid;
1676
- # else
1677
- int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_ARGS, 0 };
1678
- mib[3] = pid;
1679
- # endif
1680
-
1681
- if (sysctl(mib, NMIB(mib), buffer, &len, NULL, 0) < 0) {
1682
- return errno;
1683
- }
1684
-
1685
- if (len == 0) {
1686
- procargs->number = 0;
1687
- return SIGAR_OK;
1688
- }
1689
-
1690
- buffer[len] = '\0';
1691
-
1692
- while (len > 0) {
1693
- int alen = strlen(ptr)+1;
1694
- char *arg = malloc(alen);
1695
-
1696
- SIGAR_PROC_ARGS_GROW(procargs);
1697
- memcpy(arg, ptr, alen);
1698
-
1699
- procargs->data[procargs->number++] = arg;
1700
-
1701
- len -= alen;
1702
- if (len > 0) {
1703
- ptr += alen;
1704
- }
1705
- }
1706
-
1707
- return SIGAR_OK;
1708
- #elif defined(__OpenBSD__)
1709
- char buffer[SIGAR_ARG_MAX+1], **ptr=(char **)buffer;
1710
- size_t len = sizeof(buffer);
1711
- int mib[] = { CTL_KERN, KERN_PROC_ARGS, 0, KERN_PROC_ARGV };
1712
- mib[2] = pid;
1713
-
1714
- if (sysctl(mib, NMIB(mib), buffer, &len, NULL, 0) < 0) {
1715
- return errno;
1716
- }
1717
-
1718
- if (len == 0) {
1719
- procargs->number = 0;
1720
- return SIGAR_OK;
1721
- }
1722
-
1723
- for (; *ptr; ptr++) {
1724
- int alen = strlen(*ptr)+1;
1725
- char *arg = malloc(alen);
1726
-
1727
- SIGAR_PROC_ARGS_GROW(procargs);
1728
- memcpy(arg, *ptr, alen);
1729
-
1730
- procargs->data[procargs->number++] = arg;
1731
- }
1732
-
1733
- return SIGAR_OK;
1734
- #else
1735
- return SIGAR_ENOTIMPL;
1736
- #endif
1737
- }
1738
-
1739
- int sigar_proc_env_get(sigar_t *sigar, sigar_pid_t pid,
1740
- sigar_proc_env_t *procenv)
1741
- {
1742
- #ifdef DARWIN
1743
- int status, count;
1744
- sigar_kern_proc_args_t kargs;
1745
- char *ptr, *end;
1746
-
1747
- status = sigar_kern_proc_args_get(sigar, pid, NULL, &kargs);
1748
- if (status != SIGAR_OK) {
1749
- return status;
1750
- }
1751
-
1752
- status = kern_proc_args_skip_argv(&kargs);
1753
- if (status != SIGAR_OK) {
1754
- sigar_kern_proc_args_destroy(&kargs);
1755
- return status;
1756
- }
1757
-
1758
- count = kargs.count;
1759
- ptr = kargs.ptr;
1760
- end = kargs.end;
1761
-
1762
- /* into environ */
1763
- while (ptr < end) {
1764
- char *val = strchr(ptr, '=');
1765
- int klen, vlen, status;
1766
- char key[256]; /* XXX is there a max key size? */
1767
-
1768
- if (val == NULL) {
1769
- /* not key=val format */
1770
- break;
1771
- }
1772
-
1773
- klen = val - ptr;
1774
- SIGAR_SSTRCPY(key, ptr);
1775
- key[klen] = '\0';
1776
- ++val;
1777
-
1778
- vlen = strlen(val);
1779
- status = procenv->env_getter(procenv->data,
1780
- key, klen, val, vlen);
1781
-
1782
- if (status != SIGAR_OK) {
1783
- /* not an error; just stop iterating */
1784
- break;
1785
- }
1786
-
1787
- ptr += (klen + 1 + vlen + 1);
1788
-
1789
- if (*ptr == '\0') {
1790
- break;
1791
- }
1792
- }
1793
-
1794
- sigar_kern_proc_args_destroy(&kargs);
1795
- return SIGAR_OK;
1796
- #else
1797
- char **env;
1798
- struct kinfo_proc *pinfo;
1799
- int num;
1800
-
1801
- if (!sigar->kmem) {
1802
- return SIGAR_EPERM_KMEM;
1803
- }
1804
-
1805
- pinfo = kvm_getprocs(sigar->kmem, KERN_PROC_PID, pid, &num);
1806
- if (!pinfo || (num < 1)) {
1807
- return errno;
1808
- }
1809
-
1810
- if (!(env = kvm_getenvv(sigar->kmem, pinfo, 9086))) {
1811
- return errno;
1812
- }
1813
-
1814
- while (*env) {
1815
- char *ptr = *env++;
1816
- char *val = strchr(ptr, '=');
1817
- int klen, vlen, status;
1818
- char key[128]; /* XXX is there a max key size? */
1819
-
1820
- if (val == NULL) {
1821
- /* not key=val format */
1822
- procenv->env_getter(procenv->data, ptr, strlen(ptr), NULL, 0);
1823
- break;
1824
- }
1825
-
1826
- klen = val - ptr;
1827
- SIGAR_SSTRCPY(key, ptr);
1828
- key[klen] = '\0';
1829
- ++val;
1830
-
1831
- vlen = strlen(val);
1832
- status = procenv->env_getter(procenv->data,
1833
- key, klen, val, vlen);
1834
-
1835
- if (status != SIGAR_OK) {
1836
- /* not an error; just stop iterating */
1837
- break;
1838
- }
1839
-
1840
- ptr += (klen + 1 + vlen + 1);
1841
- }
1842
-
1843
- return SIGAR_OK;
1844
- #endif
1845
- }
1846
-
1847
- int sigar_proc_fd_get(sigar_t *sigar, sigar_pid_t pid,
1848
- sigar_proc_fd_t *procfd)
1849
- {
1850
- #ifdef __FreeBSD__
1851
- int status;
1852
- bsd_pinfo_t *pinfo;
1853
- struct filedesc filed;
1854
- #if 0
1855
- struct file **ofiles;
1856
- int nfiles, i;
1857
- size_t size;
1858
- #endif
1859
- if (!sigar->kmem) {
1860
- return SIGAR_EPERM_KMEM;
1861
- }
1862
-
1863
- if ((status = sigar_get_pinfo(sigar, pid)) != SIGAR_OK) {
1864
- return status;
1865
- }
1866
- pinfo = sigar->pinfo;
1867
-
1868
- status = kread(sigar, &filed, sizeof(filed), (u_long)pinfo->KI_FD);
1869
- if (status != SIGAR_OK) {
1870
- return status;
1871
- }
1872
- #if 0
1873
- nfiles = filed.fd_lastfile+1;
1874
- size = sizeof(*ofiles) * nfiles;
1875
- ofiles = malloc(size);
1876
- status = kread(sigar, ofiles, size, (u_long)filed.fd_ofiles);
1877
- if (status != SIGAR_OK) {
1878
- free(ofiles);
1879
- return status;
1880
- }
1881
-
1882
- procfd->total = 0;
1883
- for (i=0; i<filed.fd_lastfile; i++) {
1884
- if (!ofiles[i]) {
1885
- continue;
1886
- }
1887
- procfd->total++;
1888
- }
1889
-
1890
- free(ofiles);
1891
- #else
1892
- /* seems the same as the above */
1893
- procfd->total = filed.fd_lastfile;
1894
- #endif
1895
-
1896
- return SIGAR_OK;
1897
- #else
1898
- return SIGAR_ENOTIMPL;
1899
- #endif
1900
- }
1901
-
1902
- int sigar_proc_exe_get(sigar_t *sigar, sigar_pid_t pid,
1903
- sigar_proc_exe_t *procexe)
1904
- {
1905
- #ifdef DARWIN
1906
- int status;
1907
- sigar_kern_proc_args_t kargs;
1908
-
1909
- status = sigar_kern_proc_args_get(sigar, pid, procexe->name, &kargs);
1910
- if (status != SIGAR_OK) {
1911
- return status;
1912
- }
1913
-
1914
- procexe->cwd[0] = '\0';
1915
- procexe->root[0] = '\0';
1916
-
1917
- /* attempt to determine cwd from $PWD */
1918
- status = kern_proc_args_skip_argv(&kargs);
1919
- if (status == SIGAR_OK) {
1920
- char *ptr = kargs.ptr;
1921
- char *end = kargs.end;
1922
-
1923
- /* into environ */
1924
- while (ptr < end) {
1925
- int len = strlen(ptr);
1926
-
1927
- if ((len > 4) &&
1928
- (ptr[0] == 'P') &&
1929
- (ptr[1] == 'W') &&
1930
- (ptr[2] == 'D') &&
1931
- (ptr[3] == '='))
1932
- {
1933
- memcpy(procexe->cwd, ptr+4, len-3);
1934
- break;
1935
- }
1936
-
1937
- ptr += len+1;
1938
- }
1939
- }
1940
-
1941
- sigar_kern_proc_args_destroy(&kargs);
1942
-
1943
- return SIGAR_OK;
1944
- #else
1945
- int len;
1946
- char name[1024];
1947
-
1948
- procexe->cwd[0] = '\0';
1949
- procexe->root[0] = '\0';
1950
-
1951
- (void)SIGAR_PROC_FILENAME(name, pid, "/file");
1952
-
1953
- if ((len = readlink(name, procexe->name,
1954
- sizeof(procexe->name)-1)) < 0)
1955
- {
1956
- return PROCFS_STATUS(errno);
1957
- }
1958
-
1959
- procexe->name[len] = '\0';
1960
-
1961
- return SIGAR_OK;
1962
- #endif
1963
- }
1964
-
1965
- #ifdef DARWIN
1966
- static int sigar_dlinfo_modules(sigar_t *sigar, sigar_proc_modules_t *procmods)
1967
- {
1968
- uint32_t i, count = _dyld_image_count();
1969
-
1970
- for (i=0; i<count; i++) {
1971
- int status;
1972
- const char *name =
1973
- _dyld_get_image_name(i);
1974
-
1975
- if (name == NULL) {
1976
- continue;
1977
- }
1978
- status =
1979
- procmods->module_getter(procmods->data,
1980
- (char *)name, strlen(name));
1981
-
1982
- if (status != SIGAR_OK) {
1983
- /* not an error; just stop iterating */
1984
- break;
1985
- }
1986
- }
1987
- return SIGAR_OK;
1988
- }
1989
- #endif /* DARWIN */
1990
-
1991
- int sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
1992
- sigar_proc_modules_t *procmods)
1993
- {
1994
- #if defined(SIGAR_HAS_DLINFO_MODULES) || defined(DARWIN)
1995
- if (pid == sigar_pid_get(sigar)) {
1996
- return sigar_dlinfo_modules(sigar, procmods);
1997
- }
1998
- #endif
1999
- return SIGAR_ENOTIMPL;
2000
- }
2001
-
2002
- #define SIGAR_MICROSEC2NANO(s) \
2003
- ((sigar_uint64_t)(s) * (sigar_uint64_t)1000)
2004
-
2005
- #define TIME_NSEC(t) \
2006
- (SIGAR_SEC2NANO((t).tv_sec) + SIGAR_MICROSEC2NANO((t).tv_usec))
2007
-
2008
- int sigar_thread_cpu_get(sigar_t *sigar,
2009
- sigar_uint64_t id,
2010
- sigar_thread_cpu_t *cpu)
2011
- {
2012
- #if defined(DARWIN)
2013
- mach_port_t self = mach_thread_self();
2014
- thread_basic_info_data_t info;
2015
- mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
2016
- kern_return_t status;
2017
-
2018
- status = thread_info(self, THREAD_BASIC_INFO,
2019
- (thread_info_t)&info, &count);
2020
- if (status != KERN_SUCCESS) {
2021
- return errno;
2022
- }
2023
-
2024
- mach_port_deallocate(mach_task_self(), self);
2025
-
2026
- cpu->user = tval2nsec(info.user_time);
2027
- cpu->sys = tval2nsec(info.system_time);
2028
- cpu->total = cpu->user + cpu->sys;
2029
- #elif defined(__NetBSD__)
2030
- return SIGAR_ENOTIMPL; /* http://tinyurl.com/chbvln */
2031
- #else
2032
- /* XXX this is not per-thread, it is for the whole-process.
2033
- * just want to use for the shell time command at the moment.
2034
- */
2035
- struct rusage usage;
2036
- getrusage(RUSAGE_SELF, &usage);
2037
-
2038
- cpu->user = TIME_NSEC(usage.ru_utime);
2039
- cpu->sys = TIME_NSEC(usage.ru_stime);
2040
- cpu->total = TIME_NSEC(usage.ru_utime) + TIME_NSEC(usage.ru_stime);
2041
- #endif
2042
-
2043
- return SIGAR_OK;
2044
- }
2045
-
2046
- int sigar_os_fs_type_get(sigar_file_system_t *fsp)
2047
- {
2048
- char *type = fsp->sys_type_name;
2049
-
2050
- /* see sys/disklabel.h */
2051
- switch (*type) {
2052
- case 'f':
2053
- if (strEQ(type, "ffs")) {
2054
- fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
2055
- }
2056
- break;
2057
- case 'h':
2058
- if (strEQ(type, "hfs")) {
2059
- fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
2060
- }
2061
- break;
2062
- case 'u':
2063
- if (strEQ(type, "ufs")) {
2064
- fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
2065
- }
2066
- break;
2067
- }
2068
-
2069
- return fsp->type;
2070
- }
2071
-
2072
- static void get_fs_options(char *opts, int osize, long flags)
2073
- {
2074
- *opts = '\0';
2075
- if (flags & MNT_RDONLY) strncat(opts, "ro", osize);
2076
- else strncat(opts, "rw", osize);
2077
- if (flags & MNT_SYNCHRONOUS) strncat(opts, ",sync", osize);
2078
- if (flags & MNT_NOEXEC) strncat(opts, ",noexec", osize);
2079
- if (flags & MNT_NOSUID) strncat(opts, ",nosuid", osize);
2080
- #ifdef MNT_NODEV
2081
- if (flags & MNT_NODEV) strncat(opts, ",nodev", osize);
2082
- #endif
2083
- #ifdef MNT_UNION
2084
- if (flags & MNT_UNION) strncat(opts, ",union", osize);
2085
- #endif
2086
- if (flags & MNT_ASYNC) strncat(opts, ",async", osize);
2087
- #ifdef MNT_NOATIME
2088
- if (flags & MNT_NOATIME) strncat(opts, ",noatime", osize);
2089
- #endif
2090
- #ifdef MNT_NOCLUSTERR
2091
- if (flags & MNT_NOCLUSTERR) strncat(opts, ",noclusterr", osize);
2092
- #endif
2093
- #ifdef MNT_NOCLUSTERW
2094
- if (flags & MNT_NOCLUSTERW) strncat(opts, ",noclusterw", osize);
2095
- #endif
2096
- #ifdef MNT_NOSYMFOLLOW
2097
- if (flags & MNT_NOSYMFOLLOW) strncat(opts, ",nosymfollow", osize);
2098
- #endif
2099
- #ifdef MNT_SUIDDIR
2100
- if (flags & MNT_SUIDDIR) strncat(opts, ",suiddir", osize);
2101
- #endif
2102
- #ifdef MNT_SOFTDEP
2103
- if (flags & MNT_SOFTDEP) strncat(opts, ",soft-updates", osize);
2104
- #endif
2105
- if (flags & MNT_LOCAL) strncat(opts, ",local", osize);
2106
- if (flags & MNT_QUOTA) strncat(opts, ",quota", osize);
2107
- if (flags & MNT_ROOTFS) strncat(opts, ",rootfs", osize);
2108
- #ifdef MNT_USER
2109
- if (flags & MNT_USER) strncat(opts, ",user", osize);
2110
- #endif
2111
- #ifdef MNT_IGNORE
2112
- if (flags & MNT_IGNORE) strncat(opts, ",ignore", osize);
2113
- #endif
2114
- if (flags & MNT_EXPORTED) strncat(opts, ",nfs", osize);
2115
- }
2116
-
2117
- #ifdef __NetBSD__
2118
- #define sigar_statfs statvfs
2119
- #define sigar_getfsstat getvfsstat
2120
- #define sigar_f_flags f_flag
2121
- #else
2122
- #define sigar_statfs statfs
2123
- #define sigar_getfsstat getfsstat
2124
- #define sigar_f_flags f_flags
2125
- #endif
2126
-
2127
- int sigar_file_system_list_get(sigar_t *sigar,
2128
- sigar_file_system_list_t *fslist)
2129
- {
2130
- struct sigar_statfs *fs;
2131
- int num, i;
2132
- int is_debug = SIGAR_LOG_IS_DEBUG(sigar);
2133
- long len;
2134
-
2135
- if ((num = sigar_getfsstat(NULL, 0, MNT_NOWAIT)) < 0) {
2136
- return errno;
2137
- }
2138
-
2139
- len = sizeof(*fs) * num;
2140
- fs = malloc(len);
2141
-
2142
- if ((num = sigar_getfsstat(fs, len, MNT_NOWAIT)) < 0) {
2143
- free(fs);
2144
- return errno;
2145
- }
2146
-
2147
- sigar_file_system_list_create(fslist);
2148
-
2149
- for (i=0; i<num; i++) {
2150
- sigar_file_system_t *fsp;
2151
-
2152
- #ifdef MNT_AUTOMOUNTED
2153
- if (fs[i].sigar_f_flags & MNT_AUTOMOUNTED) {
2154
- if (is_debug) {
2155
- sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
2156
- "[file_system_list] skipping automounted %s: %s",
2157
- fs[i].f_fstypename, fs[i].f_mntonname);
2158
- }
2159
- continue;
2160
- }
2161
- #endif
2162
-
2163
- #ifdef MNT_RDONLY
2164
- if (fs[i].sigar_f_flags & MNT_RDONLY) {
2165
- /* e.g. ftp mount or .dmg image */
2166
- if (is_debug) {
2167
- sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
2168
- "[file_system_list] skipping readonly %s: %s",
2169
- fs[i].f_fstypename, fs[i].f_mntonname);
2170
- }
2171
- continue;
2172
- }
2173
- #endif
2174
-
2175
- SIGAR_FILE_SYSTEM_LIST_GROW(fslist);
2176
-
2177
- fsp = &fslist->data[fslist->number++];
2178
-
2179
- SIGAR_SSTRCPY(fsp->dir_name, fs[i].f_mntonname);
2180
- SIGAR_SSTRCPY(fsp->dev_name, fs[i].f_mntfromname);
2181
- SIGAR_SSTRCPY(fsp->sys_type_name, fs[i].f_fstypename);
2182
- get_fs_options(fsp->options, sizeof(fsp->options)-1, fs[i].sigar_f_flags);
2183
-
2184
- sigar_fs_type_init(fsp);
2185
- }
2186
-
2187
- free(fs);
2188
- return SIGAR_OK;
2189
- }
2190
-
2191
- #ifdef DARWIN
2192
- #define IoStatGetValue(key, val) \
2193
- if ((number = (CFNumberRef)CFDictionaryGetValue(stats, CFSTR(kIOBlockStorageDriverStatistics##key)))) \
2194
- CFNumberGetValue(number, kCFNumberSInt64Type, &val)
2195
- #endif
2196
-
2197
- int sigar_disk_usage_get(sigar_t *sigar, const char *name,
2198
- sigar_disk_usage_t *disk)
2199
- {
2200
- #if defined(DARWIN)
2201
- kern_return_t status;
2202
- io_registry_entry_t parent;
2203
- io_service_t service;
2204
- CFDictionaryRef props;
2205
- CFNumberRef number;
2206
- sigar_iodev_t *iodev = sigar_iodev_get(sigar, name);
2207
- char dname[256], *ptr;
2208
-
2209
- SIGAR_DISK_STATS_INIT(disk);
2210
-
2211
- if (!iodev) {
2212
- return ENXIO;
2213
- }
2214
-
2215
- /* "/dev/disk0s1" -> "disk0" */ /* XXX better way? */
2216
- ptr = &iodev->name[SSTRLEN(SIGAR_DEV_PREFIX)];
2217
- SIGAR_SSTRCPY(dname, ptr);
2218
- ptr = dname;
2219
- if (strnEQ(ptr, "disk", 4)) {
2220
- ptr += 4;
2221
- if ((ptr = strchr(ptr, 's')) && isdigit(*(ptr+1))) {
2222
- *ptr = '\0';
2223
- }
2224
- }
2225
-
2226
- if (SIGAR_LOG_IS_DEBUG(sigar)) {
2227
- sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
2228
- "[disk_usage] map %s -> %s",
2229
- iodev->name, dname);
2230
- }
2231
-
2232
- /* e.g. name == "disk0" */
2233
- service = IOServiceGetMatchingService(kIOMasterPortDefault,
2234
- IOBSDNameMatching(kIOMasterPortDefault, 0, dname));
2235
-
2236
- if (!service) {
2237
- return errno;
2238
- }
2239
-
2240
- status = IORegistryEntryGetParentEntry(service, kIOServicePlane, &parent);
2241
- if (status != KERN_SUCCESS) {
2242
- IOObjectRelease(service);
2243
- return status;
2244
- }
2245
-
2246
- status = IORegistryEntryCreateCFProperties(parent,
2247
- (CFMutableDictionaryRef *)&props,
2248
- kCFAllocatorDefault,
2249
- kNilOptions);
2250
- if (props) {
2251
- CFDictionaryRef stats =
2252
- (CFDictionaryRef)CFDictionaryGetValue(props,
2253
- CFSTR(kIOBlockStorageDriverStatisticsKey));
2254
-
2255
- if (stats) {
2256
- IoStatGetValue(ReadsKey, disk->reads);
2257
- IoStatGetValue(BytesReadKey, disk->read_bytes);
2258
- IoStatGetValue(TotalReadTimeKey, disk->rtime);
2259
- IoStatGetValue(WritesKey, disk->writes);
2260
- IoStatGetValue(BytesWrittenKey, disk->write_bytes);
2261
- IoStatGetValue(TotalWriteTimeKey, disk->wtime);
2262
- disk->time = disk->rtime + disk->wtime;
2263
- }
2264
-
2265
- CFRelease(props);
2266
- }
2267
-
2268
- IOObjectRelease(service);
2269
- IOObjectRelease(parent);
2270
-
2271
- return SIGAR_OK;
2272
- #elif defined(__FreeBSD__)
2273
- /* XXX incomplete */
2274
- struct sigar_statfs buf;
2275
-
2276
- if (sigar_statfs(name, &buf) < 0) {
2277
- return errno;
2278
- }
2279
-
2280
- SIGAR_DISK_STATS_INIT(disk);
2281
-
2282
- disk->reads = buf.f_syncreads + buf.f_asyncreads;
2283
- disk->writes = buf.f_syncwrites + buf.f_asyncwrites;
2284
- return SIGAR_OK;
2285
- #else
2286
- SIGAR_DISK_STATS_INIT(disk);
2287
- return SIGAR_ENOTIMPL;
2288
- #endif
2289
- }
2290
-
2291
- int sigar_file_system_usage_get(sigar_t *sigar,
2292
- const char *dirname,
2293
- sigar_file_system_usage_t *fsusage)
2294
- {
2295
- int status = sigar_statvfs(sigar, dirname, fsusage);
2296
-
2297
- if (status != SIGAR_OK) {
2298
- return status;
2299
- }
2300
-
2301
- fsusage->use_percent = sigar_file_system_usage_calc_used(sigar, fsusage);
2302
-
2303
- sigar_disk_usage_get(sigar, dirname, &fsusage->disk);
2304
-
2305
- return SIGAR_OK;
2306
- }
2307
-
2308
- #ifdef DARWIN
2309
- #define CTL_HW_FREQ_MAX "hw.cpufrequency_max"
2310
- #define CTL_HW_FREQ_MIN "hw.cpufrequency_min"
2311
- #else
2312
- /* XXX FreeBSD 5.x+ only? */
2313
- #define CTL_HW_FREQ "machdep.tsc_freq"
2314
- #endif
2315
-
2316
- int sigar_cpu_info_list_get(sigar_t *sigar,
2317
- sigar_cpu_info_list_t *cpu_infos)
2318
- {
2319
- int i;
2320
- unsigned int mhz, mhz_min, mhz_max;
2321
- int cache_size=SIGAR_FIELD_NOTIMPL;
2322
- size_t size;
2323
- char model[128], vendor[128], *ptr;
2324
-
2325
- size = sizeof(mhz);
2326
-
2327
- (void)sigar_cpu_core_count(sigar);
2328
-
2329
- #if defined(DARWIN)
2330
- {
2331
- int mib[] = { CTL_HW, HW_CPU_FREQ };
2332
- size = sizeof(mhz);
2333
- if (sysctl(mib, NMIB(mib), &mhz, &size, NULL, 0) < 0) {
2334
- mhz = SIGAR_FIELD_NOTIMPL;
2335
- }
2336
- }
2337
- if (sysctlbyname(CTL_HW_FREQ_MAX, &mhz_max, &size, NULL, 0) < 0) {
2338
- mhz_max = SIGAR_FIELD_NOTIMPL;
2339
- }
2340
- if (sysctlbyname(CTL_HW_FREQ_MIN, &mhz_min, &size, NULL, 0) < 0) {
2341
- mhz_min = SIGAR_FIELD_NOTIMPL;
2342
- }
2343
- #elif defined(__FreeBSD__)
2344
- if (sysctlbyname(CTL_HW_FREQ, &mhz, &size, NULL, 0) < 0) {
2345
- mhz = SIGAR_FIELD_NOTIMPL;
2346
- }
2347
- /* TODO */
2348
- mhz_max = SIGAR_FIELD_NOTIMPL;
2349
- mhz_min = SIGAR_FIELD_NOTIMPL;
2350
- #else
2351
- /*XXX OpenBSD*/
2352
- mhz = SIGAR_FIELD_NOTIMPL;
2353
- mhz_max = SIGAR_FIELD_NOTIMPL;
2354
- mhz_min = SIGAR_FIELD_NOTIMPL;
2355
- #endif
2356
-
2357
- if (mhz != SIGAR_FIELD_NOTIMPL) {
2358
- mhz /= 1000000;
2359
- }
2360
- if (mhz_max != SIGAR_FIELD_NOTIMPL) {
2361
- mhz_max /= 1000000;
2362
- }
2363
- if (mhz_min != SIGAR_FIELD_NOTIMPL) {
2364
- mhz_min /= 1000000;
2365
- }
2366
-
2367
- size = sizeof(model);
2368
- #ifdef __OpenBSD__
2369
- if (1) {
2370
- #else
2371
- if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) {
2372
- #endif
2373
- int mib[] = { CTL_HW, HW_MODEL };
2374
- size = sizeof(model);
2375
- if (sysctl(mib, NMIB(mib), &model[0], &size, NULL, 0) < 0) {
2376
- #ifdef DARWIN
2377
- strcpy(model, "powerpc");
2378
- #else
2379
- strcpy(model, "Unknown");
2380
- #endif
2381
- }
2382
- }
2383
-
2384
- if (mhz == SIGAR_FIELD_NOTIMPL) {
2385
- /* freebsd4 */
2386
- mhz = sigar_cpu_mhz_from_model(model);
2387
- }
2388
- /* XXX not sure */
2389
- if (mhz_max == SIGAR_FIELD_NOTIMPL) {
2390
- mhz_max = 0;
2391
- }
2392
- if (mhz_min == SIGAR_FIELD_NOTIMPL) {
2393
- mhz_min = 0;
2394
- }
2395
-
2396
-
2397
- #ifdef DARWIN
2398
- size = sizeof(vendor);
2399
- if (sysctlbyname("machdep.cpu.vendor", &vendor, &size, NULL, 0) < 0) {
2400
- SIGAR_SSTRCPY(vendor, "Apple");
2401
- }
2402
- else {
2403
- /* GenuineIntel -> Intel */
2404
- if (strstr(vendor, "Intel")) {
2405
- SIGAR_SSTRCPY(vendor, "Intel");
2406
- }
2407
- }
2408
- #endif
2409
-
2410
- if ((ptr = strchr(model, ' '))) {
2411
- if (strstr(model, "Intel")) {
2412
- SIGAR_SSTRCPY(vendor, "Intel");
2413
- }
2414
- else if (strstr(model, "AMD")) {
2415
- SIGAR_SSTRCPY(vendor, "AMD");
2416
- }
2417
- else {
2418
- SIGAR_SSTRCPY(vendor, "Unknown");
2419
- }
2420
- SIGAR_SSTRCPY(model, ptr+1);
2421
- }
2422
-
2423
- #ifdef DARWIN
2424
- {
2425
- int mib[] = { CTL_HW, HW_L2CACHESIZE }; /* in bytes */
2426
- size = sizeof(cache_size);
2427
- if (sysctl(mib, NMIB(mib), &cache_size, &size, NULL, 0) < 0) {
2428
- cache_size = SIGAR_FIELD_NOTIMPL;
2429
- }
2430
- else {
2431
- cache_size /= 1024; /* convert to KB */
2432
- }
2433
- }
2434
- #endif
2435
-
2436
- sigar_cpu_info_list_create(cpu_infos);
2437
-
2438
- for (i=0; i<sigar->ncpu; i++) {
2439
- sigar_cpu_info_t *info;
2440
-
2441
- SIGAR_CPU_INFO_LIST_GROW(cpu_infos);
2442
-
2443
- info = &cpu_infos->data[cpu_infos->number++];
2444
-
2445
- SIGAR_SSTRCPY(info->vendor, vendor);
2446
- SIGAR_SSTRCPY(info->model, model);
2447
- sigar_cpu_model_adjust(sigar, info);
2448
-
2449
- info->mhz = mhz;
2450
- info->mhz_max = mhz_max;
2451
- info->mhz_min = mhz_min;
2452
- info->cache_size = cache_size;
2453
- info->total_cores = sigar->ncpu;
2454
- info->cores_per_socket = sigar->lcpu;
2455
- info->total_sockets = sigar_cpu_socket_count(sigar);
2456
- }
2457
-
2458
- return SIGAR_OK;
2459
- }
2460
-
2461
- #define rt_s_addr(sa) ((struct sockaddr_in *)(sa))->sin_addr.s_addr
2462
-
2463
- #ifndef SA_SIZE
2464
- #define SA_SIZE(sa) \
2465
- ( (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ? \
2466
- sizeof(long) : \
2467
- 1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) )
2468
- #endif
2469
-
2470
- int sigar_net_route_list_get(sigar_t *sigar,
2471
- sigar_net_route_list_t *routelist)
2472
- {
2473
- size_t needed;
2474
- int bit;
2475
- char *buf, *next, *lim;
2476
- struct rt_msghdr *rtm;
2477
- int mib[6] = { CTL_NET, PF_ROUTE, 0, 0, NET_RT_DUMP, 0 };
2478
-
2479
- if (sysctl(mib, NMIB(mib), NULL, &needed, NULL, 0) < 0) {
2480
- return errno;
2481
- }
2482
- #if __FreeBSD_version >= 800000
2483
- if (needed == 0) {
2484
- return SIGAR_ENOTIMPL; /*XXX hoping this is an 8.0beta bug*/
2485
- }
2486
- #endif
2487
- buf = malloc(needed);
2488
-
2489
- if (sysctl(mib, NMIB(mib), buf, &needed, NULL, 0) < 0) {
2490
- free(buf);
2491
- return errno;
2492
- }
2493
-
2494
- sigar_net_route_list_create(routelist);
2495
-
2496
- lim = buf + needed;
2497
- for (next = buf; next < lim; next += rtm->rtm_msglen) {
2498
- struct sockaddr *sa;
2499
- sigar_net_route_t *route;
2500
- rtm = (struct rt_msghdr *)next;
2501
-
2502
- if (rtm->rtm_type != RTM_GET) {
2503
- continue;
2504
- }
2505
-
2506
- sa = (struct sockaddr *)(rtm + 1);
2507
-
2508
- if (sa->sa_family != AF_INET) {
2509
- continue;
2510
- }
2511
-
2512
- SIGAR_NET_ROUTE_LIST_GROW(routelist);
2513
- route = &routelist->data[routelist->number++];
2514
- SIGAR_ZERO(route);
2515
-
2516
- route->flags = rtm->rtm_flags;
2517
- if_indextoname(rtm->rtm_index, route->ifname);
2518
-
2519
- for (bit=RTA_DST;
2520
- bit && ((char *)sa < lim);
2521
- bit <<= 1)
2522
- {
2523
- if ((rtm->rtm_addrs & bit) == 0) {
2524
- continue;
2525
- }
2526
- switch (bit) {
2527
- case RTA_DST:
2528
- sigar_net_address_set(route->destination,
2529
- rt_s_addr(sa));
2530
- break;
2531
- case RTA_GATEWAY:
2532
- if (sa->sa_family == AF_INET) {
2533
- sigar_net_address_set(route->gateway,
2534
- rt_s_addr(sa));
2535
- }
2536
- break;
2537
- case RTA_NETMASK:
2538
- sigar_net_address_set(route->mask,
2539
- rt_s_addr(sa));
2540
- break;
2541
- case RTA_IFA:
2542
- break;
2543
- }
2544
-
2545
- sa = (struct sockaddr *)((char *)sa + SA_SIZE(sa));
2546
- }
2547
- }
2548
-
2549
- free(buf);
2550
-
2551
- return SIGAR_OK;
2552
- }
2553
-
2554
- typedef enum {
2555
- IFMSG_ITER_LIST,
2556
- IFMSG_ITER_GET
2557
- } ifmsg_iter_e;
2558
-
2559
- typedef struct {
2560
- const char *name;
2561
- ifmsg_iter_e type;
2562
- union {
2563
- sigar_net_interface_list_t *iflist;
2564
- struct if_msghdr *ifm;
2565
- } data;
2566
- } ifmsg_iter_t;
2567
-
2568
- static int sigar_ifmsg_init(sigar_t *sigar)
2569
- {
2570
- int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_IFLIST, 0 };
2571
- size_t len;
2572
-
2573
- if (sysctl(mib, NMIB(mib), NULL, &len, NULL, 0) < 0) {
2574
- return errno;
2575
- }
2576
-
2577
- if (sigar->ifconf_len < len) {
2578
- sigar->ifconf_buf = realloc(sigar->ifconf_buf, len);
2579
- sigar->ifconf_len = len;
2580
- }
2581
-
2582
- if (sysctl(mib, NMIB(mib), sigar->ifconf_buf, &len, NULL, 0) < 0) {
2583
- return errno;
2584
- }
2585
-
2586
- return SIGAR_OK;
2587
- }
2588
-
2589
- /**
2590
- * @param name name of the interface
2591
- * @param name_len length of name (w/o \0)
2592
- */
2593
- static int has_ifaddr(char *name, size_t name_len)
2594
- {
2595
- int sock, status;
2596
- struct ifreq ifr;
2597
-
2598
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2599
- return errno;
2600
- }
2601
- strncpy(ifr.ifr_name, name, MIN(sizeof(ifr.ifr_name) - 1, name_len));
2602
- ifr.ifr_name[MIN(sizeof(ifr.ifr_name) - 1, name_len)] = '\0';
2603
- if (ioctl(sock, SIOCGIFADDR, &ifr) == 0) {
2604
- status = SIGAR_OK;
2605
- }
2606
- else {
2607
- status = errno;
2608
- }
2609
-
2610
- close(sock);
2611
- return status;
2612
- }
2613
-
2614
- static int sigar_ifmsg_iter(sigar_t *sigar, ifmsg_iter_t *iter)
2615
- {
2616
- char *end = sigar->ifconf_buf + sigar->ifconf_len;
2617
- char *ptr = sigar->ifconf_buf;
2618
-
2619
- if (iter->type == IFMSG_ITER_LIST) {
2620
- sigar_net_interface_list_create(iter->data.iflist);
2621
- }
2622
-
2623
- while (ptr < end) {
2624
- char *name;
2625
- struct sockaddr_dl *sdl;
2626
- struct if_msghdr *ifm = (struct if_msghdr *)ptr;
2627
-
2628
- if (ifm->ifm_type != RTM_IFINFO) {
2629
- break;
2630
- }
2631
-
2632
- ptr += ifm->ifm_msglen;
2633
-
2634
- while (ptr < end) {
2635
- struct if_msghdr *next = (struct if_msghdr *)ptr;
2636
-
2637
- if (next->ifm_type != RTM_NEWADDR) {
2638
- break;
2639
- }
2640
-
2641
- ptr += next->ifm_msglen;
2642
- }
2643
-
2644
- sdl = (struct sockaddr_dl *)(ifm + 1);
2645
- if (sdl->sdl_family != AF_LINK) {
2646
- continue;
2647
- }
2648
-
2649
- switch (iter->type) {
2650
- case IFMSG_ITER_LIST:
2651
- if (sdl->sdl_type == IFT_OTHER) {
2652
- if (has_ifaddr(sdl->sdl_data, sdl->sdl_nlen) != SIGAR_OK) {
2653
- break;
2654
- }
2655
- }
2656
- else if (!((sdl->sdl_type == IFT_ETHER) ||
2657
- (sdl->sdl_type == IFT_LOOP)))
2658
- {
2659
- break; /* XXX deal w/ other weirdo interfaces */
2660
- }
2661
-
2662
- SIGAR_NET_IFLIST_GROW(iter->data.iflist);
2663
-
2664
- /* sdl_data doesn't include a trailing \0, it is only sdl_nlen long */
2665
- name = malloc(sdl->sdl_nlen+1);
2666
- memcpy(name, sdl->sdl_data, sdl->sdl_nlen);
2667
- name[sdl->sdl_nlen] = '\0'; /* add the missing \0 */
2668
-
2669
- iter->data.iflist->data[iter->data.iflist->number++] = name;
2670
- break;
2671
-
2672
- case IFMSG_ITER_GET:
2673
- if (strlen(iter->name) == sdl->sdl_nlen && 0 == memcmp(iter->name, sdl->sdl_data, sdl->sdl_nlen)) {
2674
- iter->data.ifm = ifm;
2675
- return SIGAR_OK;
2676
- }
2677
- }
2678
- }
2679
-
2680
- switch (iter->type) {
2681
- case IFMSG_ITER_LIST:
2682
- return SIGAR_OK;
2683
-
2684
- case IFMSG_ITER_GET:
2685
- default:
2686
- return ENXIO;
2687
- }
2688
- }
2689
-
2690
- int sigar_net_interface_list_get(sigar_t *sigar,
2691
- sigar_net_interface_list_t *iflist)
2692
- {
2693
- int status;
2694
- ifmsg_iter_t iter;
2695
-
2696
- if ((status = sigar_ifmsg_init(sigar)) != SIGAR_OK) {
2697
- return status;
2698
- }
2699
-
2700
- iter.type = IFMSG_ITER_LIST;
2701
- iter.data.iflist = iflist;
2702
-
2703
- return sigar_ifmsg_iter(sigar, &iter);
2704
- }
2705
-
2706
- #include <ifaddrs.h>
2707
-
2708
- /* in6_prefixlen derived from freebsd/sbin/ifconfig/af_inet6.c */
2709
- static int sigar_in6_prefixlen(struct sockaddr *netmask)
2710
- {
2711
- struct in6_addr *addr = SIGAR_SIN6_ADDR(netmask);
2712
- u_char *name = (u_char *)addr;
2713
- int size = sizeof(*addr);
2714
- int byte, bit, plen = 0;
2715
-
2716
- for (byte = 0; byte < size; byte++, plen += 8) {
2717
- if (name[byte] != 0xff) {
2718
- break;
2719
- }
2720
- }
2721
- if (byte == size) {
2722
- return plen;
2723
- }
2724
- for (bit = 7; bit != 0; bit--, plen++) {
2725
- if (!(name[byte] & (1 << bit))) {
2726
- break;
2727
- }
2728
- }
2729
- for (; bit != 0; bit--) {
2730
- if (name[byte] & (1 << bit)) {
2731
- return 0;
2732
- }
2733
- }
2734
- byte++;
2735
- for (; byte < size; byte++) {
2736
- if (name[byte]) {
2737
- return 0;
2738
- }
2739
- }
2740
- return plen;
2741
- }
2742
-
2743
- int sigar_net_interface_ipv6_config_get(sigar_t *sigar, const char *name,
2744
- sigar_net_interface_config_t *ifconfig)
2745
- {
2746
- int status = SIGAR_ENOENT;
2747
- struct ifaddrs *addrs, *ifa;
2748
-
2749
- if (getifaddrs(&addrs) != 0) {
2750
- return errno;
2751
- }
2752
-
2753
- for (ifa=addrs; ifa; ifa=ifa->ifa_next) {
2754
- if (ifa->ifa_addr &&
2755
- (ifa->ifa_addr->sa_family == AF_INET6) &&
2756
- strEQ(ifa->ifa_name, name))
2757
- {
2758
- status = SIGAR_OK;
2759
- break;
2760
- }
2761
- }
2762
-
2763
- if (status == SIGAR_OK) {
2764
- struct in6_addr *addr = SIGAR_SIN6_ADDR(ifa->ifa_addr);
2765
-
2766
- sigar_net_address6_set(ifconfig->address6, addr);
2767
- sigar_net_interface_scope6_set(ifconfig, addr);
2768
- ifconfig->prefix6_length = sigar_in6_prefixlen(ifa->ifa_netmask);
2769
- }
2770
-
2771
- freeifaddrs(addrs);
2772
-
2773
- return status;
2774
- }
2775
-
2776
- int sigar_net_interface_config_get(sigar_t *sigar, const char *name,
2777
- sigar_net_interface_config_t *ifconfig)
2778
- {
2779
- int sock;
2780
- int status;
2781
- ifmsg_iter_t iter;
2782
- struct if_msghdr *ifm;
2783
- struct sockaddr_dl *sdl;
2784
- struct ifreq ifr;
2785
-
2786
- if (!name) {
2787
- return sigar_net_interface_config_primary_get(sigar, ifconfig);
2788
- }
2789
-
2790
- if (sigar->ifconf_len == 0) {
2791
- if ((status = sigar_ifmsg_init(sigar)) != SIGAR_OK) {
2792
- return status;
2793
- }
2794
- }
2795
-
2796
- SIGAR_ZERO(ifconfig);
2797
-
2798
- iter.type = IFMSG_ITER_GET;
2799
- iter.name = name;
2800
-
2801
- if ((status = sigar_ifmsg_iter(sigar, &iter)) != SIGAR_OK) {
2802
- return status;
2803
- }
2804
-
2805
- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
2806
- return errno;
2807
- }
2808
-
2809
- ifm = iter.data.ifm;
2810
-
2811
- SIGAR_SSTRCPY(ifconfig->name, name);
2812
-
2813
- sdl = (struct sockaddr_dl *)(ifm + 1);
2814
-
2815
- sigar_net_address_mac_set(ifconfig->hwaddr,
2816
- LLADDR(sdl),
2817
- sdl->sdl_alen);
2818
-
2819
- ifconfig->flags = ifm->ifm_flags;
2820
- ifconfig->mtu = ifm->ifm_data.ifi_mtu;
2821
- ifconfig->metric = ifm->ifm_data.ifi_metric;
2822
-
2823
- SIGAR_SSTRCPY(ifr.ifr_name, name);
2824
-
2825
- #define ifr_s_addr(ifr) \
2826
- ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr
2827
-
2828
- if (!ioctl(sock, SIOCGIFADDR, &ifr)) {
2829
- sigar_net_address_set(ifconfig->address,
2830
- ifr_s_addr(ifr));
2831
- }
2832
-
2833
- if (!ioctl(sock, SIOCGIFNETMASK, &ifr)) {
2834
- sigar_net_address_set(ifconfig->netmask,
2835
- ifr_s_addr(ifr));
2836
- }
2837
-
2838
- if (ifconfig->flags & IFF_LOOPBACK) {
2839
- sigar_net_address_set(ifconfig->destination,
2840
- ifconfig->address.addr.in);
2841
- sigar_net_address_set(ifconfig->broadcast, 0);
2842
- SIGAR_SSTRCPY(ifconfig->type,
2843
- SIGAR_NIC_LOOPBACK);
2844
- }
2845
- else {
2846
- if (!ioctl(sock, SIOCGIFDSTADDR, &ifr)) {
2847
- sigar_net_address_set(ifconfig->destination,
2848
- ifr_s_addr(ifr));
2849
- }
2850
-
2851
- if (!ioctl(sock, SIOCGIFBRDADDR, &ifr)) {
2852
- sigar_net_address_set(ifconfig->broadcast,
2853
- ifr_s_addr(ifr));
2854
- }
2855
- SIGAR_SSTRCPY(ifconfig->type,
2856
- SIGAR_NIC_ETHERNET);
2857
- }
2858
-
2859
- close(sock);
2860
-
2861
- /* XXX can we get a better description like win32? */
2862
- SIGAR_SSTRCPY(ifconfig->description,
2863
- ifconfig->name);
2864
-
2865
- sigar_net_interface_ipv6_config_init(ifconfig);
2866
- sigar_net_interface_ipv6_config_get(sigar, name, ifconfig);
2867
-
2868
- return SIGAR_OK;
2869
- }
2870
-
2871
- int sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
2872
- sigar_net_interface_stat_t *ifstat)
2873
- {
2874
- int status;
2875
- ifmsg_iter_t iter;
2876
- struct if_msghdr *ifm;
2877
-
2878
- if ((status = sigar_ifmsg_init(sigar)) != SIGAR_OK) {
2879
- return status;
2880
- }
2881
-
2882
- iter.type = IFMSG_ITER_GET;
2883
- iter.name = name;
2884
-
2885
- if ((status = sigar_ifmsg_iter(sigar, &iter)) != SIGAR_OK) {
2886
- return status;
2887
- }
2888
-
2889
- ifm = iter.data.ifm;
2890
-
2891
- ifstat->rx_bytes = ifm->ifm_data.ifi_ibytes;
2892
- ifstat->rx_packets = ifm->ifm_data.ifi_ipackets;
2893
- ifstat->rx_errors = ifm->ifm_data.ifi_ierrors;
2894
- ifstat->rx_dropped = ifm->ifm_data.ifi_iqdrops;
2895
- ifstat->rx_overruns = SIGAR_FIELD_NOTIMPL;
2896
- ifstat->rx_frame = SIGAR_FIELD_NOTIMPL;
2897
-
2898
- ifstat->tx_bytes = ifm->ifm_data.ifi_obytes;
2899
- ifstat->tx_packets = ifm->ifm_data.ifi_opackets;
2900
- ifstat->tx_errors = ifm->ifm_data.ifi_oerrors;
2901
- ifstat->tx_collisions = ifm->ifm_data.ifi_collisions;
2902
- ifstat->tx_dropped = SIGAR_FIELD_NOTIMPL;
2903
- ifstat->tx_overruns = SIGAR_FIELD_NOTIMPL;
2904
- ifstat->tx_carrier = SIGAR_FIELD_NOTIMPL;
2905
-
2906
- ifstat->speed = ifm->ifm_data.ifi_baudrate;
2907
-
2908
- return SIGAR_OK;
2909
- }
2910
-
2911
- static int net_connection_state_get(int state)
2912
- {
2913
- switch (state) {
2914
- case TCPS_CLOSED:
2915
- return SIGAR_TCP_CLOSE;
2916
- case TCPS_LISTEN:
2917
- return SIGAR_TCP_LISTEN;
2918
- case TCPS_SYN_SENT:
2919
- return SIGAR_TCP_SYN_SENT;
2920
- case TCPS_SYN_RECEIVED:
2921
- return SIGAR_TCP_SYN_RECV;
2922
- case TCPS_ESTABLISHED:
2923
- return SIGAR_TCP_ESTABLISHED;
2924
- case TCPS_CLOSE_WAIT:
2925
- return SIGAR_TCP_CLOSE_WAIT;
2926
- case TCPS_FIN_WAIT_1:
2927
- return SIGAR_TCP_FIN_WAIT1;
2928
- case TCPS_CLOSING:
2929
- return SIGAR_TCP_CLOSING;
2930
- case TCPS_LAST_ACK:
2931
- return SIGAR_TCP_LAST_ACK;
2932
- case TCPS_FIN_WAIT_2:
2933
- return SIGAR_TCP_FIN_WAIT2;
2934
- case TCPS_TIME_WAIT:
2935
- return SIGAR_TCP_TIME_WAIT;
2936
- default:
2937
- return SIGAR_TCP_UNKNOWN;
2938
- }
2939
- }
2940
-
2941
- #if defined(__OpenBSD__) || defined(__NetBSD__)
2942
- static int net_connection_get(sigar_net_connection_walker_t *walker, int proto)
2943
- {
2944
- int status;
2945
- int istcp = 0, type;
2946
- int flags = walker->flags;
2947
- struct inpcbtable table;
2948
- struct inpcb *head, *next, *prev;
2949
- sigar_t *sigar = walker->sigar;
2950
- u_long offset;
2951
-
2952
- switch (proto) {
2953
- case IPPROTO_TCP:
2954
- offset = sigar->koffsets[KOFFSET_TCBTABLE];
2955
- istcp = 1;
2956
- type = SIGAR_NETCONN_TCP;
2957
- break;
2958
- case IPPROTO_UDP:
2959
- default:
2960
- return SIGAR_ENOTIMPL;
2961
- }
2962
-
2963
-
2964
- status = kread(sigar, &table, sizeof(table), offset);
2965
-
2966
- if (status != SIGAR_OK) {
2967
- return status;
2968
- }
2969
-
2970
- prev = head =
2971
- (struct inpcb *)&CIRCLEQ_FIRST(&((struct inpcbtable *)offset)->inpt_queue);
2972
-
2973
- next = (struct inpcb *)CIRCLEQ_FIRST(&table.inpt_queue);
2974
-
2975
- while (next != head) {
2976
- struct inpcb inpcb;
2977
- struct tcpcb tcpcb;
2978
- struct socket socket;
2979
-
2980
- status = kread(sigar, &inpcb, sizeof(inpcb), (long)next);
2981
- prev = next;
2982
- next = (struct inpcb *)CIRCLEQ_NEXT(&inpcb, inp_queue);
2983
-
2984
- kread(sigar, &socket, sizeof(socket), (u_long)inpcb.inp_socket);
2985
-
2986
- if ((((flags & SIGAR_NETCONN_SERVER) && socket.so_qlimit) ||
2987
- ((flags & SIGAR_NETCONN_CLIENT) && !socket.so_qlimit)))
2988
- {
2989
- sigar_net_connection_t conn;
2990
-
2991
- SIGAR_ZERO(&conn);
2992
-
2993
- if (istcp) {
2994
- kread(sigar, &tcpcb, sizeof(tcpcb), (u_long)inpcb.inp_ppcb);
2995
- }
2996
-
2997
- #ifdef __NetBSD__
2998
- if (inpcb.inp_af == AF_INET6) {
2999
- /*XXX*/
3000
- continue;
3001
- }
3002
- #else
3003
- if (inpcb.inp_flags & INP_IPV6) {
3004
- sigar_net_address6_set(conn.local_address,
3005
- &inpcb.inp_laddr6.s6_addr);
3006
-
3007
- sigar_net_address6_set(conn.remote_address,
3008
- &inpcb.inp_faddr6.s6_addr);
3009
- }
3010
- #endif
3011
- else {
3012
- sigar_net_address_set(conn.local_address,
3013
- inpcb.inp_laddr.s_addr);
3014
-
3015
- sigar_net_address_set(conn.remote_address,
3016
- inpcb.inp_faddr.s_addr);
3017
- }
3018
-
3019
- conn.local_port = ntohs(inpcb.inp_lport);
3020
- conn.remote_port = ntohs(inpcb.inp_fport);
3021
- conn.receive_queue = socket.so_rcv.sb_cc;
3022
- conn.send_queue = socket.so_snd.sb_cc;
3023
- conn.uid = socket.so_pgid;
3024
- conn.type = type;
3025
-
3026
- if (!istcp) {
3027
- conn.state = SIGAR_TCP_UNKNOWN;
3028
- if (walker->add_connection(walker, &conn) != SIGAR_OK) {
3029
- break;
3030
- }
3031
- continue;
3032
- }
3033
-
3034
- conn.state = net_connection_state_get(tcpcb.t_state);
3035
-
3036
- if (walker->add_connection(walker, &conn) != SIGAR_OK) {
3037
- break;
3038
- }
3039
- }
3040
- }
3041
-
3042
- return SIGAR_OK;
3043
- }
3044
- #else
3045
- static int net_connection_get(sigar_net_connection_walker_t *walker, int proto)
3046
- {
3047
- int flags = walker->flags;
3048
- int type, istcp = 0;
3049
- char *buf;
3050
- const char *mibvar;
3051
- struct tcpcb *tp = NULL;
3052
- struct inpcb *inp;
3053
- struct xinpgen *xig, *oxig;
3054
- struct xsocket *so;
3055
- size_t len;
3056
-
3057
- switch (proto) {
3058
- case IPPROTO_TCP:
3059
- mibvar = "net.inet.tcp.pcblist";
3060
- istcp = 1;
3061
- type = SIGAR_NETCONN_TCP;
3062
- break;
3063
- case IPPROTO_UDP:
3064
- mibvar = "net.inet.udp.pcblist";
3065
- type = SIGAR_NETCONN_UDP;
3066
- break;
3067
- default:
3068
- mibvar = "net.inet.raw.pcblist";
3069
- type = SIGAR_NETCONN_RAW;
3070
- break;
3071
- }
3072
-
3073
- len = 0;
3074
- if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
3075
- return errno;
3076
- }
3077
- if ((buf = malloc(len)) == 0) {
3078
- return errno;
3079
- }
3080
- if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
3081
- free(buf);
3082
- return errno;
3083
- }
3084
-
3085
- oxig = xig = (struct xinpgen *)buf;
3086
- for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
3087
- xig->xig_len > sizeof(struct xinpgen);
3088
- xig = (struct xinpgen *)((char *)xig + xig->xig_len))
3089
- {
3090
- if (istcp) {
3091
- struct xtcpcb *cb = (struct xtcpcb *)xig;
3092
- tp = &cb->xt_tp;
3093
- inp = &cb->xt_inp;
3094
- so = &cb->xt_socket;
3095
- }
3096
- else {
3097
- struct xinpcb *cb = (struct xinpcb *)xig;
3098
- inp = &cb->xi_inp;
3099
- so = &cb->xi_socket;
3100
- }
3101
-
3102
- if (so->xso_protocol != proto) {
3103
- continue;
3104
- }
3105
-
3106
- if (inp->inp_gencnt > oxig->xig_gen) {
3107
- continue;
3108
- }
3109
-
3110
- if ((((flags & SIGAR_NETCONN_SERVER) && so->so_qlimit) ||
3111
- ((flags & SIGAR_NETCONN_CLIENT) && !so->so_qlimit)))
3112
- {
3113
- sigar_net_connection_t conn;
3114
-
3115
- SIGAR_ZERO(&conn);
3116
-
3117
- if (inp->inp_vflag & INP_IPV6) {
3118
- sigar_net_address6_set(conn.local_address,
3119
- &inp->in6p_laddr.s6_addr);
3120
-
3121
- sigar_net_address6_set(conn.remote_address,
3122
- &inp->in6p_faddr.s6_addr);
3123
- }
3124
- else {
3125
- sigar_net_address_set(conn.local_address,
3126
- inp->inp_laddr.s_addr);
3127
-
3128
- sigar_net_address_set(conn.remote_address,
3129
- inp->inp_faddr.s_addr);
3130
- }
3131
-
3132
- conn.local_port = ntohs(inp->inp_lport);
3133
- conn.remote_port = ntohs(inp->inp_fport);
3134
- conn.receive_queue = so->so_rcv.sb_cc;
3135
- conn.send_queue = so->so_snd.sb_cc;
3136
- conn.uid = so->so_pgid;
3137
- conn.type = type;
3138
-
3139
- if (!istcp) {
3140
- conn.state = SIGAR_TCP_UNKNOWN;
3141
- if (walker->add_connection(walker, &conn) != SIGAR_OK) {
3142
- break;
3143
- }
3144
- continue;
3145
- }
3146
-
3147
- conn.state = net_connection_state_get(tp->t_state);
3148
-
3149
- if (walker->add_connection(walker, &conn) != SIGAR_OK) {
3150
- break;
3151
- }
3152
- }
3153
- }
3154
-
3155
- free(buf);
3156
-
3157
- return SIGAR_OK;
3158
- }
3159
- #endif
3160
-
3161
- int sigar_net_connection_walk(sigar_net_connection_walker_t *walker)
3162
- {
3163
- int flags = walker->flags;
3164
- int status;
3165
-
3166
- if (flags & SIGAR_NETCONN_TCP) {
3167
- status = net_connection_get(walker, IPPROTO_TCP);
3168
- if (status != SIGAR_OK) {
3169
- return status;
3170
- }
3171
- }
3172
- if (flags & SIGAR_NETCONN_UDP) {
3173
- status = net_connection_get(walker, IPPROTO_UDP);
3174
- if (status != SIGAR_OK) {
3175
- return status;
3176
- }
3177
- }
3178
-
3179
- return SIGAR_OK;
3180
- }
3181
-
3182
- SIGAR_DECLARE(int)
3183
- sigar_tcp_get(sigar_t *sigar,
3184
- sigar_tcp_t *tcp)
3185
- {
3186
- struct tcpstat mib;
3187
- #if !defined(TCPCTL_STATS) && (defined(__OpenBSD__) || defined(__NetBSD__))
3188
- int status =
3189
- kread(sigar, &mib, sizeof(mib),
3190
- sigar->koffsets[KOFFSET_TCPSTAT]);
3191
- if (status != SIGAR_OK) {
3192
- return status;
3193
- }
3194
- #else
3195
- int var[4] = { CTL_NET, PF_INET, IPPROTO_TCP, TCPCTL_STATS };
3196
- size_t len = sizeof(mib);
3197
-
3198
- if (sysctl(var, NMIB(var), &mib, &len, NULL, 0) < 0) {
3199
- return errno;
3200
- }
3201
- #endif
3202
-
3203
- tcp->active_opens = mib.tcps_connattempt;
3204
- tcp->passive_opens = mib.tcps_accepts;
3205
- tcp->attempt_fails = mib.tcps_conndrops;
3206
- tcp->estab_resets = mib.tcps_drops;
3207
- if (sigar_tcp_curr_estab(sigar, tcp) != SIGAR_OK) {
3208
- tcp->curr_estab = -1;
3209
- }
3210
- tcp->in_segs = mib.tcps_rcvtotal;
3211
- tcp->out_segs = mib.tcps_sndtotal - mib.tcps_sndrexmitpack;
3212
- tcp->retrans_segs = mib.tcps_sndrexmitpack;
3213
- tcp->in_errs =
3214
- mib.tcps_rcvbadsum +
3215
- mib.tcps_rcvbadoff +
3216
- mib.tcps_rcvmemdrop +
3217
- mib.tcps_rcvshort;
3218
- tcp->out_rsts = -1; /* XXX mib.tcps_sndctrl - mib.tcps_closed; ? */
3219
-
3220
- return SIGAR_OK;
3221
- }
3222
-
3223
- #ifndef SIGAR_FREEBSD5_NFSSTAT
3224
- static int get_nfsstats(struct nfsstats *stats)
3225
- {
3226
- size_t len = sizeof(*stats);
3227
- int mib[] = { CTL_VFS, 2, NFS_NFSSTATS };
3228
-
3229
- if (sysctl(mib, NMIB(mib), stats, &len, NULL, 0) < 0) {
3230
- return errno;
3231
- }
3232
- else {
3233
- return SIGAR_OK;
3234
- }
3235
- }
3236
- #endif
3237
-
3238
- #if defined(__OpenBSD__)
3239
- typedef uint64_t rpc_cnt_t;
3240
- #else
3241
- typedef int rpc_cnt_t;
3242
- #endif
3243
-
3244
- static void map_nfs_stats(sigar_nfs_v3_t *nfs, rpc_cnt_t *rpc)
3245
- {
3246
- nfs->null = rpc[NFSPROC_NULL];
3247
- nfs->getattr = rpc[NFSPROC_GETATTR];
3248
- nfs->setattr = rpc[NFSPROC_SETATTR];
3249
- nfs->lookup = rpc[NFSPROC_LOOKUP];
3250
- nfs->access = rpc[NFSPROC_ACCESS];
3251
- nfs->readlink = rpc[NFSPROC_READLINK];
3252
- nfs->read = rpc[NFSPROC_READ];
3253
- nfs->write = rpc[NFSPROC_WRITE];
3254
- nfs->create = rpc[NFSPROC_CREATE];
3255
- nfs->mkdir = rpc[NFSPROC_MKDIR];
3256
- nfs->symlink = rpc[NFSPROC_SYMLINK];
3257
- nfs->mknod = rpc[NFSPROC_MKNOD];
3258
- nfs->remove = rpc[NFSPROC_REMOVE];
3259
- nfs->rmdir = rpc[NFSPROC_RMDIR];
3260
- nfs->rename = rpc[NFSPROC_RENAME];
3261
- nfs->link = rpc[NFSPROC_LINK];
3262
- nfs->readdir = rpc[NFSPROC_READDIR];
3263
- nfs->readdirplus = rpc[NFSPROC_READDIRPLUS];
3264
- nfs->fsstat = rpc[NFSPROC_FSSTAT];
3265
- nfs->fsinfo = rpc[NFSPROC_FSINFO];
3266
- nfs->pathconf = rpc[NFSPROC_PATHCONF];
3267
- nfs->commit = rpc[NFSPROC_COMMIT];
3268
- }
3269
-
3270
- int sigar_nfs_client_v2_get(sigar_t *sigar,
3271
- sigar_nfs_client_v2_t *nfs)
3272
- {
3273
- return SIGAR_ENOTIMPL;
3274
- }
3275
-
3276
- int sigar_nfs_server_v2_get(sigar_t *sigar,
3277
- sigar_nfs_server_v2_t *nfs)
3278
- {
3279
- return SIGAR_ENOTIMPL;
3280
- }
3281
-
3282
- int sigar_nfs_client_v3_get(sigar_t *sigar,
3283
- sigar_nfs_client_v3_t *nfs)
3284
- {
3285
- #ifdef SIGAR_FREEBSD5_NFSSTAT
3286
- struct nfsstats stats;
3287
- size_t size = sizeof(stats);
3288
-
3289
- if (sysctlbyname("vfs.nfs.nfsstats", &stats, &size, NULL, 0) == -1) {
3290
- return errno;
3291
- }
3292
-
3293
- map_nfs_stats((sigar_nfs_v3_t *)nfs, &stats.rpccnt[0]);
3294
- #else
3295
- int status;
3296
- struct nfsstats stats;
3297
-
3298
- if ((status = get_nfsstats(&stats)) != SIGAR_OK) {
3299
- return status;
3300
- }
3301
-
3302
- map_nfs_stats((sigar_nfs_v3_t *)nfs, &stats.rpccnt[0]);
3303
- #endif
3304
-
3305
- return SIGAR_OK;
3306
- }
3307
-
3308
- int sigar_nfs_server_v3_get(sigar_t *sigar,
3309
- sigar_nfs_server_v3_t *nfs)
3310
- {
3311
- #ifdef SIGAR_FREEBSD5_NFSSTAT
3312
- struct nfsrvstats stats;
3313
- size_t size = sizeof(stats);
3314
-
3315
- if (sysctlbyname("vfs.nfsrv.nfsrvstats", &stats, &size, NULL, 0) == -1) {
3316
- return errno;
3317
- }
3318
-
3319
- map_nfs_stats((sigar_nfs_v3_t *)nfs, &stats.srvrpccnt[0]);
3320
- #else
3321
- int status;
3322
- struct nfsstats stats;
3323
-
3324
- if ((status = get_nfsstats(&stats)) != SIGAR_OK) {
3325
- return status;
3326
- }
3327
-
3328
- map_nfs_stats((sigar_nfs_v3_t *)nfs, &stats.srvrpccnt[0]);
3329
- #endif
3330
-
3331
- return SIGAR_OK;
3332
- }
3333
-
3334
- static char *get_hw_type(int type)
3335
- {
3336
- switch (type) {
3337
- case IFT_ETHER:
3338
- return "ether";
3339
- case IFT_ISO88025:
3340
- return "tr";
3341
- case IFT_FDDI:
3342
- return "fddi";
3343
- case IFT_ATM:
3344
- return "atm";
3345
- case IFT_L2VLAN:
3346
- return "vlan";
3347
- case IFT_IEEE1394:
3348
- return "firewire";
3349
- #ifdef IFT_BRIDGE
3350
- case IFT_BRIDGE:
3351
- return "bridge";
3352
- #endif
3353
- default:
3354
- return "unknown";
3355
- }
3356
- }
3357
-
3358
- int sigar_arp_list_get(sigar_t *sigar,
3359
- sigar_arp_list_t *arplist)
3360
- {
3361
- size_t needed;
3362
- char *lim, *buf, *next;
3363
- struct rt_msghdr *rtm;
3364
- struct sockaddr_inarp *sin;
3365
- struct sockaddr_dl *sdl;
3366
- int mib[] = { CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO };
3367
-
3368
- if (sysctl(mib, NMIB(mib), NULL, &needed, NULL, 0) < 0) {
3369
- return errno;
3370
- }
3371
-
3372
- if (needed == 0) { /* empty cache */
3373
- return 0;
3374
- }
3375
-
3376
- buf = malloc(needed);
3377
-
3378
- if (sysctl(mib, NMIB(mib), buf, &needed, NULL, 0) < 0) {
3379
- free(buf);
3380
- return errno;
3381
- }
3382
-
3383
- sigar_arp_list_create(arplist);
3384
-
3385
- lim = buf + needed;
3386
- for (next = buf; next < lim; next += rtm->rtm_msglen) {
3387
- sigar_arp_t *arp;
3388
-
3389
- SIGAR_ARP_LIST_GROW(arplist);
3390
- arp = &arplist->data[arplist->number++];
3391
-
3392
- rtm = (struct rt_msghdr *)next;
3393
- sin = (struct sockaddr_inarp *)(rtm + 1);
3394
- sdl = (struct sockaddr_dl *)((char *)sin + SA_SIZE(sin));
3395
-
3396
- sigar_net_address_set(arp->address, sin->sin_addr.s_addr);
3397
- sigar_net_address_mac_set(arp->hwaddr, LLADDR(sdl), sdl->sdl_alen);
3398
- if_indextoname(sdl->sdl_index, arp->ifname);
3399
- arp->flags = rtm->rtm_flags;
3400
-
3401
- SIGAR_SSTRCPY(arp->type, get_hw_type(sdl->sdl_type));
3402
- }
3403
-
3404
- free(buf);
3405
-
3406
- return SIGAR_OK;
3407
- }
3408
-
3409
- #if defined(__FreeBSD__) && /*XXX*/ (__FreeBSD_version < 800000)
3410
-
3411
- #define _KERNEL
3412
- #include <sys/file.h>
3413
- #undef _KERNEL
3414
-
3415
- /* derived from
3416
- * /usr/ports/security/pidentd/work/pidentd-3.0.16/src/k_freebsd2.c
3417
- */
3418
- int sigar_proc_port_get(sigar_t *sigar, int protocol,
3419
- unsigned long port, sigar_pid_t *pid)
3420
- {
3421
- struct nlist nl[2];
3422
- struct inpcbhead tcb;
3423
- struct socket *sockp = NULL;
3424
- struct kinfo_proc *pinfo;
3425
- struct inpcb *head, pcbp;
3426
- int i, nentries, status;
3427
-
3428
- if (protocol != SIGAR_NETCONN_TCP) {
3429
- return SIGAR_ENOTIMPL;
3430
- }
3431
-
3432
- if (!sigar->kmem) {
3433
- return SIGAR_EPERM_KMEM;
3434
- }
3435
-
3436
- nl[0].n_name = "_tcb"; /* XXX cache */
3437
- nl[1].n_name = "";
3438
- if (kvm_nlist(sigar->kmem, nl) < 0) {
3439
- return errno;
3440
- }
3441
-
3442
- status = kread(sigar, &tcb, sizeof(tcb), nl[0].n_value);
3443
- if (status != SIGAR_OK) {
3444
- return status;
3445
- }
3446
-
3447
- for (head = tcb.lh_first; head != NULL;
3448
- head = pcbp.inp_list.le_next)
3449
- {
3450
- status = kread(sigar, &pcbp, sizeof(pcbp), (long)head);
3451
- if (status != SIGAR_OK) {
3452
- return status;
3453
- }
3454
- if (!(pcbp.inp_vflag & INP_IPV4)) {
3455
- continue;
3456
- }
3457
- if (pcbp.inp_fport != 0) {
3458
- continue;
3459
- }
3460
- if (ntohs(pcbp.inp_lport) == port) {
3461
- sockp = pcbp.inp_socket;
3462
- break;
3463
- }
3464
- }
3465
-
3466
- if (!sockp) {
3467
- return ENOENT;
3468
- }
3469
-
3470
- pinfo = kvm_getprocs(sigar->kmem, KERN_PROC_PROC, 0, &nentries);
3471
- if (!pinfo) {
3472
- return errno;
3473
- }
3474
-
3475
- for (i=0; i<nentries; i++) {
3476
- if (pinfo[i].KI_FLAG & P_SYSTEM) {
3477
- continue;
3478
- }
3479
- if (pinfo[i].KI_FD) {
3480
- struct filedesc pfd;
3481
- struct file **ofiles, ofile;
3482
- int j, osize;
3483
-
3484
- status = kread(sigar, &pfd, sizeof(pfd), (long)pinfo[i].KI_FD);
3485
- if (status != SIGAR_OK) {
3486
- return status;
3487
- }
3488
-
3489
- osize = pfd.fd_nfiles * sizeof(struct file *);
3490
- ofiles = malloc(osize); /* XXX reuse */
3491
- if (!ofiles) {
3492
- return errno;
3493
- }
3494
-
3495
- status = kread(sigar, ofiles, osize, (long)pfd.fd_ofiles);
3496
- if (status != SIGAR_OK) {
3497
- free(ofiles);
3498
- return status;
3499
- }
3500
-
3501
- for (j=0; j<pfd.fd_nfiles; j++) {
3502
- if (!ofiles[j]) {
3503
- continue;
3504
- }
3505
-
3506
- status = kread(sigar, &ofile, sizeof(ofile), (long)ofiles[j]);
3507
- if (status != SIGAR_OK) {
3508
- free(ofiles);
3509
- return status;
3510
- }
3511
-
3512
- if (ofile.f_count == 0) {
3513
- continue;
3514
- }
3515
-
3516
- if (ofile.f_type == DTYPE_SOCKET &&
3517
- (struct socket *)ofile.f_data == sockp)
3518
- {
3519
- *pid = pinfo[i].KI_PID;
3520
- free(ofiles);
3521
- return SIGAR_OK;
3522
- }
3523
- }
3524
-
3525
- free(ofiles);
3526
- }
3527
- }
3528
-
3529
- return ENOENT;
3530
- }
3531
-
3532
- #elif defined(DARWIN) && defined(DARWIN_HAS_LIBPROC_H)
3533
-
3534
- int sigar_proc_port_get(sigar_t *sigar, int protocol,
3535
- unsigned long port, sigar_pid_t *pid)
3536
- {
3537
- sigar_proc_list_t pids;
3538
- int i, status, found=0;
3539
-
3540
- if (!sigar->libproc) {
3541
- return SIGAR_ENOTIMPL;
3542
- }
3543
-
3544
- status = sigar_proc_list_get(sigar, &pids);
3545
- if (status != SIGAR_OK) {
3546
- return status;
3547
- }
3548
-
3549
- for (i=0; i<pids.number; i++) {
3550
- int n, num=0;
3551
- struct proc_fdinfo *fdinfo;
3552
-
3553
- status = proc_fdinfo_get(sigar, pids.data[i], &num);
3554
- if (status != SIGAR_OK) {
3555
- continue;
3556
- }
3557
- fdinfo = (struct proc_fdinfo *)sigar->ifconf_buf;
3558
-
3559
- for (n=0; n<num; n++) {
3560
- struct proc_fdinfo *fdp = &fdinfo[n];
3561
- struct socket_fdinfo si;
3562
- int rsize, family;
3563
- unsigned long lport;
3564
-
3565
- if (fdp->proc_fdtype != PROX_FDTYPE_SOCKET) {
3566
- continue;
3567
- }
3568
- rsize = sigar->proc_pidfdinfo(pids.data[i], fdp->proc_fd,
3569
- PROC_PIDFDSOCKETINFO, &si, sizeof(si));
3570
- if (rsize != sizeof(si)) {
3571
- continue;
3572
- }
3573
- if (si.psi.soi_kind != SOCKINFO_TCP) {
3574
- continue;
3575
- }
3576
- if (si.psi.soi_proto.pri_tcp.tcpsi_state != TSI_S_LISTEN) {
3577
- continue;
3578
- }
3579
- family = si.psi.soi_family;
3580
- if (!((family == AF_INET) || (family == AF_INET6))) {
3581
- continue;
3582
- }
3583
- lport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport);
3584
- if (lport == port) {
3585
- *pid = pids.data[i];
3586
- found = 1;
3587
- break;
3588
- }
3589
- }
3590
- }
3591
-
3592
- sigar_proc_list_destroy(sigar, &pids);
3593
-
3594
- return found ? SIGAR_OK : ENOENT;
3595
- }
3596
-
3597
- #else
3598
-
3599
- int sigar_proc_port_get(sigar_t *sigar, int protocol,
3600
- unsigned long port, sigar_pid_t *pid)
3601
- {
3602
- return SIGAR_ENOTIMPL;
3603
- }
3604
-
3605
- #endif
3606
-
3607
- int sigar_os_sys_info_get(sigar_t *sigar,
3608
- sigar_sys_info_t *sysinfo)
3609
- {
3610
- #ifdef DARWIN
3611
- char *codename = NULL;
3612
- SInt32 version, version_major, version_minor, version_fix;
3613
-
3614
- SIGAR_SSTRCPY(sysinfo->name, "MacOSX");
3615
- SIGAR_SSTRCPY(sysinfo->vendor_name, "Mac OS X");
3616
- SIGAR_SSTRCPY(sysinfo->vendor, "Apple");
3617
-
3618
- if (Gestalt(gestaltSystemVersion, &version) == noErr) {
3619
- if (version >= 0x00001040) {
3620
- Gestalt('sys1' /*gestaltSystemVersionMajor*/, &version_major);
3621
- Gestalt('sys2' /*gestaltSystemVersionMinor*/, &version_minor);
3622
- Gestalt('sys3' /*gestaltSystemVersionBugFix*/, &version_fix);
3623
- }
3624
- else {
3625
- version_fix = version & 0xf;
3626
- version >>= 4;
3627
- version_minor = version & 0xf;
3628
- version >>= 4;
3629
- version_major = version - (version >> 4) * 6;
3630
- }
3631
- }
3632
- else {
3633
- return SIGAR_ENOTIMPL;
3634
- }
3635
-
3636
- snprintf(sysinfo->vendor_version,
3637
- sizeof(sysinfo->vendor_version),
3638
- "%d.%d",
3639
- (int)version_major, (int)version_minor);
3640
-
3641
- snprintf(sysinfo->version,
3642
- sizeof(sysinfo->version),
3643
- "%s.%d",
3644
- sysinfo->vendor_version, (int)version_fix);
3645
-
3646
- if (version_major == 10) {
3647
- switch (version_minor) {
3648
- case 2:
3649
- codename = "Jaguar";
3650
- break;
3651
- case 3:
3652
- codename = "Panther";
3653
- break;
3654
- case 4:
3655
- codename = "Tiger";
3656
- break;
3657
- case 5:
3658
- codename = "Leopard";
3659
- break;
3660
- case 6:
3661
- codename = "Snow Leopard";
3662
- break;
3663
- case 7:
3664
- codename = "Lion";
3665
- break;
3666
- default:
3667
- codename = "Unknown";
3668
- break;
3669
- }
3670
- }
3671
- else {
3672
- return SIGAR_ENOTIMPL;
3673
- }
3674
-
3675
- SIGAR_SSTRCPY(sysinfo->vendor_code_name, codename);
3676
-
3677
- snprintf(sysinfo->description,
3678
- sizeof(sysinfo->description),
3679
- "%s %s",
3680
- sysinfo->vendor_name, sysinfo->vendor_code_name);
3681
- #else
3682
- char *ptr;
3683
-
3684
- #if defined(__FreeBSD__)
3685
- SIGAR_SSTRCPY(sysinfo->name, "FreeBSD");
3686
- #elif defined(__OpenBSD__)
3687
- SIGAR_SSTRCPY(sysinfo->name, "OpenBSD");
3688
- #elif defined(__NetBSD__)
3689
- SIGAR_SSTRCPY(sysinfo->name, "NetBSD");
3690
- #else
3691
- SIGAR_SSTRCPY(sysinfo->name, "Unknown");
3692
- #endif
3693
- SIGAR_SSTRCPY(sysinfo->vendor_name, sysinfo->name);
3694
- SIGAR_SSTRCPY(sysinfo->vendor, sysinfo->name);
3695
- SIGAR_SSTRCPY(sysinfo->vendor_version,
3696
- sysinfo->version);
3697
-
3698
- if ((ptr = strstr(sysinfo->vendor_version, "-"))) {
3699
- /* STABLE, RELEASE, CURRENT */
3700
- *ptr++ = '\0';
3701
- SIGAR_SSTRCPY(sysinfo->vendor_code_name, ptr);
3702
- }
3703
-
3704
- snprintf(sysinfo->description,
3705
- sizeof(sysinfo->description),
3706
- "%s %s",
3707
- sysinfo->name, sysinfo->version);
3708
- #endif
3709
-
3710
- return SIGAR_OK;
3711
- }