]> git.itanic.dy.fi Git - scan-pagemap/commitdiff
parser: Add support for parsing processes by name
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Fri, 23 Jul 2010 10:41:22 +0000 (13:41 +0300)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Fri, 23 Jul 2010 10:41:22 +0000 (13:41 +0300)
Signed-off-by: Timo Kokkonen <kaapeli@itanic.dy.fi>
parse.c

diff --git a/parse.c b/parse.c
index 117026b1c3a4e2fd4894965622fe9805dfc10433..678dda339c9d4c0dc8db9004ca6836a3a8561331 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
+#include <libgen.h>
 
 #include "parse.h"
 #include "pagemap.h"
@@ -144,6 +145,26 @@ static int read_cmdline(int pid, int tid, char *cmdline, size_t len)
        return ret > 0 ? 0 : -1;
 }
 
+static char *get_name_by_pid(int pid)
+{
+       static int last_pid;
+       static char cmdline[128];
+       static char *bname;
+
+       if (last_pid == pid)
+               return bname;
+
+       if (read_cmdline(pid, pid, cmdline, sizeof(cmdline))) {
+               bname = NULL;
+               return NULL;
+       }
+
+       bname = basename(cmdline);
+
+       last_pid = pid;
+       return bname;
+}
+
 static int check_parse_opts(struct parse_opts *opts, struct pageframe *pf,
                struct maps *map)
 {
@@ -157,6 +178,11 @@ static int check_parse_opts(struct parse_opts *opts, struct pageframe *pf,
                        return 1;
        }
 
+       if (opts->parse_mask & PARSE_PROCESS_NAME) {
+               if (!strcmp(opts->name, get_name_by_pid(map->pid)))
+                       return 1;
+       }
+
        return 0;
 }
 
@@ -369,6 +395,31 @@ static int get_next_pid(DIR **dir)
        return parse_pid(dir);
 }
 
+static int get_next_pid_by_name(DIR **dir, char *name)
+{
+       int pid;
+       char *pname;
+
+       if (opendir_check(dir, "/proc"))
+               return -1;
+
+       while (1) {
+               pid = parse_pid(dir);
+               if (pid <= 0)
+                       break;
+
+               pname = get_name_by_pid(pid);
+               if (pname == NULL)
+                       continue;
+               if (strcmp(pname, name))
+                       continue;
+
+               return pid;
+       }
+
+       return 0;
+}
+
 static void read_pageframe_with_threads(int pid,
                                        struct pageframe *pageframe,
                                        struct process **process_list,
@@ -399,6 +450,14 @@ void scan_all_pids(struct pageframe *pf, struct process **process_list,
        DIR *dir = NULL;
        int pid;
 
+       if (opts->parse_mask & PARSE_PROCESS_NAME) {
+               while ((pid = get_next_pid_by_name(&dir, opts->name))) {
+                       read_pageframe_with_threads(pid, pf, process_list,
+                                               opts);
+               }
+               dir = NULL;
+       }
+
        if (opts->parse_mask & PARSE_PID)
                read_pageframe_with_threads(opts->pid, pf, process_list, opts);