Advertisement
Guest User

memusage.c

a guest
Mar 25th, 2015
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.81 KB | None | 0 0
  1. /* Copyright (c) 2015 cmm2
  2.  *
  3.  * Permission to use, copy, modify, and/or distribute this software for any
  4.  * purpose with or without fee is hereby granted, provided that the above
  5.  * copyright notice and this permission notice appear in all copies.
  6.  *
  7.  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  8.  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  9.  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  10.  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  11.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  12.  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  13.  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  14.  */
  15.  
  16. #define _GNU_SOURCE
  17. #include <assert.h>
  18. #include <errno.h>
  19. #include <error.h>
  20. #include <math.h>
  21. #include <stddef.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <sys/types.h>
  25. #include <sys/user.h>
  26.  
  27. struct statm {
  28.     size_t size;
  29.     size_t resident;
  30.     size_t shared;
  31.     size_t text;
  32.     size_t lib;
  33.     size_t data;
  34.     size_t dt;
  35. };
  36.  
  37. void
  38. read_statm(pid_t pid, struct statm* s) {
  39.     FILE *file = NULL;
  40.     char *line = NULL;
  41.     char *path = NULL;
  42.     size_t line_len = 0;
  43.  
  44.     assert(pid > 0);
  45.     assert(s != NULL);
  46.  
  47.     if (asprintf(&path, "/proc/%i/statm", pid) == -1)
  48.         error(1, errno, "failed to allocate /proc/%i/statm string", pid);
  49.  
  50.     file = fopen(path, "r");
  51.  
  52.     if (file == NULL)
  53.         error(1, errno, "failed to open %s", path);
  54.  
  55.     if (getline(&line, &line_len, file) == -1)
  56.         error(1, errno, "failed to read %s", path);
  57.  
  58.     if (sscanf(line, "%zu %zu %zu %zu %zu %zu %zu", &s->size, &s->resident,
  59.         &s->shared, &s->text, &s->lib, &s->data, &s->dt) != 7)
  60.         error(1, errno, "failed to parse %s", path);
  61.  
  62.     free(line);
  63.     fclose(file);
  64.     free(path);
  65. }
  66.  
  67. pid_t
  68. pid_from_string(char const* str) {
  69.     pid_t pid;
  70.  
  71.     assert(str != NULL);
  72.  
  73.     errno = 0;
  74.  
  75.     pid = strtol(str, NULL, 10);
  76.  
  77.     if (errno != 0)
  78.         error(1, errno, "failed to parse pid %s", str);
  79.  
  80.     if (pid < 1)
  81.         error(1, 0, "pid out of range: %s", str);
  82.  
  83.     return pid;
  84. }
  85.  
  86. double
  87. size_round(size_t n, char const** suffix) {
  88.     assert(suffix != NULL);
  89.  
  90.     if (n < 1.024E3) {
  91.         *suffix = "B";
  92.         return n/1E0;
  93.     }
  94.     if (n < 1.048576E6) {
  95.         *suffix = "KiB";
  96.         return n/1.024E3;
  97.     }
  98.     if (n < 1.073741824E9) {
  99.         *suffix = "MiB";
  100.         return n/1.048576E6;
  101.     }
  102.     if (n < 1.099511627776E12) {
  103.         *suffix = "GiB";
  104.         return n/1.073741824E9;
  105.     }
  106.     if (n < 1.125899906842624E15) {
  107.         *suffix = "TiB";
  108.         return n/1.099511627776E12;
  109.     }
  110.     if (n < 1.152921504606846976E18) {
  111.         *suffix = "PiB";
  112.         return n/1.125899906842624E15;
  113.     }
  114.     error(1, 0, "size out of range");
  115.  
  116.     return 0;
  117. }
  118.  
  119. void
  120. print_statm_mem(struct statm const* s) {
  121.     double n;
  122.     char const* suffix = NULL;
  123.  
  124.     assert(s != NULL);
  125.     assert(s->resident > s->shared);
  126.  
  127.     printf("%-19s %-19s %-19s %-19s\n", "Private", "Virtual", "Resident",
  128.         "Shared");
  129.  
  130.     n = size_round((s->resident - s->shared) * PAGE_SIZE, &suffix);
  131.     printf("%-6.2lf %-13s", n, suffix);
  132.  
  133.     n = size_round(s->size * PAGE_SIZE, &suffix);
  134.     printf("%-6.2lf %-13s", n, suffix);
  135.  
  136.     n = size_round(s->resident * PAGE_SIZE, &suffix);
  137.     printf("%-6.2lf %-13s", n, suffix);
  138.  
  139.     n = size_round(s->shared * PAGE_SIZE, &suffix);
  140.     printf("%-6.2lf %-13s\n", n, suffix);
  141. }
  142.  
  143. int main(int argc, char const* argv[]) {
  144.     pid_t pid;
  145.     struct statm s = {0};
  146.  
  147.     if (argc < 2)
  148.         error(1, 0, "pid argument missing");
  149.  
  150.     pid = pid_from_string(argv[1]);
  151.  
  152.     read_statm(pid, &s);
  153.     print_statm_mem(&s);
  154.  
  155.     return 0;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement