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>
---
 proc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 proc.h |  1 +
 2 files changed, 75 insertions(+)

diff --git a/proc.c b/proc.c
index 76e3c93..8119226 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;
 }
 
+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