ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/statgrab/statgrab.c
(Generate patch)

Comparing projects/libstatgrab/src/statgrab/statgrab.c (file contents):
Revision 1.27 by ats, Fri Jul 16 11:17:16 2004 UTC vs.
Revision 1.38 by tdb, Sun Oct 3 18:35:59 2010 UTC

# Line 33 | Line 33
33  
34   typedef enum {
35          LONG_LONG = 0,
36 +        BYTES,
37          TIME_T,
38          FLOAT,
39          DOUBLE,
# Line 59 | Line 60 | typedef struct {
60          char *name;
61          stat_type type;
62          void *stat;
63 < } stat;
63 > } stat_item;
64 > /* AIX:
65 > statgrab.c:63: error: 'stat' redeclared as different kind of symbol
66 > /usr/include/sys/stat.h:320: error: previous declaration of 'stat' was here
67 > */
68  
69 < stat *stats = NULL;
69 > stat_item *stat_items = NULL;
70   int num_stats = 0;
71   int alloc_stats = 0;
72   #define INCREMENT_STATS 64
# Line 71 | Line 76 | repeat_mode_type repeat_mode = REPEAT_NONE;
76   int repeat_time = 1;
77   int use_cpu_percent = 0;
78   int use_diffs = 0;
79 + long float_scale_factor = 0;
80 + long long bytes_scale_factor = 0;
81  
82   /* Exit with an error message. */
83   void die(const char *s) {
# Line 83 | Line 90 | void clear_stats() {
90          int i;
91  
92          for (i = 0; i < num_stats; i++)
93 <                free(stats[i].name);
93 >                free(stat_items[i].name);
94          num_stats = 0;
95   }
96  
# Line 118 | Line 125 | void add_stat(stat_type type, void *stat, ...) {
125                          break;
126                  partlen = strlen(part);
127                  memcpy(p, part, partlen);
128 <                p += partlen;
128 >
129 >                /* Replace spaces and dots with underscores. */
130 >                while (partlen-- > 0) {
131 >                        if (*p == ' ' || *p == '.')
132 >                                *p = '_';
133 >                        p++;
134 >                }
135 >
136                  *p++ = '.';
137          }
138          va_end(ap);
139          *--p = '\0';
140  
127        /* Replace spaces with underscores. */
128        for (p = name; *p != '\0'; p++) {
129                if (*p == ' ')
130                        *p = '_';
131        }
132
141          /* Stretch the stats array if necessary. */
142          if (num_stats >= alloc_stats) {
143                  alloc_stats += INCREMENT_STATS;
144 <                stats = realloc(stats, alloc_stats * sizeof *stats);
145 <                if (stats == NULL)
144 >                stat_items = realloc(stat_items, alloc_stats * sizeof *stat_items);
145 >                if (stat_items == NULL)
146                          die("out of memory");
147          }
148  
149 <        stats[num_stats].name = name;
150 <        stats[num_stats].type = type;
151 <        stats[num_stats].stat = stat;
149 >        stat_items[num_stats].name = name;
150 >        stat_items[num_stats].type = type;
151 >        stat_items[num_stats].stat = stat;
152          ++num_stats;
153   }
154  
155   /* Compare two stats by name for qsort and bsearch. */
156   int stats_compare(const void *a, const void *b) {
157 <        return strcmp(((stat *)a)->name, ((stat *)b)->name);
157 >        return strcmp(((stat_item *)a)->name, ((stat_item *)b)->name);
158   }
159  
160   /* Compare up to the length of the key for bsearch. */
161   int stats_compare_prefix(const void *key, const void *item) {
162 <        const char *kn = ((stat *)key)->name;
163 <        const char *in = ((stat *)item)->name;
162 >        const char *kn = ((stat_item *)key)->name;
163 >        const char *in = ((stat_item *)item)->name;
164  
165          return strncmp(kn, in, strlen(kn));
166   }
# Line 214 | Line 222 | void populate_mem() {
222          sg_mem_stats *mem = sg_get_mem_stats();
223  
224          if (mem != NULL) {
225 <                add_stat(LONG_LONG, &mem->total, "mem", "total", NULL);
226 <                add_stat(LONG_LONG, &mem->free, "mem", "free", NULL);
227 <                add_stat(LONG_LONG, &mem->used, "mem", "used", NULL);
228 <                add_stat(LONG_LONG, &mem->cache, "mem", "cache", NULL);
225 >                add_stat(BYTES, &mem->total, "mem", "total", NULL);
226 >                add_stat(BYTES, &mem->free, "mem", "free", NULL);
227 >                add_stat(BYTES, &mem->used, "mem", "used", NULL);
228 >                add_stat(BYTES, &mem->cache, "mem", "cache", NULL);
229          }
230   }
231  
# Line 244 | Line 252 | void populate_swap() {
252          sg_swap_stats *swap = sg_get_swap_stats();
253  
254          if (swap != NULL) {
255 <                add_stat(LONG_LONG, &swap->total, "swap", "total", NULL);
256 <                add_stat(LONG_LONG, &swap->used, "swap", "used", NULL);
257 <                add_stat(LONG_LONG, &swap->free, "swap", "free", NULL);
255 >                add_stat(BYTES, &swap->total, "swap", "total", NULL);
256 >                add_stat(BYTES, &swap->used, "swap", "used", NULL);
257 >                add_stat(BYTES, &swap->free, "swap", "free", NULL);
258          }
259   }
260  
# Line 298 | Line 306 | void populate_fs() {
306                                   "fs", name, "fs_type", NULL);
307                          add_stat(STRING, &disk[i].mnt_point,
308                                   "fs", name, "mnt_point", NULL);
309 <                        add_stat(LONG_LONG, &disk[i].size,
309 >                        add_stat(BYTES, &disk[i].size,
310                                   "fs", name, "size", NULL);
311 <                        add_stat(LONG_LONG, &disk[i].used,
311 >                        add_stat(BYTES, &disk[i].used,
312                                   "fs", name, "used", NULL);
313 <                        add_stat(LONG_LONG, &disk[i].avail,
313 >                        add_stat(BYTES, &disk[i].avail,
314                                   "fs", name, "avail", NULL);
315                          add_stat(LONG_LONG, &disk[i].total_inodes,
316                                   "fs", name, "total_inodes", NULL);
# Line 310 | Line 318 | void populate_fs() {
318                                   "fs", name, "used_inodes", NULL);
319                          add_stat(LONG_LONG, &disk[i].free_inodes,
320                                   "fs", name, "free_inodes", NULL);
321 +                        add_stat(LONG_LONG, &disk[i].avail_inodes,
322 +                                 "fs", name, "avail_inodes", NULL);
323 +                        add_stat(LONG_LONG, &disk[i].io_size,
324 +                                 "fs", name, "io_size", NULL);
325 +                        add_stat(LONG_LONG, &disk[i].block_size,
326 +                                 "fs", name, "block_size", NULL);
327 +                        add_stat(LONG_LONG, &disk[i].total_blocks,
328 +                                 "fs", name, "total_blocks", NULL);
329 +                        add_stat(LONG_LONG, &disk[i].free_blocks,
330 +                                 "fs", name, "free_blocks", NULL);
331 +                        add_stat(LONG_LONG, &disk[i].avail_blocks,
332 +                                 "fs", name, "avail_blocks", NULL);
333 +                        add_stat(LONG_LONG, &disk[i].used_blocks,
334 +                                 "fs", name, "used_blocks", NULL);
335  
336                          free(buf);
337                  }
# Line 328 | Line 350 | void populate_disk() {
350          
351                          add_stat(STRING, &diskio[i].disk_name,
352                                   "disk", name, "disk_name", NULL);
353 <                        add_stat(LONG_LONG, &diskio[i].read_bytes,
353 >                        add_stat(BYTES, &diskio[i].read_bytes,
354                                   "disk", name, "read_bytes", NULL);
355 <                        add_stat(LONG_LONG, &diskio[i].write_bytes,
355 >                        add_stat(BYTES, &diskio[i].write_bytes,
356                                   "disk", name, "write_bytes", NULL);
357                          add_stat(TIME_T, &diskio[i].systime,
358                                   "disk", name, "systime", NULL);
# Line 364 | Line 386 | void populate_net() {
386          
387                          add_stat(STRING, &io[i].interface_name,
388                                   "net", name, "interface_name", NULL);
389 <                        add_stat(LONG_LONG, &io[i].tx,
389 >                        add_stat(BYTES, &io[i].tx,
390                                   "net", name, "tx", NULL);
391 <                        add_stat(LONG_LONG, &io[i].rx,
391 >                        add_stat(BYTES, &io[i].rx,
392                                   "net", name, "rx", NULL);
393                          add_stat(LONG_LONG, &io[i].ipackets,
394                                   "net", name, "ipackets", NULL);
# Line 409 | Line 431 | void populate_net() {
431                                   "net", name, "speed", NULL);
432                          add_stat(BOOL, &iface[i].up,
433                                   "net", name, "up", NULL);
434 <                        add_stat(DUPLEX, &iface[i].dup,
434 >                        add_stat(DUPLEX, &iface[i].duplex,
435                                   "net", name, "duplex", NULL);
436                  }
437          }
# Line 470 | Line 492 | void select_interesting(int argc, char **argv) {
492          }
493   }
494  
495 < /* Clear and rebuild the stats array. */
495 > /* Clear and rebuild the stat_items array. */
496   void get_stats() {
497          toplevel *t;
498  
# Line 481 | Line 503 | void get_stats() {
503                          t->populate();
504          }
505  
506 <        if (stats != NULL)
507 <                qsort(stats, num_stats, sizeof *stats, stats_compare);
506 >        if (stat_items != NULL)
507 >                qsort(stat_items, num_stats, sizeof *stat_items, stats_compare);
508   }
509  
510 < /* Print the value of a stat. */
511 < void print_stat_value(const stat *s) {
510 > /* Print the value of a stat_item. */
511 > void print_stat_value(const stat_item *s) {
512          void *v = s->stat;
513 <        long l;
513 >        double fv;
514 >        long lv;
515 >        long long llv;
516  
517          switch (s->type) {
518          case LONG_LONG:
519 + #ifdef WIN32 /* Windows printf does not understand %lld, so use %I64d instead */
520 +                printf("%I64d", *(long long *)v);
521 + #else
522                  printf("%lld", *(long long *)v);
523 + #endif
524                  break;
525 +        case BYTES:
526 +                llv = *(long long *)v;
527 +                if (bytes_scale_factor != 0) {
528 +                        llv /= bytes_scale_factor;
529 +                }
530 + #ifdef WIN32
531 +                printf("%I64d", llv);
532 + #else
533 +                printf("%lld", llv);
534 + #endif
535 +                break;
536          case TIME_T:
537                  /* FIXME option for formatted time? */
538 <                l = *(time_t *)v;
539 <                printf("%ld", l);
538 >                lv = *(time_t *)v;
539 >                printf("%ld", lv);
540                  break;
541          case FLOAT:
503                printf("%f", *(float *)v);
504                break;
542          case DOUBLE:
543 <                printf("%f", *(double *)v);
543 >                if (s->type == FLOAT) {
544 >                        fv = *(float *)v;
545 >                } else {
546 >                        fv = *(double *)v;
547 >                }
548 >                if (float_scale_factor != 0) {
549 >                        printf("%ld", (long)(float_scale_factor * fv));
550 >                } else {
551 >                        printf("%f", fv);
552 >                }
553                  break;
554          case STRING:
555                  /* FIXME escaping? */
# Line 532 | Line 578 | void print_stat_value(const stat *s) {
578   }
579  
580   /* Print the name and value of a stat. */
581 < void print_stat(const stat *s) {
581 > void print_stat(const stat_item *s) {
582          switch (display_mode) {
583          case DISPLAY_LINUX:
584                  printf("%s = ", s->name);
# Line 555 | Line 601 | void print_stats(int argc, char **argv) {
601          if (argc == optind) {
602                  /* Print all stats. */
603                  for (i = 0; i < num_stats; i++)
604 <                        print_stat(&stats[i]);
604 >                        print_stat(&stat_items[i]);
605          } else {
606                  /* Print selected stats. */
607                  for (i = optind; i < argc; i++) {
608                          char *name = argv[i];
609 <                        stat key;
610 <                        const stat *s, *end;
609 >                        stat_item key;
610 >                        const stat_item *s, *end;
611                          int (*compare)(const void *, const void *);
612  
613                          key.name = name;
# Line 570 | Line 616 | void print_stats(int argc, char **argv) {
616                          else
617                                  compare = stats_compare;
618  
619 <                        if (stats == NULL) {
619 >                        if (stat_items == NULL) {
620                                  s = NULL;
621                          } else {
622 <                                s = (const stat *)bsearch(&key, stats,
622 >                                s = (const stat_item *)bsearch(&key, stat_items,
623                                                            num_stats,
624 <                                                          sizeof *stats,
624 >                                                          sizeof *stat_items,
625                                                            compare);
626                          }
627  
# Line 585 | Line 631 | void print_stats(int argc, char **argv) {
631                          }
632  
633                          /* Find the range of stats the user wanted. */
634 <                        for (; s >= stats; s--) {
634 >                        for (; s >= stat_items; s--) {
635                                  if (compare(&key, s) != 0)
636                                          break;
637                          }
638                          s++;
639 <                        for (end = s; end < &stats[num_stats]; end++) {
639 >                        for (end = s; end < &stat_items[num_stats]; end++) {
640                                  if (compare(&key, end) != 0)
641                                          break;
642                          }
# Line 610 | Line 656 | void usage() {
656                 "If no STATs are given, all will be displayed. Specify 'STAT.' to display all\n"
657                 "statistics starting with that prefix.\n"
658                 "\n");
659 <        printf("  -l     Linux sysctl-style output (default)\n"
660 <               "  -b     BSD sysctl-style output\n"
661 <               "  -m     MRTG-compatible output\n"
662 <               "  -u     Plain output (only show values)\n"
663 <               "  -n     Display cumulative stats once (default)\n"
664 <               "  -s     Display stat differences repeatedly\n"
665 <               "  -o     Display stat differences once\n"
659 >        printf("  -l         Linux sysctl-style output (default)\n"
660 >               "  -b         BSD sysctl-style output\n"
661 >               "  -m         MRTG-compatible output\n"
662 >               "  -u         Plain output (only show values)\n"
663 >               "  -n         Display cumulative stats once (default)\n"
664 >               "  -s         Display stat differences repeatedly\n"
665 >               "  -o         Display stat differences once\n"
666                 "  -t DELAY   When repeating, wait DELAY seconds between updates (default 1)\n"
667 <               "  -p     Display CPU usage differences as percentages rather than\n"
668 <               "             absolute values\n"
667 >               "  -p         Display CPU usage differences as percentages rather than\n"
668 >               "             absolute values\n"
669 >               "  -f FACTOR  Display floating-point values as integers scaled by FACTOR\n"
670 >               "  -K         Display byte counts in kibibytes\n"
671 >               "  -M         Display byte counts in mebibytes\n"
672 >               "  -G         Display byte counts in gibibytes\n"
673                 "\n");
674          printf("Version %s - report bugs to <%s>.\n",
675                 PACKAGE_VERSION, PACKAGE_BUGREPORT);
# Line 629 | Line 679 | void usage() {
679   int main(int argc, char **argv) {
680          opterr = 0;
681          while (1) {
682 <                int c = getopt(argc, argv, "lbmunsot:p");
682 >                int c = getopt(argc, argv, "lbmunsot:pf:KMG");
683                  if (c == -1)
684                          break;
685                  switch (c) {
# Line 660 | Line 710 | int main(int argc, char **argv) {
710                  case 'p':
711                          use_cpu_percent = 1;
712                          break;
713 +                case 'f':
714 +                        float_scale_factor = atol(optarg);
715 +                        break;
716 +                case 'K':
717 +                        bytes_scale_factor = 1024;
718 +                        break;
719 +                case 'M':
720 +                        bytes_scale_factor = 1024 * 1024;
721 +                        break;
722 +                case 'G':
723 +                        bytes_scale_factor = 1024 * 1024 * 1024;
724 +                        break;
725                  default:
726                          usage();
727                  }
# Line 682 | Line 744 | int main(int argc, char **argv) {
744  
745          select_interesting(argc - optind, &argv[optind]);
746  
747 <        /* We don't care if statgrab_init fails, because we can just display
747 >        /* We don't care if sg_init fails, because we can just display
748             the statistics that can be read as non-root. */
749          sg_init();
750 +        sg_snapshot();
751          if (sg_drop_privileges() != 0)
752                  die("Failed to drop setuid/setgid privileges");
753  
# Line 696 | Line 759 | int main(int argc, char **argv) {
759          case REPEAT_ONCE:
760                  get_stats();
761                  sleep(repeat_time);
762 +                sg_snapshot();
763                  get_stats();
764                  print_stats(argc, argv);
765                  break;
# Line 705 | Line 769 | int main(int argc, char **argv) {
769                          print_stats(argc, argv);
770                          printf("\n");
771                          sleep(repeat_time);
772 +                        sg_snapshot();
773                  }
774          }
775  
# Line 712 | Line 777 | int main(int argc, char **argv) {
777                  printf("\n");
778                  printf("statgrab\n");
779          }
780 +
781 +        sg_shutdown();
782  
783          return 0;
784   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines