diff options
| -rw-r--r-- | flowtop.c | 78 | ||||
| -rw-r--r-- | proc.c | 75 | ||||
| -rw-r--r-- | proc.h | 1 | 
3 files changed, 85 insertions, 69 deletions
| @@ -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) @@ -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; @@ -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 */ | 
