chiark / gitweb /
install, cgtop: adjust hashmap_move_one() callers for -ENOMEM possibility
[elogind.git] / src / cgtop / cgtop.c
index 38f4c3050dddc20c47832610380da0f16a278270..932a7ba7c6c360c8bf5d1c2ad8842d7f47e0c21b 100644 (file)
@@ -98,7 +98,7 @@ static void group_hashmap_free(Hashmap *h) {
 static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) {
         Group *g;
         int r;
 static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) {
         Group *g;
         int r;
-        FILE *f;
+        FILE *f = NULL;
         pid_t pid;
         unsigned n;
 
         pid_t pid;
         unsigned n;
 
@@ -126,7 +126,9 @@ static int process(const char *controller, const char *path, Hashmap *a, Hashmap
                                 return r;
                         }
                 } else {
                                 return r;
                         }
                 } else {
-                        assert_se(hashmap_move_one(a, b, path) == 0);
+                        r = hashmap_move_one(a, b, path);
+                        if (r < 0)
+                                return r;
                         g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false;
                 }
         }
                         g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false;
                 }
         }
@@ -134,7 +136,7 @@ static int process(const char *controller, const char *path, Hashmap *a, Hashmap
         /* Regardless which controller, let's find the maximum number
          * of processes in any of it */
 
         /* Regardless which controller, let's find the maximum number
          * of processes in any of it */
 
-        r = cg_enumerate_tasks(controller, path, &f);
+        r = cg_enumerate_processes(controller, path, &f);
         if (r < 0)
                 return r;
 
         if (r < 0)
                 return r;
 
@@ -446,7 +448,7 @@ static int display(Hashmap *a) {
         Group **array;
         signed path_columns;
         unsigned rows, n = 0, j, maxtcpu = 0, maxtpath = 0;
         Group **array;
         signed path_columns;
         unsigned rows, n = 0, j, maxtcpu = 0, maxtpath = 0;
-        char cpu_title[21];
+        char buffer[MAX3(21, FORMAT_BYTES_MAX, FORMAT_TIMESPAN_MAX)];
 
         assert(a);
 
 
         assert(a);
 
@@ -461,29 +463,30 @@ static int display(Hashmap *a) {
                 if (g->n_tasks_valid || g->cpu_valid || g->memory_valid || g->io_valid)
                         array[n++] = g;
 
                 if (g->n_tasks_valid || g->cpu_valid || g->memory_valid || g->io_valid)
                         array[n++] = g;
 
-        qsort(array, n, sizeof(Group*), group_compare);
+        qsort_safe(array, n, sizeof(Group*), group_compare);
 
         /* Find the longest names in one run */
         for (j = 0; j < n; j++) {
                 unsigned cputlen, pathtlen;
 
         /* Find the longest names in one run */
         for (j = 0; j < n; j++) {
                 unsigned cputlen, pathtlen;
-                snprintf(cpu_title, sizeof(cpu_title), "%"PRIu64, array[j]->cpu_usage);
-                cputlen = strlen(cpu_title);
+
+                format_timespan(buffer, sizeof(buffer), (nsec_t) (array[j]->cpu_usage / NSEC_PER_USEC), 0);
+                cputlen = strlen(buffer);
                 maxtcpu = MAX(maxtcpu, cputlen);
                 pathtlen = strlen(array[j]->path);
                 maxtpath = MAX(maxtpath, pathtlen);
         }
 
         if (arg_cpu_type == CPU_PERCENT)
                 maxtcpu = MAX(maxtcpu, cputlen);
                 pathtlen = strlen(array[j]->path);
                 maxtpath = MAX(maxtpath, pathtlen);
         }
 
         if (arg_cpu_type == CPU_PERCENT)
-                snprintf(cpu_title, sizeof(cpu_title), "%6s", "%CPU");
+                snprintf(buffer, sizeof(buffer), "%6s", "%CPU");
         else
         else
-                snprintf(cpu_title, sizeof(cpu_title), "%*s", maxtcpu, "CPU Time");
+                snprintf(buffer, sizeof(buffer), "%*s", maxtcpu, "CPU Time");
 
         rows = lines();
         if (rows <= 10)
                 rows = 10;
 
         if (on_tty()) {
 
         rows = lines();
         if (rows <= 10)
                 rows = 10;
 
         if (on_tty()) {
-                path_columns = columns() - 36 - strlen(cpu_title);
+                path_columns = columns() - 36 - strlen(buffer);
                 if (path_columns < 10)
                         path_columns = 10;
 
                 if (path_columns < 10)
                         path_columns = 10;
 
@@ -492,7 +495,7 @@ static int display(Hashmap *a) {
                        arg_order == ORDER_PATH ? OFF : "",
                        arg_order == ORDER_TASKS ? ON : "", "Tasks",
                        arg_order == ORDER_TASKS ? OFF : "",
                        arg_order == ORDER_PATH ? OFF : "",
                        arg_order == ORDER_TASKS ? ON : "", "Tasks",
                        arg_order == ORDER_TASKS ? OFF : "",
-                       arg_order == ORDER_CPU ? ON : "", cpu_title,
+                       arg_order == ORDER_CPU ? ON : "", buffer,
                        arg_order == ORDER_CPU ? OFF : "",
                        arg_order == ORDER_MEMORY ? ON : "", "Memory",
                        arg_order == ORDER_MEMORY ? OFF : "",
                        arg_order == ORDER_CPU ? OFF : "",
                        arg_order == ORDER_MEMORY ? ON : "", "Memory",
                        arg_order == ORDER_MEMORY ? OFF : "",
@@ -505,7 +508,6 @@ static int display(Hashmap *a) {
 
         for (j = 0; j < n; j++) {
                 char *p;
 
         for (j = 0; j < n; j++) {
                 char *p;
-                char m[FORMAT_BYTES_MAX];
 
                 if (on_tty() && j + 5 > rows)
                         break;
 
                 if (on_tty() && j + 5 > rows)
                         break;
@@ -521,24 +523,24 @@ static int display(Hashmap *a) {
                 else
                         fputs("       -", stdout);
 
                 else
                         fputs("       -", stdout);
 
-                if (arg_cpu_type == CPU_PERCENT)
+                if (arg_cpu_type == CPU_PERCENT) {
                         if (g->cpu_valid)
                                 printf(" %6.1f", g->cpu_fraction*100);
                         else
                                 fputs("      -", stdout);
                         if (g->cpu_valid)
                                 printf(" %6.1f", g->cpu_fraction*100);
                         else
                                 fputs("      -", stdout);
-                else
-                        printf(" %*"PRIu64, maxtcpu, g->cpu_usage);
+                else
+                        printf(" %*s", maxtcpu, format_timespan(buffer, sizeof(buffer), (nsec_t) (g->cpu_usage / NSEC_PER_USEC), 0));
 
                 if (g->memory_valid)
 
                 if (g->memory_valid)
-                        printf(" %8s", format_bytes(m, sizeof(m), g->memory));
+                        printf(" %8s", format_bytes(buffer, sizeof(buffer), g->memory));
                 else
                         fputs("        -", stdout);
 
                 if (g->io_valid) {
                         printf(" %8s",
                 else
                         fputs("        -", stdout);
 
                 if (g->io_valid) {
                         printf(" %8s",
-                               format_bytes(m, sizeof(m), g->io_input_bps));
+                               format_bytes(buffer, sizeof(buffer), g->io_input_bps));
                         printf(" %8s",
                         printf(" %8s",
-                               format_bytes(m, sizeof(m), g->io_output_bps));
+                               format_bytes(buffer, sizeof(buffer), g->io_output_bps));
                 } else
                         fputs("        -        -", stdout);
 
                 } else
                         fputs("        -        -", stdout);
 
@@ -549,7 +551,6 @@ static int display(Hashmap *a) {
 }
 
 static void help(void) {
 }
 
 static void help(void) {
-
         printf("%s [OPTIONS...]\n\n"
                "Show top control groups by their resource usage.\n\n"
                "  -h --help           Show this help\n"
         printf("%s [OPTIONS...]\n\n"
                "Show top control groups by their resource usage.\n\n"
                "  -h --help           Show this help\n"
@@ -563,12 +564,8 @@ static void help(void) {
                "  -d --delay=DELAY    Delay between updates\n"
                "  -n --iterations=N   Run for N iterations before exiting\n"
                "  -b --batch          Run in batch mode, accepting no input\n"
                "  -d --delay=DELAY    Delay between updates\n"
                "  -n --iterations=N   Run for N iterations before exiting\n"
                "  -b --batch          Run in batch mode, accepting no input\n"
-               "     --depth=DEPTH    Maximum traversal depth (default: %d)\n",
-               program_invocation_short_name, arg_depth);
-}
-
-static void version(void) {
-        puts(PACKAGE_STRING " cgtop");
+               "     --depth=DEPTH    Maximum traversal depth (default: %u)\n"
+               , program_invocation_short_name, arg_depth);
 }
 
 static int parse_argv(int argc, char *argv[]) {
 }
 
 static int parse_argv(int argc, char *argv[]) {
@@ -587,7 +584,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "batch",      no_argument,       NULL, 'b'         },
                 { "depth",      required_argument, NULL, ARG_DEPTH   },
                 { "cpu",        optional_argument, NULL, ARG_CPU_TYPE},
                 { "batch",      no_argument,       NULL, 'b'         },
                 { "depth",      required_argument, NULL, ARG_DEPTH   },
                 { "cpu",        optional_argument, NULL, ARG_CPU_TYPE},
-                { NULL,         0,                 NULL, 0           }
+                {}
         };
 
         int c;
         };
 
         int c;
@@ -596,7 +593,7 @@ static int parse_argv(int argc, char *argv[]) {
         assert(argc >= 1);
         assert(argv);
 
         assert(argc >= 1);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0) {
+        while ((c = getopt_long(argc, argv, "hptcmin:bd:", options, NULL)) >= 0)
 
                 switch (c) {
 
 
                 switch (c) {
 
@@ -605,7 +602,8 @@ static int parse_argv(int argc, char *argv[]) {
                         return 0;
 
                 case ARG_VERSION:
                         return 0;
 
                 case ARG_VERSION:
-                        version();
+                        puts(PACKAGE_STRING);
+                        puts(SYSTEMD_FEATURES);
                         return 0;
 
                 case ARG_CPU_TYPE:
                         return 0;
 
                 case ARG_CPU_TYPE:
@@ -629,7 +627,7 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'd':
                         break;
 
                 case 'd':
-                        r = parse_usec(optarg, &arg_delay);
+                        r = parse_sec(optarg, &arg_delay);
                         if (r < 0 || arg_delay <= 0) {
                                 log_error("Failed to parse delay parameter.");
                                 return -EINVAL;
                         if (r < 0 || arg_delay <= 0) {
                                 log_error("Failed to parse delay parameter.");
                                 return -EINVAL;
@@ -674,10 +672,8 @@ static int parse_argv(int argc, char *argv[]) {
                         return -EINVAL;
 
                 default:
                         return -EINVAL;
 
                 default:
-                        log_error("Unknown option code %c", c);
-                        return -EINVAL;
+                        assert_not_reached("Unhandled option");
                 }
                 }
-        }
 
         if (optind < argc) {
                 log_error("Too many arguments.");
 
         if (optind < argc) {
                 log_error("Too many arguments.");
@@ -701,8 +697,8 @@ int main(int argc, char *argv[]) {
         if (r <= 0)
                 goto finish;
 
         if (r <= 0)
                 goto finish;
 
-        a = hashmap_new(string_hash_func, string_compare_func);
-        b = hashmap_new(string_hash_func, string_compare_func);
+        a = hashmap_new(&string_hash_ops);
+        b = hashmap_new(&string_hash_ops);
         if (!a || !b) {
                 r = log_oom();
                 goto finish;
         if (!a || !b) {
                 r = log_oom();
                 goto finish;
@@ -793,13 +789,17 @@ int main(int argc, char *argv[]) {
                         arg_order = ORDER_IO;
                         break;
 
                         arg_order = ORDER_IO;
                         break;
 
+                case '%':
+                        arg_cpu_type = arg_cpu_type == CPU_TIME ? CPU_PERCENT : CPU_TIME;
+                        break;
+
                 case '+':
                         if (arg_delay < USEC_PER_SEC)
                                 arg_delay += USEC_PER_MSEC*250;
                         else
                                 arg_delay += USEC_PER_SEC;
 
                 case '+':
                         if (arg_delay < USEC_PER_SEC)
                                 arg_delay += USEC_PER_MSEC*250;
                         else
                                 arg_delay += USEC_PER_SEC;
 
-                        fprintf(stdout, "\nIncreased delay to %s.", format_timespan(h, sizeof(h), arg_delay));
+                        fprintf(stdout, "\nIncreased delay to %s.", format_timespan(h, sizeof(h), arg_delay, 0));
                         fflush(stdout);
                         sleep(1);
                         break;
                         fflush(stdout);
                         sleep(1);
                         break;
@@ -812,7 +812,7 @@ int main(int argc, char *argv[]) {
                         else
                                 arg_delay -= USEC_PER_SEC;
 
                         else
                                 arg_delay -= USEC_PER_SEC;
 
-                        fprintf(stdout, "\nDecreased delay to %s.", format_timespan(h, sizeof(h), arg_delay));
+                        fprintf(stdout, "\nDecreased delay to %s.", format_timespan(h, sizeof(h), arg_delay, 0));
                         fflush(stdout);
                         sleep(1);
                         break;
                         fflush(stdout);
                         sleep(1);
                         break;
@@ -820,8 +820,9 @@ int main(int argc, char *argv[]) {
                 case '?':
                 case 'h':
                         fprintf(stdout,
                 case '?':
                 case 'h':
                         fprintf(stdout,
-                                "\t<" ON "P" OFF "> By path; <" ON "T" OFF "> By tasks; <" ON "C" OFF "> By CPU; <" ON "M" OFF "> By memory; <" ON "I" OFF "> By I/O\n"
-                                "\t<" ON "Q" OFF "> Quit; <" ON "+" OFF "> Increase delay; <" ON "-" OFF "> Decrease delay; <" ON "SPACE" OFF "> Refresh");
+                                "\t<" ON "p" OFF "> By path; <" ON "t" OFF "> By tasks; <" ON "c" OFF "> By CPU; <" ON "m" OFF "> By memory; <" ON "i" OFF "> By I/O\n"
+                                "\t<" ON "+" OFF "> Increase delay; <" ON "-" OFF "> Decrease delay; <" ON "%%" OFF "> Toggle time\n"
+                                "\t<" ON "q" OFF "> Quit; <" ON "SPACE" OFF "> Refresh");
                         fflush(stdout);
                         sleep(3);
                         break;
                         fflush(stdout);
                         sleep(3);
                         break;