sigar 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +2 -0
- data/Rakefile +105 -0
- data/bindings/SigarBuild.pm +310 -0
- data/bindings/SigarWrapper.pm +2978 -0
- data/bindings/ruby/examples/arp.rb +24 -0
- data/bindings/ruby/examples/cpu_info.rb +35 -0
- data/bindings/ruby/examples/df.rb +49 -0
- data/bindings/ruby/examples/free.rb +36 -0
- data/bindings/ruby/examples/ifconfig.rb +101 -0
- data/bindings/ruby/examples/logging.rb +58 -0
- data/bindings/ruby/examples/net_info.rb +31 -0
- data/bindings/ruby/examples/netstat.rb +71 -0
- data/bindings/ruby/examples/pargs.rb +35 -0
- data/bindings/ruby/examples/penv.rb +31 -0
- data/bindings/ruby/examples/route.rb +48 -0
- data/bindings/ruby/examples/version.rb +40 -0
- data/bindings/ruby/examples/who.rb +30 -0
- data/bindings/ruby/extconf.rb +128 -0
- data/bindings/ruby/rbsigar.c +888 -0
- data/bindings/ruby/test/cpu_test.rb +40 -0
- data/bindings/ruby/test/file_system_test.rb +43 -0
- data/bindings/ruby/test/helper.rb +57 -0
- data/bindings/ruby/test/loadavg_test.rb +30 -0
- data/bindings/ruby/test/mem_test.rb +45 -0
- data/bindings/ruby/test/swap_test.rb +36 -0
- data/bindings/ruby/test/uptime_test.rb +26 -0
- data/include/sigar.h +939 -0
- data/include/sigar_fileinfo.h +157 -0
- data/include/sigar_format.h +65 -0
- data/include/sigar_getline.h +18 -0
- data/include/sigar_log.h +80 -0
- data/include/sigar_private.h +422 -0
- data/include/sigar_ptql.h +53 -0
- data/include/sigar_util.h +191 -0
- data/src/os/aix/aix_sigar.c +2151 -0
- data/src/os/aix/sigar_os.h +73 -0
- data/src/os/darwin/Info.plist.in +27 -0
- data/src/os/darwin/darwin_sigar.c +3709 -0
- data/src/os/darwin/sigar_os.h +80 -0
- data/src/os/hpux/hpux_sigar.c +1342 -0
- data/src/os/hpux/sigar_os.h +49 -0
- data/src/os/linux/linux_sigar.c +2782 -0
- data/src/os/linux/sigar_os.h +82 -0
- data/src/os/solaris/get_mib2.c +321 -0
- data/src/os/solaris/get_mib2.h +127 -0
- data/src/os/solaris/kstats.c +181 -0
- data/src/os/solaris/procfs.c +97 -0
- data/src/os/solaris/sigar_os.h +224 -0
- data/src/os/solaris/solaris_sigar.c +2717 -0
- data/src/os/win32/peb.c +212 -0
- data/src/os/win32/sigar.rc.in +40 -0
- data/src/os/win32/sigar_os.h +653 -0
- data/src/os/win32/sigar_pdh.h +47 -0
- data/src/os/win32/win32_sigar.c +3911 -0
- data/src/sigar.c +2428 -0
- data/src/sigar_cache.c +179 -0
- data/src/sigar_fileinfo.c +815 -0
- data/src/sigar_format.c +696 -0
- data/src/sigar_getline.c +1849 -0
- data/src/sigar_ptql.c +1967 -0
- data/src/sigar_signal.c +216 -0
- data/src/sigar_util.c +1060 -0
- data/src/sigar_version.c.in +22 -0
- data/src/sigar_version_autoconf.c.in +22 -0
- data/version.properties +11 -0
- metadata +131 -0
data/src/sigar_signal.c
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2007 Hyperic, Inc.
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#include "sigar.h"
|
18
|
+
#include "sigar_private.h"
|
19
|
+
#include "sigar_util.h"
|
20
|
+
|
21
|
+
#ifdef WIN32
|
22
|
+
#include <windows.h>
|
23
|
+
#endif
|
24
|
+
|
25
|
+
#include <signal.h>
|
26
|
+
#include <errno.h>
|
27
|
+
|
28
|
+
SIGAR_DECLARE(int) sigar_proc_kill(sigar_pid_t pid, int signum)
|
29
|
+
{
|
30
|
+
#ifdef WIN32
|
31
|
+
int status = -1;
|
32
|
+
HANDLE proc =
|
33
|
+
OpenProcess(PROCESS_ALL_ACCESS,
|
34
|
+
TRUE, (DWORD)pid);
|
35
|
+
|
36
|
+
if (proc) {
|
37
|
+
switch (signum) {
|
38
|
+
case 0:
|
39
|
+
status = SIGAR_OK;
|
40
|
+
break;
|
41
|
+
default:
|
42
|
+
if (TerminateProcess(proc, signum)) {
|
43
|
+
status = SIGAR_OK;
|
44
|
+
}
|
45
|
+
break;
|
46
|
+
}
|
47
|
+
|
48
|
+
CloseHandle(proc);
|
49
|
+
|
50
|
+
if (status == SIGAR_OK) {
|
51
|
+
return SIGAR_OK;
|
52
|
+
}
|
53
|
+
}
|
54
|
+
return GetLastError();
|
55
|
+
#else
|
56
|
+
if (kill(pid, signum) == -1) {
|
57
|
+
return errno;
|
58
|
+
}
|
59
|
+
return SIGAR_OK;
|
60
|
+
#endif
|
61
|
+
}
|
62
|
+
|
63
|
+
SIGAR_DECLARE(int) sigar_signum_get(char *name)
|
64
|
+
{
|
65
|
+
if (strnEQ(name, "SIG", 3)) {
|
66
|
+
name += 3;
|
67
|
+
}
|
68
|
+
|
69
|
+
switch (*name) {
|
70
|
+
case 'A':
|
71
|
+
#ifdef SIGABRT
|
72
|
+
if (strEQ(name, "ABRT")) return SIGABRT;
|
73
|
+
#endif
|
74
|
+
#ifdef SIGALRM
|
75
|
+
if (strEQ(name, "ALRM")) return SIGALRM;
|
76
|
+
#endif
|
77
|
+
break;
|
78
|
+
case 'B':
|
79
|
+
#ifdef SIGBUS
|
80
|
+
if (strEQ(name, "BUS")) return SIGBUS;
|
81
|
+
#endif
|
82
|
+
break;
|
83
|
+
case 'C':
|
84
|
+
#ifdef SIGCONT
|
85
|
+
if (strEQ(name, "CONT")) return SIGCONT;
|
86
|
+
#endif
|
87
|
+
#ifdef SIGCHLD
|
88
|
+
if (strEQ(name, "CHLD")) return SIGCHLD;
|
89
|
+
#endif
|
90
|
+
#ifdef SIGCLD
|
91
|
+
if (strEQ(name, "CLD")) return SIGCLD;
|
92
|
+
#endif
|
93
|
+
break;
|
94
|
+
case 'E':
|
95
|
+
#ifdef SIGEMT
|
96
|
+
if (strEQ(name, "EMT")) return SIGEMT;
|
97
|
+
#endif
|
98
|
+
break;
|
99
|
+
case 'F':
|
100
|
+
#ifdef SIGFPE
|
101
|
+
if (strEQ(name, "FPE")) return SIGFPE;
|
102
|
+
#endif
|
103
|
+
break;
|
104
|
+
case 'H':
|
105
|
+
#ifdef SIGHUP
|
106
|
+
if (strEQ(name, "HUP")) return SIGHUP;
|
107
|
+
#endif
|
108
|
+
break;
|
109
|
+
case 'I':
|
110
|
+
#ifdef SIGINT
|
111
|
+
if (strEQ(name, "INT")) return SIGINT;
|
112
|
+
#endif
|
113
|
+
#ifdef SIGILL
|
114
|
+
if (strEQ(name, "ILL")) return SIGILL;
|
115
|
+
#endif
|
116
|
+
#ifdef SIGIOT
|
117
|
+
if (strEQ(name, "IOT")) return SIGIOT;
|
118
|
+
#endif
|
119
|
+
#ifdef SIGIO
|
120
|
+
if (strEQ(name, "IO")) return SIGIO;
|
121
|
+
#endif
|
122
|
+
#ifdef SIGINFO
|
123
|
+
if (strEQ(name, "INFO")) return SIGINFO;
|
124
|
+
#endif
|
125
|
+
break;
|
126
|
+
case 'K':
|
127
|
+
#ifdef SIGKILL
|
128
|
+
if (strEQ(name, "KILL")) return SIGKILL;
|
129
|
+
#endif
|
130
|
+
break;
|
131
|
+
case 'P':
|
132
|
+
#ifdef SIGPOLL
|
133
|
+
if (strEQ(name, "POLL")) return SIGPOLL;
|
134
|
+
#endif
|
135
|
+
#ifdef SIGPIPE
|
136
|
+
if (strEQ(name, "PIPE")) return SIGPIPE;
|
137
|
+
#endif
|
138
|
+
#ifdef SIGPROF
|
139
|
+
if (strEQ(name, "PROF")) return SIGPROF;
|
140
|
+
#endif
|
141
|
+
#ifdef SIGPWR
|
142
|
+
if (strEQ(name, "PWR")) return SIGPWR;
|
143
|
+
#endif
|
144
|
+
break;
|
145
|
+
case 'Q':
|
146
|
+
#ifdef SIGQUIT
|
147
|
+
if (strEQ(name, "QUIT")) return SIGQUIT;
|
148
|
+
#endif
|
149
|
+
break;
|
150
|
+
case 'S':
|
151
|
+
#ifdef SIGSEGV
|
152
|
+
if (strEQ(name, "SEGV")) return SIGSEGV;
|
153
|
+
#endif
|
154
|
+
#ifdef SIGSYS
|
155
|
+
if (strEQ(name, "SYS")) return SIGSYS;
|
156
|
+
#endif
|
157
|
+
#ifdef SIGSTOP
|
158
|
+
if (strEQ(name, "STOP")) return SIGSTOP;
|
159
|
+
#endif
|
160
|
+
#ifdef SIGSTKFLT
|
161
|
+
if (strEQ(name, "STKFLT")) return SIGSTKFLT;
|
162
|
+
#endif
|
163
|
+
break;
|
164
|
+
case 'T':
|
165
|
+
#ifdef SIGTRAP
|
166
|
+
if (strEQ(name, "TRAP")) return SIGTRAP;
|
167
|
+
#endif
|
168
|
+
#ifdef SIGTERM
|
169
|
+
if (strEQ(name, "TERM")) return SIGTERM;
|
170
|
+
#endif
|
171
|
+
#ifdef SIGTSTP
|
172
|
+
if (strEQ(name, "TSTP")) return SIGTSTP;
|
173
|
+
#endif
|
174
|
+
#ifdef SIGTTIN
|
175
|
+
if (strEQ(name, "TTIN")) return SIGTTIN;
|
176
|
+
#endif
|
177
|
+
#ifdef SIGTTOU
|
178
|
+
if (strEQ(name, "TTOU")) return SIGTTOU;
|
179
|
+
#endif
|
180
|
+
break;
|
181
|
+
case 'U':
|
182
|
+
#ifdef SIGURG
|
183
|
+
if (strEQ(name, "URG")) return SIGURG;
|
184
|
+
#endif
|
185
|
+
#ifdef SIGUSR1
|
186
|
+
if (strEQ(name, "USR1")) return SIGUSR1;
|
187
|
+
#endif
|
188
|
+
#ifdef SIGUSR2
|
189
|
+
if (strEQ(name, "USR2")) return SIGUSR2;
|
190
|
+
#endif
|
191
|
+
break;
|
192
|
+
case 'V':
|
193
|
+
#ifdef SIGVTALRM
|
194
|
+
if (strEQ(name, "VTALRM")) return SIGVTALRM;
|
195
|
+
#endif
|
196
|
+
break;
|
197
|
+
case 'W':
|
198
|
+
#ifdef SIGWINCH
|
199
|
+
if (strEQ(name, "WINCH")) return SIGWINCH;
|
200
|
+
#endif
|
201
|
+
break;
|
202
|
+
case 'X':
|
203
|
+
#ifdef SIGXCPU
|
204
|
+
if (strEQ(name, "XCPU")) return SIGXCPU;
|
205
|
+
#endif
|
206
|
+
#ifdef SIGXFSZ
|
207
|
+
if (strEQ(name, "XFSZ")) return SIGXFSZ;
|
208
|
+
#endif
|
209
|
+
break;
|
210
|
+
default:
|
211
|
+
break;
|
212
|
+
}
|
213
|
+
|
214
|
+
return -1;
|
215
|
+
}
|
216
|
+
|
data/src/sigar_util.c
ADDED
@@ -0,0 +1,1060 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (c) 2004-2009 Hyperic, Inc.
|
3
|
+
* Copyright (c) 2009 SpringSource, Inc.
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
|
18
|
+
#include <stdio.h>
|
19
|
+
#include <stdlib.h>
|
20
|
+
#include <errno.h>
|
21
|
+
#include <fcntl.h>
|
22
|
+
#include <assert.h>
|
23
|
+
|
24
|
+
#include "sigar.h"
|
25
|
+
#include "sigar_private.h"
|
26
|
+
#include "sigar_util.h"
|
27
|
+
#include "sigar_os.h"
|
28
|
+
|
29
|
+
#ifndef WIN32
|
30
|
+
|
31
|
+
#include <dirent.h>
|
32
|
+
#include <sys/stat.h>
|
33
|
+
|
34
|
+
SIGAR_INLINE char *sigar_uitoa(char *buf, unsigned int n, int *len)
|
35
|
+
{
|
36
|
+
char *start = buf + UITOA_BUFFER_SIZE - 1;
|
37
|
+
|
38
|
+
*start = 0;
|
39
|
+
|
40
|
+
do {
|
41
|
+
*--start = '0' + (n % 10);
|
42
|
+
++*len;
|
43
|
+
n /= 10;
|
44
|
+
} while (n);
|
45
|
+
|
46
|
+
return start;
|
47
|
+
}
|
48
|
+
|
49
|
+
SIGAR_INLINE char *sigar_skip_line(char *buffer, int buflen)
|
50
|
+
{
|
51
|
+
char *ptr = buflen ?
|
52
|
+
(char *)memchr(buffer, '\n', buflen) : /* bleh */
|
53
|
+
strchr(buffer, '\n');
|
54
|
+
return ++ptr;
|
55
|
+
}
|
56
|
+
|
57
|
+
SIGAR_INLINE char *sigar_skip_token(char *p)
|
58
|
+
{
|
59
|
+
while (sigar_isspace(*p)) p++;
|
60
|
+
while (*p && !sigar_isspace(*p)) p++;
|
61
|
+
return p;
|
62
|
+
}
|
63
|
+
|
64
|
+
SIGAR_INLINE char *sigar_skip_multiple_token(char *p, int count)
|
65
|
+
{
|
66
|
+
int i;
|
67
|
+
|
68
|
+
for (i = 0; i < count; i++) {
|
69
|
+
p = sigar_skip_token(p);
|
70
|
+
}
|
71
|
+
|
72
|
+
return p;
|
73
|
+
}
|
74
|
+
|
75
|
+
char *sigar_getword(char **line, char stop)
|
76
|
+
{
|
77
|
+
char *pos = *line;
|
78
|
+
int len;
|
79
|
+
char *res;
|
80
|
+
|
81
|
+
while ((*pos != stop) && *pos) {
|
82
|
+
++pos;
|
83
|
+
}
|
84
|
+
|
85
|
+
len = pos - *line;
|
86
|
+
res = malloc(len + 1);
|
87
|
+
memcpy(res, *line, len);
|
88
|
+
res[len] = 0;
|
89
|
+
|
90
|
+
if (stop) {
|
91
|
+
while (*pos == stop) {
|
92
|
+
++pos;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
*line = pos;
|
97
|
+
|
98
|
+
return res;
|
99
|
+
}
|
100
|
+
|
101
|
+
/* avoiding sprintf */
|
102
|
+
|
103
|
+
char *sigar_proc_filename(char *buffer, int buflen,
|
104
|
+
sigar_pid_t bigpid,
|
105
|
+
const char *fname, int fname_len)
|
106
|
+
{
|
107
|
+
int len = 0;
|
108
|
+
char *ptr = buffer;
|
109
|
+
unsigned int pid = (unsigned int)bigpid; /* XXX -- This isn't correct */
|
110
|
+
char pid_buf[UITOA_BUFFER_SIZE];
|
111
|
+
char *pid_str = sigar_uitoa(pid_buf, pid, &len);
|
112
|
+
|
113
|
+
assert((unsigned int)buflen >=
|
114
|
+
(SSTRLEN(PROCP_FS_ROOT) + UITOA_BUFFER_SIZE + fname_len + 1));
|
115
|
+
|
116
|
+
memcpy(ptr, PROCP_FS_ROOT, SSTRLEN(PROCP_FS_ROOT));
|
117
|
+
ptr += SSTRLEN(PROCP_FS_ROOT);
|
118
|
+
|
119
|
+
memcpy(ptr, pid_str, len);
|
120
|
+
ptr += len;
|
121
|
+
|
122
|
+
memcpy(ptr, fname, fname_len);
|
123
|
+
ptr += fname_len;
|
124
|
+
*ptr = '\0';
|
125
|
+
|
126
|
+
return buffer;
|
127
|
+
}
|
128
|
+
|
129
|
+
int sigar_proc_file2str(char *buffer, int buflen,
|
130
|
+
sigar_pid_t pid,
|
131
|
+
const char *fname,
|
132
|
+
int fname_len)
|
133
|
+
{
|
134
|
+
int retval;
|
135
|
+
|
136
|
+
buffer = sigar_proc_filename(buffer, buflen, pid,
|
137
|
+
fname, fname_len);
|
138
|
+
|
139
|
+
retval = sigar_file2str(buffer, buffer, buflen);
|
140
|
+
|
141
|
+
if (retval != SIGAR_OK) {
|
142
|
+
switch (retval) {
|
143
|
+
case ENOENT:
|
144
|
+
retval = ESRCH; /* no such process */
|
145
|
+
default:
|
146
|
+
break;
|
147
|
+
}
|
148
|
+
}
|
149
|
+
|
150
|
+
return retval;
|
151
|
+
}
|
152
|
+
|
153
|
+
int sigar_proc_list_procfs_get(sigar_t *sigar,
|
154
|
+
sigar_proc_list_t *proclist)
|
155
|
+
{
|
156
|
+
DIR *dirp = opendir("/proc");
|
157
|
+
struct dirent *ent;
|
158
|
+
#ifdef HAVE_READDIR_R
|
159
|
+
struct dirent dbuf;
|
160
|
+
#endif
|
161
|
+
|
162
|
+
if (!dirp) {
|
163
|
+
return errno;
|
164
|
+
}
|
165
|
+
|
166
|
+
#ifdef HAVE_READDIR_R
|
167
|
+
while (readdir_r(dirp, &dbuf, &ent) == 0) {
|
168
|
+
if (ent == NULL) {
|
169
|
+
break;
|
170
|
+
}
|
171
|
+
#else
|
172
|
+
while ((ent = readdir(dirp))) {
|
173
|
+
#endif
|
174
|
+
if (!sigar_isdigit(*ent->d_name)) {
|
175
|
+
continue;
|
176
|
+
}
|
177
|
+
|
178
|
+
/* XXX: more sanity checking */
|
179
|
+
|
180
|
+
SIGAR_PROC_LIST_GROW(proclist);
|
181
|
+
|
182
|
+
proclist->data[proclist->number++] =
|
183
|
+
strtoul(ent->d_name, NULL, 10);
|
184
|
+
}
|
185
|
+
|
186
|
+
closedir(dirp);
|
187
|
+
|
188
|
+
return SIGAR_OK;
|
189
|
+
}
|
190
|
+
|
191
|
+
int sigar_proc_fd_count(sigar_t *sigar, sigar_pid_t pid,
|
192
|
+
sigar_uint64_t *total)
|
193
|
+
{
|
194
|
+
DIR *dirp;
|
195
|
+
struct dirent *ent;
|
196
|
+
#ifdef HAVE_READDIR_R
|
197
|
+
struct dirent dbuf;
|
198
|
+
#endif
|
199
|
+
char name[BUFSIZ];
|
200
|
+
|
201
|
+
(void)SIGAR_PROC_FILENAME(name, pid, "/fd");
|
202
|
+
|
203
|
+
*total = 0;
|
204
|
+
|
205
|
+
if (!(dirp = opendir(name))) {
|
206
|
+
return errno;
|
207
|
+
}
|
208
|
+
|
209
|
+
#ifdef HAVE_READDIR_R
|
210
|
+
while (readdir_r(dirp, &dbuf, &ent) == 0) {
|
211
|
+
if (ent == NULL) {
|
212
|
+
break;
|
213
|
+
}
|
214
|
+
#else
|
215
|
+
while ((ent = readdir(dirp))) {
|
216
|
+
#endif
|
217
|
+
if (!sigar_isdigit(*ent->d_name)) {
|
218
|
+
continue;
|
219
|
+
}
|
220
|
+
|
221
|
+
(*total)++;
|
222
|
+
}
|
223
|
+
|
224
|
+
closedir(dirp);
|
225
|
+
|
226
|
+
return SIGAR_OK;
|
227
|
+
}
|
228
|
+
|
229
|
+
int sigar_procfs_args_get(sigar_t *sigar, sigar_pid_t pid,
|
230
|
+
sigar_proc_args_t *procargs)
|
231
|
+
{
|
232
|
+
char buffer[9086], *buf=NULL, *ptr;
|
233
|
+
int fd, len, total=0;
|
234
|
+
|
235
|
+
(void)SIGAR_PROC_FILENAME(buffer, pid, "/cmdline");
|
236
|
+
|
237
|
+
if ((fd = open(buffer, O_RDONLY)) < 0) {
|
238
|
+
if (errno == ENOENT) {
|
239
|
+
return ESRCH;
|
240
|
+
}
|
241
|
+
return errno;
|
242
|
+
}
|
243
|
+
|
244
|
+
buffer[0] = '\0';
|
245
|
+
|
246
|
+
/* XXX: possible to get rid of some mallocs here.
|
247
|
+
* but, unlikely this will be called often so it
|
248
|
+
* might not even matter much.
|
249
|
+
*/
|
250
|
+
while ((len = read(fd, buffer, sizeof(buffer)-1)) > 0) {
|
251
|
+
if (len == 0) {
|
252
|
+
break;
|
253
|
+
}
|
254
|
+
buf = realloc(buf, total+len+1);
|
255
|
+
memcpy(buf+total, buffer, len);
|
256
|
+
total += len;
|
257
|
+
}
|
258
|
+
|
259
|
+
close(fd);
|
260
|
+
|
261
|
+
/* e.g. /proc/2/cmdline */
|
262
|
+
if (total == 0) {
|
263
|
+
procargs->number = 0;
|
264
|
+
return SIGAR_OK;
|
265
|
+
}
|
266
|
+
|
267
|
+
buf[total] = '\0';
|
268
|
+
ptr = buf;
|
269
|
+
|
270
|
+
while (total > 0) {
|
271
|
+
int alen = strlen(ptr)+1;
|
272
|
+
char *arg = malloc(alen);
|
273
|
+
|
274
|
+
SIGAR_PROC_ARGS_GROW(procargs);
|
275
|
+
memcpy(arg, ptr, alen);
|
276
|
+
|
277
|
+
procargs->data[procargs->number++] = arg;
|
278
|
+
|
279
|
+
total -= alen;
|
280
|
+
if (total > 0) {
|
281
|
+
ptr += alen;
|
282
|
+
}
|
283
|
+
}
|
284
|
+
|
285
|
+
free(buf);
|
286
|
+
|
287
|
+
return SIGAR_OK;
|
288
|
+
}
|
289
|
+
|
290
|
+
#endif /* WIN32 */
|
291
|
+
|
292
|
+
/* from httpd/server/util.c */
|
293
|
+
char *sigar_strcasestr(const char *s1, const char *s2)
|
294
|
+
{
|
295
|
+
char *p1, *p2;
|
296
|
+
if (*s2 == '\0') {
|
297
|
+
/* an empty s2 */
|
298
|
+
return((char *)s1);
|
299
|
+
}
|
300
|
+
while(1) {
|
301
|
+
for ( ; (*s1 != '\0') && (sigar_tolower(*s1) != sigar_tolower(*s2)); s1++);
|
302
|
+
if (*s1 == '\0') {
|
303
|
+
return(NULL);
|
304
|
+
}
|
305
|
+
/* found first character of s2, see if the rest matches */
|
306
|
+
p1 = (char *)s1;
|
307
|
+
p2 = (char *)s2;
|
308
|
+
for (++p1, ++p2; sigar_tolower(*p1) == sigar_tolower(*p2); ++p1, ++p2) {
|
309
|
+
if (*p1 == '\0') {
|
310
|
+
/* both strings ended together */
|
311
|
+
return((char *)s1);
|
312
|
+
}
|
313
|
+
}
|
314
|
+
if (*p2 == '\0') {
|
315
|
+
/* second string ended, a match */
|
316
|
+
break;
|
317
|
+
}
|
318
|
+
/* didn't find a match here, try starting at next character in s1 */
|
319
|
+
s1++;
|
320
|
+
}
|
321
|
+
return((char *)s1);
|
322
|
+
}
|
323
|
+
|
324
|
+
int sigar_mem_calc_ram(sigar_t *sigar, sigar_mem_t *mem)
|
325
|
+
{
|
326
|
+
sigar_int64_t total = mem->total / 1024, diff;
|
327
|
+
sigar_uint64_t lram = (mem->total / (1024 * 1024));
|
328
|
+
int ram = (int)lram; /* must cast after division */
|
329
|
+
int remainder = ram % 8;
|
330
|
+
|
331
|
+
if (remainder > 0) {
|
332
|
+
ram += (8 - remainder);
|
333
|
+
}
|
334
|
+
|
335
|
+
mem->ram = ram;
|
336
|
+
|
337
|
+
diff = total - (mem->actual_free / 1024);
|
338
|
+
mem->used_percent =
|
339
|
+
(double)(diff * 100) / total;
|
340
|
+
|
341
|
+
diff = total - (mem->actual_used / 1024);
|
342
|
+
mem->free_percent =
|
343
|
+
(double)(diff * 100) / total;
|
344
|
+
|
345
|
+
return ram;
|
346
|
+
}
|
347
|
+
|
348
|
+
#ifndef WIN32
|
349
|
+
|
350
|
+
sigar_iodev_t *sigar_iodev_get(sigar_t *sigar,
|
351
|
+
const char *dirname)
|
352
|
+
{
|
353
|
+
sigar_cache_entry_t *entry;
|
354
|
+
struct stat sb;
|
355
|
+
sigar_uint64_t id;
|
356
|
+
sigar_file_system_list_t fslist;
|
357
|
+
int i, status, is_dev=0;
|
358
|
+
int debug = SIGAR_LOG_IS_DEBUG(sigar);
|
359
|
+
char dev_name[SIGAR_FS_NAME_LEN];
|
360
|
+
|
361
|
+
if (!sigar->fsdev) {
|
362
|
+
sigar->fsdev = sigar_cache_new(15);
|
363
|
+
}
|
364
|
+
|
365
|
+
if (*dirname != '/') {
|
366
|
+
snprintf(dev_name, sizeof(dev_name),
|
367
|
+
SIGAR_DEV_PREFIX "%s", dirname);
|
368
|
+
dirname = dev_name;
|
369
|
+
is_dev = 1;
|
370
|
+
}
|
371
|
+
else if (SIGAR_NAME_IS_DEV(dirname)) {
|
372
|
+
is_dev = 1;
|
373
|
+
}
|
374
|
+
|
375
|
+
if (stat(dirname, &sb) < 0) {
|
376
|
+
if (debug) {
|
377
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
378
|
+
"[iodev] stat(%s) failed",
|
379
|
+
dirname);
|
380
|
+
}
|
381
|
+
return NULL;
|
382
|
+
}
|
383
|
+
|
384
|
+
id = SIGAR_FSDEV_ID(sb);
|
385
|
+
|
386
|
+
entry = sigar_cache_get(sigar->fsdev, id);
|
387
|
+
|
388
|
+
if (entry->value != NULL) {
|
389
|
+
return (sigar_iodev_t *)entry->value;
|
390
|
+
}
|
391
|
+
|
392
|
+
if (is_dev) {
|
393
|
+
sigar_iodev_t *iodev;
|
394
|
+
entry->value = iodev = malloc(sizeof(*iodev));
|
395
|
+
SIGAR_ZERO(iodev);
|
396
|
+
SIGAR_SSTRCPY(iodev->name, dirname);
|
397
|
+
if (debug) {
|
398
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
399
|
+
"[iodev] %s is_dev=true", dirname);
|
400
|
+
}
|
401
|
+
return iodev;
|
402
|
+
}
|
403
|
+
|
404
|
+
status = sigar_file_system_list_get(sigar, &fslist);
|
405
|
+
|
406
|
+
if (status != SIGAR_OK) {
|
407
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
408
|
+
"[iodev] file_system_list failed: %s",
|
409
|
+
sigar_strerror(sigar, status));
|
410
|
+
return NULL;
|
411
|
+
}
|
412
|
+
|
413
|
+
for (i=0; i<fslist.number; i++) {
|
414
|
+
sigar_file_system_t *fsp = &fslist.data[i];
|
415
|
+
|
416
|
+
if (fsp->type == SIGAR_FSTYPE_LOCAL_DISK) {
|
417
|
+
int retval = stat(fsp->dir_name, &sb);
|
418
|
+
sigar_cache_entry_t *ent;
|
419
|
+
|
420
|
+
if (retval < 0) {
|
421
|
+
if (debug) {
|
422
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
423
|
+
"[iodev] inode stat(%s) failed",
|
424
|
+
fsp->dir_name);
|
425
|
+
}
|
426
|
+
continue; /* cant cache w/o inode */
|
427
|
+
}
|
428
|
+
|
429
|
+
ent = sigar_cache_get(sigar->fsdev, SIGAR_FSDEV_ID(sb));
|
430
|
+
if (ent->value) {
|
431
|
+
continue; /* already cached */
|
432
|
+
}
|
433
|
+
|
434
|
+
if (SIGAR_NAME_IS_DEV(fsp->dev_name)) {
|
435
|
+
sigar_iodev_t *iodev;
|
436
|
+
ent->value = iodev = malloc(sizeof(*iodev));
|
437
|
+
SIGAR_ZERO(iodev);
|
438
|
+
iodev->is_partition = 1;
|
439
|
+
SIGAR_SSTRCPY(iodev->name, fsp->dev_name);
|
440
|
+
|
441
|
+
if (debug) {
|
442
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
443
|
+
"[iodev] map %s -> %s",
|
444
|
+
fsp->dir_name, iodev->name);
|
445
|
+
}
|
446
|
+
}
|
447
|
+
}
|
448
|
+
}
|
449
|
+
|
450
|
+
sigar_file_system_list_destroy(sigar, &fslist);
|
451
|
+
|
452
|
+
if (entry->value &&
|
453
|
+
(((sigar_iodev_t *)entry->value)->name[0] != '\0'))
|
454
|
+
{
|
455
|
+
return (sigar_iodev_t *)entry->value;
|
456
|
+
}
|
457
|
+
else {
|
458
|
+
return NULL;
|
459
|
+
}
|
460
|
+
}
|
461
|
+
#endif
|
462
|
+
|
463
|
+
double sigar_file_system_usage_calc_used(sigar_t *sigar,
|
464
|
+
sigar_file_system_usage_t *fsusage)
|
465
|
+
{
|
466
|
+
/*
|
467
|
+
* win32 will not convert __uint64 to double.
|
468
|
+
* convert to KB then do unsigned long -> double.
|
469
|
+
*/
|
470
|
+
sigar_uint64_t b_used = (fsusage->total - fsusage->free) / 1024;
|
471
|
+
sigar_uint64_t b_avail = fsusage->avail / 1024;
|
472
|
+
unsigned long utotal = b_used + b_avail;
|
473
|
+
unsigned long used = b_used;
|
474
|
+
|
475
|
+
if (utotal != 0) {
|
476
|
+
unsigned long u100 = used * 100;
|
477
|
+
double pct = u100 / utotal +
|
478
|
+
((u100 % utotal != 0) ? 1 : 0);
|
479
|
+
return pct / 100;
|
480
|
+
}
|
481
|
+
|
482
|
+
return 0;
|
483
|
+
}
|
484
|
+
|
485
|
+
typedef struct {
|
486
|
+
sigar_uint32_t eax;
|
487
|
+
sigar_uint32_t ebx;
|
488
|
+
sigar_uint32_t ecx;
|
489
|
+
sigar_uint32_t edx;
|
490
|
+
} sigar_cpuid_t;
|
491
|
+
|
492
|
+
#if defined(__GNUC__) && !defined(__sun)
|
493
|
+
|
494
|
+
# if defined(__i386__)
|
495
|
+
# define SIGAR_HAS_CPUID
|
496
|
+
static void sigar_cpuid(sigar_uint32_t request, sigar_cpuid_t *id)
|
497
|
+
{
|
498
|
+
/* derived from: */
|
499
|
+
/* http://svn.red-bean.com/repos/minor/trunk/gc/barriers-ia-32.c */
|
500
|
+
asm volatile ("mov %%ebx, %%esi\n\t"
|
501
|
+
"cpuid\n\t"
|
502
|
+
"xchgl %%ebx, %%esi"
|
503
|
+
: "=a" (id->eax),
|
504
|
+
"=S" (id->ebx),
|
505
|
+
"=c" (id->ecx),
|
506
|
+
"=d" (id->edx)
|
507
|
+
: "0" (request)
|
508
|
+
: "memory");
|
509
|
+
}
|
510
|
+
# elif defined(__amd64__)
|
511
|
+
# define SIGAR_HAS_CPUID
|
512
|
+
static void sigar_cpuid(sigar_uint32_t request,
|
513
|
+
sigar_cpuid_t *id)
|
514
|
+
{
|
515
|
+
/* http://svn.red-bean.com/repos/minor/trunk/gc/barriers-amd64.c */
|
516
|
+
asm volatile ("cpuid\n\t"
|
517
|
+
: "=a" (id->eax),
|
518
|
+
"=b" (id->ebx),
|
519
|
+
"=c" (id->ecx),
|
520
|
+
"=d" (id->edx)
|
521
|
+
: "0" (request)
|
522
|
+
: "memory");
|
523
|
+
}
|
524
|
+
# endif
|
525
|
+
#elif defined(WIN32)
|
526
|
+
# ifdef _M_X64
|
527
|
+
# include <intrin.h>
|
528
|
+
# define SIGAR_HAS_CPUID
|
529
|
+
static void sigar_cpuid(sigar_uint32_t request,
|
530
|
+
sigar_cpuid_t *id)
|
531
|
+
{
|
532
|
+
sigar_uint32_t info[4];
|
533
|
+
__cpuid(info, request); /* as of MSVC 7 */
|
534
|
+
memcpy(id, &info[0], sizeof(info));
|
535
|
+
}
|
536
|
+
# else
|
537
|
+
# define SIGAR_HAS_CPUID
|
538
|
+
static void sigar_cpuid(sigar_uint32_t request,
|
539
|
+
sigar_cpuid_t *id)
|
540
|
+
{
|
541
|
+
__asm {
|
542
|
+
mov edi, id
|
543
|
+
mov eax, [edi].eax
|
544
|
+
mov ecx, [edi].ecx
|
545
|
+
cpuid
|
546
|
+
mov [edi].eax, eax
|
547
|
+
mov [edi].ebx, ebx
|
548
|
+
mov [edi].ecx, ecx
|
549
|
+
mov [edi].edx, edx
|
550
|
+
}
|
551
|
+
}
|
552
|
+
# endif
|
553
|
+
#endif
|
554
|
+
|
555
|
+
#define INTEL_ID 0x756e6547
|
556
|
+
#define AMD_ID 0x68747541
|
557
|
+
|
558
|
+
int sigar_cpu_core_count(sigar_t *sigar)
|
559
|
+
{
|
560
|
+
#if defined(SIGAR_HAS_CPUID)
|
561
|
+
sigar_cpuid_t id;
|
562
|
+
|
563
|
+
if (sigar->lcpu == -1) {
|
564
|
+
sigar->lcpu = 1;
|
565
|
+
|
566
|
+
sigar_cpuid(0, &id);
|
567
|
+
|
568
|
+
if ((id.ebx == INTEL_ID) || (id.ebx == AMD_ID)) {
|
569
|
+
sigar_cpuid(1, &id);
|
570
|
+
|
571
|
+
if (id.edx & (1<<28)) {
|
572
|
+
sigar->lcpu = (id.ebx & 0x00FF0000) >> 16;
|
573
|
+
}
|
574
|
+
}
|
575
|
+
|
576
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
577
|
+
"[cpu] %d cores per socket", sigar->lcpu);
|
578
|
+
}
|
579
|
+
|
580
|
+
return sigar->lcpu;
|
581
|
+
#elif defined(__sun) || defined(__hpux) || defined(_AIX)
|
582
|
+
return 1;
|
583
|
+
#else
|
584
|
+
sigar->lcpu = 1;
|
585
|
+
return sigar->lcpu;
|
586
|
+
#endif
|
587
|
+
}
|
588
|
+
|
589
|
+
int sigar_cpu_core_rollup(sigar_t *sigar)
|
590
|
+
{
|
591
|
+
#ifdef SIGAR_HAS_CPUID
|
592
|
+
int log_rollup =
|
593
|
+
SIGAR_LOG_IS_DEBUG(sigar) &&
|
594
|
+
(sigar->lcpu == -1);
|
595
|
+
|
596
|
+
(void)sigar_cpu_core_count(sigar);
|
597
|
+
|
598
|
+
if (sigar->cpu_list_cores) {
|
599
|
+
if (log_rollup && (sigar->lcpu > 1)) {
|
600
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
601
|
+
"[cpu] treating cores as-is");
|
602
|
+
}
|
603
|
+
}
|
604
|
+
else {
|
605
|
+
if (log_rollup && (sigar->lcpu > 1)) {
|
606
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
607
|
+
"[cpu] rolling up cores to sockets");
|
608
|
+
return 1;
|
609
|
+
}
|
610
|
+
}
|
611
|
+
#endif
|
612
|
+
return 0;
|
613
|
+
}
|
614
|
+
|
615
|
+
#define IS_CPU_R(p) \
|
616
|
+
((*p == '(') && (*(p+1) == 'R') && (*(p+2) == ')'))
|
617
|
+
|
618
|
+
typedef struct {
|
619
|
+
char *name; /* search */
|
620
|
+
int len;
|
621
|
+
char *rname; /* replace */
|
622
|
+
int rlen;
|
623
|
+
} cpu_model_str_t;
|
624
|
+
|
625
|
+
/* to later replace 's' with 'r' */
|
626
|
+
#define CPU_MODEL_ENT_R(s, r) \
|
627
|
+
{ s, sizeof(s)-1, r, sizeof(r) }
|
628
|
+
|
629
|
+
#define CPU_MODEL_ENT(s) \
|
630
|
+
CPU_MODEL_ENT_R(s, s)
|
631
|
+
|
632
|
+
/* after the vendor part of the string is removed,
|
633
|
+
* looking for startsWith the entries below
|
634
|
+
* to remove the crap after the model name, see
|
635
|
+
* ../exp/intel_amd_cpu_models.txt
|
636
|
+
*/
|
637
|
+
static const cpu_model_str_t cpu_models[] = {
|
638
|
+
/* intel */
|
639
|
+
CPU_MODEL_ENT("Xeon"),
|
640
|
+
CPU_MODEL_ENT_R("XEON", "Xeon"),
|
641
|
+
CPU_MODEL_ENT("Pentium III"),
|
642
|
+
CPU_MODEL_ENT("Pentium II"),
|
643
|
+
CPU_MODEL_ENT_R("Pentium(R) III", "Pentium III"),
|
644
|
+
CPU_MODEL_ENT_R("Pentium(R) 4", "Pentium 4"),
|
645
|
+
CPU_MODEL_ENT_R("Pentium(R) M", "Pentium M"),
|
646
|
+
CPU_MODEL_ENT("Pentium Pro"),
|
647
|
+
CPU_MODEL_ENT("Celeron"),
|
648
|
+
|
649
|
+
/* amd */
|
650
|
+
CPU_MODEL_ENT("Opteron"),
|
651
|
+
CPU_MODEL_ENT("Athlon"),
|
652
|
+
CPU_MODEL_ENT("Duron"),
|
653
|
+
CPU_MODEL_ENT_R("K6(tm)-III", "K6 III"),
|
654
|
+
CPU_MODEL_ENT_R("K6(tm) 3D+", "K6 3D+"),
|
655
|
+
{ NULL }
|
656
|
+
};
|
657
|
+
|
658
|
+
/* common to win32 and linux */
|
659
|
+
void sigar_cpu_model_adjust(sigar_t *sigar, sigar_cpu_info_t *info)
|
660
|
+
{
|
661
|
+
int len, i;
|
662
|
+
char model[128], *ptr=model, *end;
|
663
|
+
|
664
|
+
memcpy(model, info->model, sizeof(model));
|
665
|
+
|
666
|
+
/* trim leading and trailing spaces */
|
667
|
+
len = strlen(model);
|
668
|
+
end = &model[len-1];
|
669
|
+
while (*ptr == ' ') ++ptr;
|
670
|
+
while (*end == ' ') *end-- = '\0';
|
671
|
+
|
672
|
+
/* remove vendor from model name */
|
673
|
+
len = strlen(info->vendor);
|
674
|
+
if (strnEQ(ptr, info->vendor, len)) {
|
675
|
+
ptr += len;
|
676
|
+
if (IS_CPU_R(ptr)) {
|
677
|
+
ptr += 3; /* remove (R) */
|
678
|
+
}
|
679
|
+
while (*ptr == ' ') ++ptr;
|
680
|
+
}
|
681
|
+
|
682
|
+
if (*ptr == '-') {
|
683
|
+
++ptr; /* e.g. was AMD-K6... */
|
684
|
+
}
|
685
|
+
|
686
|
+
for (i=0; cpu_models[i].name; i++) {
|
687
|
+
const cpu_model_str_t *cpu_model = &cpu_models[i];
|
688
|
+
|
689
|
+
if (strnEQ(ptr, cpu_model->name, cpu_model->len)) {
|
690
|
+
memcpy(info->model, cpu_model->rname, cpu_model->rlen);
|
691
|
+
return;
|
692
|
+
}
|
693
|
+
}
|
694
|
+
|
695
|
+
strcpy(info->model, ptr);
|
696
|
+
}
|
697
|
+
|
698
|
+
/* attempt to derive MHz from model name
|
699
|
+
* currently works for certain intel strings
|
700
|
+
* see exp/intel_amd_cpu_models.txt
|
701
|
+
*/
|
702
|
+
int sigar_cpu_mhz_from_model(char *model)
|
703
|
+
{
|
704
|
+
int mhz = SIGAR_FIELD_NOTIMPL;
|
705
|
+
char *ptr = model;
|
706
|
+
|
707
|
+
while (*ptr && (ptr = strchr(ptr, ' '))) {
|
708
|
+
while(*ptr && !sigar_isdigit(*ptr)) {
|
709
|
+
ptr++;
|
710
|
+
}
|
711
|
+
mhz = sigar_strtoul(ptr);
|
712
|
+
|
713
|
+
if (*ptr == '.') {
|
714
|
+
/* e.g. "2.40GHz" */
|
715
|
+
++ptr;
|
716
|
+
mhz *= 100;
|
717
|
+
mhz += sigar_strtoul(ptr);
|
718
|
+
break;
|
719
|
+
}
|
720
|
+
else if (strnEQ(ptr, "GHz", 3) ||
|
721
|
+
strnEQ(ptr, "MHz", 3))
|
722
|
+
{
|
723
|
+
/* e.g. "1500MHz" */
|
724
|
+
break;
|
725
|
+
}
|
726
|
+
else {
|
727
|
+
mhz = SIGAR_FIELD_NOTIMPL;
|
728
|
+
}
|
729
|
+
}
|
730
|
+
|
731
|
+
if (mhz != SIGAR_FIELD_NOTIMPL) {
|
732
|
+
if (strnEQ(ptr, "GHz", 3)) {
|
733
|
+
mhz *= 10;
|
734
|
+
}
|
735
|
+
}
|
736
|
+
|
737
|
+
return mhz;
|
738
|
+
}
|
739
|
+
|
740
|
+
#if !defined(WIN32) && !defined(NETWARE)
|
741
|
+
#include <netdb.h>
|
742
|
+
#include <rpc/rpc.h>
|
743
|
+
#include <rpc/pmap_prot.h>
|
744
|
+
#include <rpc/pmap_clnt.h>
|
745
|
+
#ifdef SIGAR_HPUX
|
746
|
+
#include <nfs/nfs.h>
|
747
|
+
#endif
|
748
|
+
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun) || defined(DARWIN)
|
749
|
+
#include <arpa/inet.h>
|
750
|
+
#endif
|
751
|
+
#if defined(__sun) || defined(SIGAR_HPUX)
|
752
|
+
#include <rpc/clnt_soc.h>
|
753
|
+
#endif
|
754
|
+
#if defined(_AIX) || defined(SIGAR_HPUX) || defined(__OpenBSD__) || defined(__NetBSD__)
|
755
|
+
#include <sys/socket.h>
|
756
|
+
#endif
|
757
|
+
|
758
|
+
static enum clnt_stat get_sockaddr(struct sockaddr_in *addr, char *host)
|
759
|
+
{
|
760
|
+
register struct hostent *hp;
|
761
|
+
sigar_hostent_t data;
|
762
|
+
|
763
|
+
memset(addr, 0, sizeof(struct sockaddr_in));
|
764
|
+
addr->sin_family = AF_INET;
|
765
|
+
|
766
|
+
if ((addr->sin_addr.s_addr = inet_addr(host)) == -1) {
|
767
|
+
if (!(hp = sigar_gethostbyname(host, &data))) {
|
768
|
+
return RPC_UNKNOWNHOST;
|
769
|
+
}
|
770
|
+
memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
|
771
|
+
}
|
772
|
+
|
773
|
+
return RPC_SUCCESS;
|
774
|
+
}
|
775
|
+
|
776
|
+
char *sigar_rpc_strerror(int err)
|
777
|
+
{
|
778
|
+
return (char *)clnt_sperrno(err);
|
779
|
+
}
|
780
|
+
|
781
|
+
SIGAR_DECLARE(int) sigar_rpc_ping(char *host,
|
782
|
+
int protocol,
|
783
|
+
unsigned long program,
|
784
|
+
unsigned long version)
|
785
|
+
{
|
786
|
+
CLIENT *client;
|
787
|
+
struct sockaddr_in addr;
|
788
|
+
int sock;
|
789
|
+
struct timeval timeout;
|
790
|
+
unsigned short port = 0;
|
791
|
+
enum clnt_stat rpc_stat;
|
792
|
+
|
793
|
+
rpc_stat = get_sockaddr(&addr, host);
|
794
|
+
if (rpc_stat != RPC_SUCCESS) {
|
795
|
+
return rpc_stat;
|
796
|
+
}
|
797
|
+
|
798
|
+
timeout.tv_sec = 2;
|
799
|
+
timeout.tv_usec = 0;
|
800
|
+
addr.sin_port = htons(port);
|
801
|
+
sock = RPC_ANYSOCK;
|
802
|
+
|
803
|
+
if (protocol == SIGAR_NETCONN_UDP) {
|
804
|
+
client =
|
805
|
+
clntudp_create(&addr, program, version,
|
806
|
+
timeout, &sock);
|
807
|
+
}
|
808
|
+
else if (protocol == SIGAR_NETCONN_TCP) {
|
809
|
+
client =
|
810
|
+
clnttcp_create(&addr, program, version,
|
811
|
+
&sock, 0, 0);
|
812
|
+
}
|
813
|
+
else {
|
814
|
+
return RPC_UNKNOWNPROTO;
|
815
|
+
}
|
816
|
+
|
817
|
+
if (!client) {
|
818
|
+
return rpc_createerr.cf_stat;
|
819
|
+
}
|
820
|
+
|
821
|
+
timeout.tv_sec = 10;
|
822
|
+
timeout.tv_usec = 0;
|
823
|
+
rpc_stat = clnt_call(client, NULLPROC, (xdrproc_t)xdr_void, NULL,
|
824
|
+
(xdrproc_t)xdr_void, NULL, timeout);
|
825
|
+
|
826
|
+
clnt_destroy(client);
|
827
|
+
|
828
|
+
return rpc_stat;
|
829
|
+
}
|
830
|
+
#endif
|
831
|
+
|
832
|
+
int sigar_file2str(const char *fname, char *buffer, int buflen)
|
833
|
+
{
|
834
|
+
int len, status;
|
835
|
+
int fd = open(fname, O_RDONLY);
|
836
|
+
|
837
|
+
if (fd < 0) {
|
838
|
+
return ENOENT;
|
839
|
+
}
|
840
|
+
|
841
|
+
if ((len = read(fd, buffer, buflen)) < 0) {
|
842
|
+
status = errno;
|
843
|
+
}
|
844
|
+
else {
|
845
|
+
status = SIGAR_OK;
|
846
|
+
buffer[len] = '\0';
|
847
|
+
}
|
848
|
+
close(fd);
|
849
|
+
|
850
|
+
return status;
|
851
|
+
}
|
852
|
+
|
853
|
+
#ifdef WIN32
|
854
|
+
#define vsnprintf _vsnprintf
|
855
|
+
#endif
|
856
|
+
|
857
|
+
#ifdef WIN32
|
858
|
+
# define rindex strrchr
|
859
|
+
#endif
|
860
|
+
|
861
|
+
static int proc_module_get_self(void *data, char *name, int len)
|
862
|
+
{
|
863
|
+
sigar_t *sigar = (sigar_t *)data;
|
864
|
+
char *ptr = rindex(name, '/');
|
865
|
+
|
866
|
+
if (!ptr) {
|
867
|
+
return SIGAR_OK;
|
868
|
+
}
|
869
|
+
|
870
|
+
if (strnEQ(ptr+1, "libsigar-", 9)) {
|
871
|
+
int offset = ptr - name;
|
872
|
+
|
873
|
+
sigar->self_path = sigar_strdup(name);
|
874
|
+
*(sigar->self_path + offset) = '\0'; /* chop libsigar-*.so */
|
875
|
+
|
876
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
877
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
878
|
+
"detected sigar-lib='%s'",
|
879
|
+
sigar->self_path);
|
880
|
+
}
|
881
|
+
|
882
|
+
return !SIGAR_OK; /* break loop */
|
883
|
+
}
|
884
|
+
|
885
|
+
return SIGAR_OK;
|
886
|
+
}
|
887
|
+
|
888
|
+
char *sigar_get_self_path(sigar_t *sigar)
|
889
|
+
{
|
890
|
+
if (!sigar->self_path) {
|
891
|
+
sigar_proc_modules_t procmods;
|
892
|
+
char *self_path = getenv("SIGAR_PATH");
|
893
|
+
|
894
|
+
if (self_path) {
|
895
|
+
sigar->self_path = sigar_strdup(self_path);
|
896
|
+
return sigar->self_path;
|
897
|
+
}
|
898
|
+
|
899
|
+
procmods.module_getter = proc_module_get_self;
|
900
|
+
procmods.data = sigar;
|
901
|
+
|
902
|
+
sigar_proc_modules_get(sigar,
|
903
|
+
sigar_pid_get(sigar),
|
904
|
+
&procmods);
|
905
|
+
|
906
|
+
if (!sigar->self_path) {
|
907
|
+
/* dont try again */
|
908
|
+
sigar->self_path = sigar_strdup(".");
|
909
|
+
}
|
910
|
+
}
|
911
|
+
|
912
|
+
return sigar->self_path;
|
913
|
+
}
|
914
|
+
|
915
|
+
#ifdef SIGAR_HAS_DLINFO_MODULES
|
916
|
+
|
917
|
+
static int sigar_dlinfo_get(sigar_t *sigar, const char *func,
|
918
|
+
void **handle, Link_map **map)
|
919
|
+
{
|
920
|
+
Dl_info dli;
|
921
|
+
|
922
|
+
if (!dladdr((void *)((uintptr_t)sigar_dlinfo_get), &dli)) {
|
923
|
+
sigar_log_printf(sigar, SIGAR_LOG_ERROR,
|
924
|
+
"[%s] dladdr(%s) = %s",
|
925
|
+
func, SIGAR_FUNC, dlerror());
|
926
|
+
return ESRCH;
|
927
|
+
}
|
928
|
+
|
929
|
+
if (!(*handle = dlopen(dli.dli_fname, RTLD_LAZY))) {
|
930
|
+
sigar_log_printf(sigar, SIGAR_LOG_ERROR,
|
931
|
+
"[%s] dlopen(%s) = %s",
|
932
|
+
func, dli.dli_fname, dlerror());
|
933
|
+
return ESRCH;
|
934
|
+
}
|
935
|
+
|
936
|
+
dlinfo(*handle, RTLD_DI_LINKMAP, map);
|
937
|
+
|
938
|
+
if (!map) {
|
939
|
+
sigar_log_printf(sigar, SIGAR_LOG_ERROR,
|
940
|
+
"[%s] dlinfo = %s",
|
941
|
+
func, dlerror());
|
942
|
+
return ESRCH;
|
943
|
+
}
|
944
|
+
|
945
|
+
return SIGAR_OK;
|
946
|
+
}
|
947
|
+
|
948
|
+
int sigar_dlinfo_modules(sigar_t *sigar, sigar_proc_modules_t *procmods)
|
949
|
+
{
|
950
|
+
int status;
|
951
|
+
void *handle;
|
952
|
+
Link_map *map;
|
953
|
+
|
954
|
+
status = sigar_dlinfo_get(sigar, SIGAR_FUNC, &handle, &map);
|
955
|
+
if (status != SIGAR_OK) {
|
956
|
+
return status;
|
957
|
+
}
|
958
|
+
|
959
|
+
while (map->l_prev != NULL) {
|
960
|
+
map = map->l_prev;
|
961
|
+
}
|
962
|
+
|
963
|
+
do {
|
964
|
+
int status =
|
965
|
+
procmods->module_getter(procmods->data,
|
966
|
+
(char *)map->l_name,
|
967
|
+
strlen(map->l_name));
|
968
|
+
|
969
|
+
if (status != SIGAR_OK) {
|
970
|
+
/* not an error; just stop iterating */
|
971
|
+
break;
|
972
|
+
}
|
973
|
+
} while ((map = map->l_next));
|
974
|
+
|
975
|
+
dlclose(handle);
|
976
|
+
|
977
|
+
return SIGAR_OK;
|
978
|
+
}
|
979
|
+
#endif
|
980
|
+
|
981
|
+
SIGAR_DECLARE(void) sigar_log_printf(sigar_t *sigar, int level,
|
982
|
+
const char *format, ...)
|
983
|
+
{
|
984
|
+
va_list args;
|
985
|
+
char buffer[8192];
|
986
|
+
|
987
|
+
if (level > sigar->log_level) {
|
988
|
+
return;
|
989
|
+
}
|
990
|
+
|
991
|
+
if (!sigar->log_impl) {
|
992
|
+
return;
|
993
|
+
}
|
994
|
+
|
995
|
+
va_start(args, format);
|
996
|
+
vsnprintf(buffer, sizeof(buffer), format, args);
|
997
|
+
va_end(args);
|
998
|
+
|
999
|
+
sigar->log_impl(sigar, sigar->log_data, level, buffer);
|
1000
|
+
}
|
1001
|
+
|
1002
|
+
SIGAR_DECLARE(void) sigar_log(sigar_t *sigar, int level, char *message)
|
1003
|
+
{
|
1004
|
+
if (level > sigar->log_level) {
|
1005
|
+
return;
|
1006
|
+
}
|
1007
|
+
|
1008
|
+
if (!sigar->log_impl) {
|
1009
|
+
return;
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
sigar->log_impl(sigar, sigar->log_data, level, message);
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
SIGAR_DECLARE(void) sigar_log_impl_set(sigar_t *sigar, void *data,
|
1016
|
+
sigar_log_impl_t impl)
|
1017
|
+
{
|
1018
|
+
sigar->log_data = data;
|
1019
|
+
sigar->log_impl = impl;
|
1020
|
+
}
|
1021
|
+
|
1022
|
+
SIGAR_DECLARE(int) sigar_log_level_get(sigar_t *sigar)
|
1023
|
+
{
|
1024
|
+
return sigar->log_level;
|
1025
|
+
}
|
1026
|
+
|
1027
|
+
static const char *log_levels[] = {
|
1028
|
+
"FATAL",
|
1029
|
+
"ERROR",
|
1030
|
+
"WARN",
|
1031
|
+
"INFO",
|
1032
|
+
"DEBUG",
|
1033
|
+
"TRACE"
|
1034
|
+
};
|
1035
|
+
|
1036
|
+
SIGAR_DECLARE(const char *) sigar_log_level_string_get(sigar_t *sigar)
|
1037
|
+
{
|
1038
|
+
return log_levels[sigar->log_level];
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
SIGAR_DECLARE(void) sigar_log_level_set(sigar_t *sigar, int level)
|
1042
|
+
{
|
1043
|
+
sigar->log_level = level;
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
SIGAR_DECLARE(void) sigar_log_impl_file(sigar_t *sigar, void *data,
|
1047
|
+
int level, char *message)
|
1048
|
+
{
|
1049
|
+
FILE *fp = (FILE*)data;
|
1050
|
+
fprintf(fp, "[%s] %s\n", log_levels[level], message);
|
1051
|
+
}
|
1052
|
+
|
1053
|
+
#ifndef WIN32
|
1054
|
+
sigar_int64_t sigar_time_now_millis(void)
|
1055
|
+
{
|
1056
|
+
struct timeval tv;
|
1057
|
+
gettimeofday(&tv, NULL);
|
1058
|
+
return ((tv.tv_sec * SIGAR_USEC) + tv.tv_usec) / SIGAR_MSEC;
|
1059
|
+
}
|
1060
|
+
#endif
|