Add proc_find_by_inode(...) which finds pid by inode & gets processe's
command line.

Actually this function was taken from flowtop.c walk_process(...)
and refactored to look more generic.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>

flowtop: Replace walk_processes(...) by proc_find_by_inode(...)

Use proc_find_by_inode(...) from proc.c to find pid by inode
and it's command line instead of having own specific process walker.

Signed-off-by: Vadim Kochan <vadi...@gmail.com>
---
v2:
   1) Add static to __match_pid_by_inode(...)
   2) Remove sys/stat.h & dirent.h includes from flowtop.c
   3) Squash changes into one patch

 flowtop.c | 78 ++++++++-------------------------------------------------------
 proc.c    | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 proc.h    |  1 +
 3 files changed, 84 insertions(+), 69 deletions(-)

diff --git a/flowtop.c b/flowtop.c
index 4f8cbcf..f382d6c 100644
--- a/flowtop.c
+++ b/flowtop.c
@@ -17,8 +17,6 @@
 #include <ctype.h>
 #include <netinet/in.h>
 #include <curses.h>
-#include <dirent.h>
-#include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/fsuid.h>
 #include <urcu.h>
@@ -474,80 +472,22 @@ static void flow_list_destroy(struct flow_list *fl)
        spinlock_unlock(&flow_list.lock);
 }
 
-static int walk_process(unsigned int pid, struct flow_entry *n)
+static void flow_entry_find_process(struct flow_entry *n)
 {
+       char cmdline[512];
+       pid_t pid;
        int ret;
-       DIR *dir;
-       struct dirent *ent;
-       char path[1024];
 
-       if (snprintf(path, sizeof(path), "/proc/%u/fd", pid) == -1)
-               panic("giant process name! %u\n", pid);
-
-       dir = opendir(path);
-       if (!dir)
-               return 0;
-
-       while ((ent = readdir(dir))) {
-               struct stat statbuf;
-
-               if (snprintf(path, sizeof(path), "/proc/%u/fd/%s",
-                            pid, ent->d_name) < 0)
-                       continue;
-
-               if (stat(path, &statbuf) < 0)
-                       continue;
-
-               if (S_ISSOCK(statbuf.st_mode) && (ino_t) n->inode == 
statbuf.st_ino) {
-                       char cmdline[256];
-
-                       ret = proc_get_cmdline(pid, cmdline, sizeof(cmdline));
-                       if (ret < 0)
-                               panic("Failed to get process cmdline: %s\n", 
strerror(errno));
-
-                       if (snprintf(n->procname, sizeof(n->procname), "%s", 
basename(cmdline)) < 0)
-                               n->procname[0] = '\0';
-                       n->procnum = pid;
-                       closedir(dir);
-                       return 1;
-               }
-       }
-
-       closedir(dir);
-       return 0;
-}
-
-static void walk_processes(struct flow_entry *n)
-{
-       int ret;
-       DIR *dir;
-       struct dirent *ent;
-
-       /* n->inode must be set */
-       if (n->inode <= 0) {
+       ret = proc_find_by_inode(n->inode, cmdline, sizeof(cmdline), &pid);
+       if (ret <= 0) {
                n->procname[0] = '\0';
                return;
        }
 
-       dir = opendir("/proc");
-       if (!dir)
-               panic("Cannot open /proc: %s\n", strerror(errno));
-
-       while ((ent = readdir(dir))) {
-               const char *name = ent->d_name;
-               char *end;
-               unsigned int pid = strtoul(name, &end, 10);
-
-               /* not a PID */
-               if (pid == 0 && end == name)
-                       continue;
-
-               ret = walk_process(pid, n);
-               if (ret > 0)
-                       break;
-       }
+       if (snprintf(n->procname, sizeof(n->procname), "%s", basename(cmdline)) 
< 0)
+               n->procname[0] = '\0';
 
-       closedir(dir);
+       n->procnum = pid;
 }
 
 static int get_port_inode(uint16_t port, int proto, bool is_ip6)
@@ -810,7 +750,7 @@ static void flow_entry_get_extended(struct flow_entry *n)
        n->inode = get_port_inode(n->port_src, n->l4_proto,
                                  n->l3_proto == AF_INET6);
        if (n->inode > 0)
-               walk_processes(n);
+               flow_entry_find_process(n);
 }
 
 static char *bandw2str(double bytes, char *buf, size_t len)
diff --git a/proc.c b/proc.c
index 76e3c93..f3fcd4b 100644
--- a/proc.c
+++ b/proc.c
@@ -3,11 +3,13 @@
 #endif
 #include <sched.h>
 #include <sys/wait.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/resource.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <dirent.h>
 
 #include "proc.h"
 #include "die.h"
@@ -83,6 +85,78 @@ ssize_t proc_get_cmdline(unsigned int pid, char *cmdline, 
size_t len)
        return ret;
 }
 
+static int __match_pid_by_inode(pid_t pid, ino_t ino)
+{
+       struct dirent *ent;
+       char path[1024];
+       DIR *dir;
+
+       if (snprintf(path, sizeof(path), "/proc/%u/fd", pid) == -1)
+               panic("giant process name! %u\n", pid);
+
+       dir = opendir(path);
+       if (!dir)
+               return -1;
+
+       while ((ent = readdir(dir))) {
+               struct stat statbuf;
+
+               if (snprintf(path, sizeof(path), "/proc/%u/fd/%s",
+                            pid, ent->d_name) < 0)
+                       continue;
+
+               if (stat(path, &statbuf) < 0)
+                       continue;
+
+               if (S_ISSOCK(statbuf.st_mode) && ino == statbuf.st_ino) {
+                       closedir(dir);
+                       return 0;
+               }
+       }
+
+       closedir(dir);
+       return -1;
+}
+
+int proc_find_by_inode(ino_t ino, char *cmdline, size_t len, pid_t *pid)
+{
+       struct dirent *ent;
+       DIR *dir;
+
+       if (ino <= 0) {
+               cmdline[0] = '\0';
+               return 0;
+       }
+
+       dir = opendir("/proc");
+       if (!dir)
+               panic("Cannot open /proc: %s\n", strerror(errno));
+
+       while ((ent = readdir(dir))) {
+               int ret;
+               char *end;
+               const char *name = ent->d_name;
+               pid_t _pid = strtoul(name, &end, 10);
+
+               /* not a PID */
+               if (_pid == 0 && end == name)
+                       continue;
+
+               ret = __match_pid_by_inode(_pid, ino);
+               if (!ret) {
+                       ret = proc_get_cmdline(_pid, cmdline, len);
+                       if (ret < 0)
+                               panic("Failed to get process cmdline: %s\n", 
strerror(errno));
+
+                       *pid = _pid;
+                       return ret;
+               }
+       }
+
+       closedir(dir);
+       return -1;
+}
+
 int proc_exec(const char *proc, char *const argv[])
 {
        int status;
diff --git a/proc.h b/proc.h
index 9220b2a..6e5f3ac 100644
--- a/proc.h
+++ b/proc.h
@@ -8,5 +8,6 @@ extern int set_proc_prio(int prio);
 extern int set_sched_status(int policy, int priority);
 extern ssize_t proc_get_cmdline(unsigned int pid, char *cmdline, size_t len);
 extern int proc_exec(const char *proc, char *const argv[]);
+extern int proc_find_by_inode(ino_t ino, char *cmdline, size_t len, pid_t 
*pid);
 
 #endif /* PROC_H */
-- 
2.10.2

-- 
You received this message because you are subscribed to the Google Groups 
"netsniff-ng" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to netsniff-ng+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to