dump-cpp sandbox/klewandowski/dump-cpp
authorKarol Lewandowski <lmctl@lmctl.net>
Tue, 18 Sep 2018 23:47:59 +0000 (01:47 +0200)
committerKarol Lewandowski <lmctl@lmctl.net>
Tue, 18 Sep 2018 23:54:29 +0000 (01:54 +0200)
src/dump_systemstate/dump_systemstate.c

index 2f6061dda1b5024410d3fb30ce10ddee4f95404c..17fe82929bbcb828dc98cb3e8acdb81e55c651c9 100644 (file)
@@ -95,14 +95,57 @@ static int get_disk_used_percent(const char *path)
        return percent;
 }
 
+class Command {
+ public:
+ Command(const char *_title, std::vector<const char *> _av, std::vector<const char *> _ev)
+        : av(_av), ev(_ev)
+       {
+               title = strdup(_title);
+               av.push_back(NULL);
+               ev.push_back(NULL);
+       }
+
+       int run(void) {
+               int fd[2];
+
+               pipe(fd);
+               fd_child = fd[0];
+               fcntl(fd[1], F_SETPIPE_SZ, DEFAULT_PIPE_SIZE);
+
+               int r = spawn(av, ev, spawn_setstdout, (void *)fd[1], 0, &pid);
+
+               close(fd[1]);
+               return r;
+       }
+
+       int dump(int _outfd) {
+               if (title) {
+                       dprintf(_outfd, "\n==== %s (", title);
+                       for (auto v : av)
+                               dprintf(_outfd, " %s", v);
+                       dprintf(_outfd, ")\n");
+               }
+
+               return copy_bytes(_outfd, fd[0]);
+       }
+
+       ~Command() {
+               if (fd_child != -1)
+                       close(fd_child);
+               if (pid != -1)
+                       wait_for_pid(pid);
+       }
+ private:
+       int fd_child = -1;
+       pid_t pid = -1;
+       char *title;
+       std::vector<const char *> av;
+       std::vector<const char *> ev;
+
+}
+
 static int dump_commands(int out_fd, bool dump_dmesg, bool dump_dlog, bool dump_journal)
 {
-       static char *const ev[] = {
-               "COLUMNS=200",       // for top(1)
-               "TZ=UTC",            // for dmesg(1)
-               NULL
-       };
-
        int dpercent = get_disk_used_percent("/opt");
        char *dtitle = NULL;
        bool is_root = geteuid() == 0;
@@ -112,39 +155,39 @@ static int dump_commands(int out_fd, bool dump_dmesg, bool dump_dlog, bool dump_
        if (!dtitle || r < 0)
                return -errno;
 
-       struct commands {
-               bool active;
-               char *title;
-               char *av[8]; /* XXX inflexible: update this field to match actuall cmd arguments below */
-       } commands[] = {
-               { 1, "System disk space usage", {"/bin/df", "-h", NULL}, },
-               { 90 < dpercent, dtitle, {"/bin/du", "-ah", "/opt", "--exclude=/opt/usr", NULL},  },
-               { 1, "System timezone", {"/bin/ls", "-al", "/opt/etc/localtime", NULL}, },
-               { 1, "System summary", { "/bin/top", "-bcH", "-n", "1", NULL}, },
-               { 1, "Current processes", {"/bin/ps", "auxfw", NULL}, },
-               { 1, "System memory statistics", {"/bin/memps", "-v", NULL}, },
-               { is_root, "System configuration (memory, db, file)", {"/bin/vconftool", "get", "memory/", "-r", NULL}, },
-               { is_root, NULL, {"/bin/vconftool", "get", "db/", "-r", NULL}, },
-               { is_root, NULL, {"/bin/vconftool", "get", "file/", "-r", NULL}, },
-               { dump_dmesg && is_root, "Kernel messages", {"/bin/dmesg", "-T", NULL},  },
-               { dump_dlog, "Log messages", {"/bin/dlogutil", "-d", "-v", "threadtime", "-u", "16384", NULL}, },
-               { dump_journal, "Journal messages", {"/bin/journalctl", "-b", "-n", "1024", NULL}, },
-       };
-
-       for (int i = 0; i < ARRAY_SIZE(commands); i++) {
-               if (!commands[i].active)
-                       continue;
-               if (commands[i].title) {
-                       dprintf(out_fd, "\n==== %s (", commands[i].title);
-                       for (int j = 0; j < ARRAY_SIZE(commands[i].av) && commands[i].av[j]; j++)
-                               dprintf(out_fd, " %s", commands[i].av[j]);
-                       dprintf(out_fd, ")\n");
-               }
-               int ret = spawn_wait(commands[i].av, ev, spawn_setstdout, (void *)out_fd, TIMEOUT_DEFAULT_MS);
-               if (ret != 0)
-                       break;
+       std::list<Command> cmd;
+
+       cmd.push_back(Command("System disk space usage", {"/bin/df", "-h"}, {}));
+
+       if (90 < dpercent)
+               cmd.push_back(Command(dtitle, {"/bin/du", "-ah", "/opt", "--exclude=/opt/usr"}, {}));
+
+       cmd.push_back(Command("System timezone", {"/bin/ls", "-al", "/opt/etc/localtime"},{}));
+       cmd.push_back(Command("System summary", {"/bin/top", "-bcH", "-n", "1"}, {"COLUMNS=200"}));
+       cmd.push_back(Command("Current processes", {"/bin/ps", "auxfw"}, {}));
+       cmd.push_back(Command("System memory statistics", {"/bin/memps", "-v"}, {}));
+
+       if (is_root) {
+               cmd.push_back(Command("System configuration (memory, db, file)", {"/bin/vconftool", "get", "memory/", "-r"}, {}));
+               cmd.push_back(Command(NULL, {"/bin/vconftool", "get", "db/", "-r"}, {}));
+               cmd.push_back(Command(NULL, {"/bin/vconftool", "get", "file/", "-r"}, {}));
        }
 
+       if (is_root & dmesg)
+               cmd.push_back(Command("Kernel messages", {"/bin/dmesg", "-T"}, {"TZ=UTC"}));
+
+       if (dump_dlog)
+               cmd.push_back(Command("Log messages", {"/bin/dlogutil", "-d", "-v", "threadtime", "-u", "16384"}, {}));
+
+       if (dump_journal)
+               cmd.push_back(Command("Journal messages", {"/bin/journalctl", "-b", "-n", "1024"}, {}));
+
+       for (int e : cmd)
+               e.run();
+
+       for (int e : cmd)
+               e.dump(out_fd);
+
        free(dtitle);
        return ret;
 }