summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authorVadim Kochan <vadim4j@gmail.com>2016-12-17 17:57:22 +0200
committerTobias Klauser <tklauser@distanz.ch>2016-12-19 20:30:53 +0100
commit1edfb2409d159f46af385ef36b2017a4102cf67f (patch)
tree6727e6ac1c9d274db2d6fdf07aef94283347688c /proc.c
parent8642322396987a586037942a2e47dee44bb1ed05 (diff)
flowtop: Move & refactor walk_processes() to proc.c
Add proc_find_by_inode() in proc.c which finds pid by inode & gets processe's command line and use it in the flowtop.c instead of walk_processes(). Signed-off-by: Vadim Kochan <vadim4j@gmail.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/proc.c b/proc.c
index 76e3c93..c25396a 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,79 @@ 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 cur_pid = strtoul(name, &end, 10);
+
+ /* not a PID */
+ if (cur_pid == 0 && end == name)
+ continue;
+
+ ret = match_pid_by_inode(cur_pid, ino);
+ if (!ret) {
+ ret = proc_get_cmdline(cur_pid, cmdline, len);
+ if (ret < 0)
+ panic("Failed to get process cmdline: %s\n", strerror(errno));
+
+ closedir(dir);
+ *pid = cur_pid;
+ return ret;
+ }
+ }
+
+ closedir(dir);
+ return -1;
+}
+
int proc_exec(const char *proc, char *const argv[])
{
int status;