sigar 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Binary file
@@ -1,216 +0,0 @@
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
-
Binary file
@@ -1,1060 +0,0 @@
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