From a7eed94df7d91af217623f0f000f437eec8a13d3 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Sat, 21 Aug 2010 10:09:58 +0300 Subject: [PATCH] Factor out all pid handling functions in a separate pidlib.c There will be need to handle pids from other files as well, so separating them all out into one file is needed. Signed-off-by: Timo Kokkonen --- Makefile | 2 +- parse.c | 131 +---------------------------------------------------- pidlib.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ pidlib.h | 13 ++++++ 4 files changed, 150 insertions(+), 131 deletions(-) create mode 100644 pidlib.c create mode 100644 pidlib.h diff --git a/Makefile b/Makefile index 2311e35..b64806e 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ CC=gcc SPARSE=sparse CHECKPATCH=/usr/src/linux/scripts/checkpatch.pl -SCAN_PAGEMAP_OBJS=main.o parse.o bintree.o analyze.o +SCAN_PAGEMAP_OBJS=main.o parse.o bintree.o analyze.o pidlib.o SCAN_PAGEMAP_DEBUG_OBJS= $(patsubst %.o,%-debug.o,$(SCAN_PAGEMAP_OBJS)) scan-pagemap: $(SCAN_PAGEMAP_OBJS) diff --git a/parse.c b/parse.c index 278f17e..6434b72 100644 --- a/parse.c +++ b/parse.c @@ -1,13 +1,11 @@ -#include -#include #include #include #include #include -#include #include "parse.h" #include "pagemap.h" +#include "pidlib.h" static struct maps_list *alloc_maplist(void) { @@ -103,46 +101,6 @@ struct bintree_ops pageframe_ops = { .compare = compare_pageframe, }; -static int read_cmdline(int pid, int tid, char *cmdline, size_t len) -{ - FILE *file; - char path[512]; - int ret; - - snprintf(path, sizeof(path), "/proc/%d/task/%d/cmdline", pid, tid); - file = fopen(path, "rb"); - - if (!file) - return -1; - - ret = fread(cmdline, 1, len, file); - if (ret > 0) - cmdline[ret - 1] = 0; - fclose(file); - - 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 should_scan_process(struct parse_opts *opts, struct process *process) { struct pidlist *pid; @@ -348,93 +306,6 @@ free: return 0; } -static int parse_pid(DIR **dir) -{ - struct dirent *dirent; - int error; - -restart: - dirent = readdir(*dir); - if (!dirent) { - if (errno == 0) { - closedir(*dir); - *dir = NULL; - return 0; - } - error = errno; - printf("Failed to read /proc directory: %s\n", strerror(error)); - return -1; - } - - if (dirent->d_name[0] < '0' || dirent->d_name[0] > '9') - goto restart; - - return atoi(dirent->d_name); -} - -static int opendir_check(DIR **dir, const char *path) -{ - int error; - - if (!*dir) { - *dir = opendir(path); - if (!dir) { - error = errno; - fprintf(stderr, "Failed to open %s directory: %s\n", - path, strerror(error)); - return -1; - } - } - - return 0; -} - -static int get_next_tid(int pid, DIR **dir) -{ - if (*dir == NULL) { - char path[64]; - - snprintf(path, sizeof(path), "/proc/%d/task/", pid); - if (opendir_check(dir, path)) - return -1; - } - - return parse_pid(dir); -} - -static int get_next_pid(DIR **dir) -{ - if (opendir_check(dir, "/proc")) - return -1; - - 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 int read_pageframe_with_threads(int pid, struct pageframe *pageframe, struct process *process_list, diff --git a/pidlib.c b/pidlib.c new file mode 100644 index 0000000..da36035 --- /dev/null +++ b/pidlib.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include + +#include "pidlib.h" + +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 parse_pid(DIR **dir) +{ + struct dirent *dirent; + int error; + +restart: + dirent = readdir(*dir); + if (!dirent) { + if (errno == 0) { + closedir(*dir); + *dir = NULL; + return 0; + } + error = errno; + printf("Failed to read /proc directory: %s\n", strerror(error)); + return -1; + } + + if (dirent->d_name[0] < '0' || dirent->d_name[0] > '9') + goto restart; + + return atoi(dirent->d_name); +} + +static int opendir_check(DIR **dir, const char *path) +{ + int error; + + if (!*dir) { + *dir = opendir(path); + if (!dir) { + error = errno; + fprintf(stderr, "Failed to open %s directory: %s\n", + path, strerror(error)); + return -1; + } + } + + return 0; +} + +int get_next_tid(int pid, DIR **dir) +{ + if (*dir == NULL) { + char path[64]; + + snprintf(path, sizeof(path), "/proc/%d/task/", pid); + if (opendir_check(dir, path)) + return -1; + } + + return parse_pid(dir); +} + +int get_next_pid(DIR **dir) +{ + if (opendir_check(dir, "/proc")) + return -1; + + return parse_pid(dir); +} + +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; +} + +int read_cmdline(int pid, int tid, char *cmdline, size_t len) +{ + FILE *file; + char path[512]; + int ret; + + snprintf(path, sizeof(path), "/proc/%d/task/%d/cmdline", pid, tid); + file = fopen(path, "rb"); + + if (!file) + return -1; + + ret = fread(cmdline, 1, len, file); + if (ret > 0) + cmdline[ret - 1] = 0; + fclose(file); + + return ret > 0 ? 0 : -1; +} + diff --git a/pidlib.h b/pidlib.h new file mode 100644 index 0000000..e095ecb --- /dev/null +++ b/pidlib.h @@ -0,0 +1,13 @@ +#ifndef _PIDLIB_H_ +#define _PIDLIB_H_ + +#include +#include + +char *get_name_by_pid(int pid); +int get_next_tid(int pid, DIR **dir); +int get_next_pid(DIR **dir); +int get_next_pid_by_name(DIR **dir, char *name); +int read_cmdline(int pid, int tid, char *cmdline, size_t len); + +#endif -- 2.44.0