From 2b7b03c9b0c24f81092331907a7e2a741942f214 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Tue, 19 Jun 2018 17:27:22 +0200 Subject: pid_depth: parse /proc/$PID/stat without using brittle fscanf --- extrace.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/extrace.c b/extrace.c index b7eb37e..24c5d84 100644 --- a/extrace.c +++ b/extrace.c @@ -61,6 +61,7 @@ #include #include +#include #include #include #include @@ -121,17 +122,31 @@ static int pid_depth(pid_t pid) { pid_t ppid = 0; - FILE *f; char name[PATH_MAX]; - int d, i; + char buf[2048]; + char *s; + int fd, d, i; snprintf(name, sizeof name, "/proc/%d/stat", pid); - if ((f = fopen(name, "r"))) { - if (fscanf(f, "%*d (%*[^)]) %*c %d", &ppid) < 0) - ppid = 0; - fclose(f); - } + if ((fd = open(name, O_RDONLY)) < 0) + return 0; + if (read(fd, buf, sizeof buf) <= 0) + return 0; + close(fd); + + s = strrchr(buf, ')'); /* find end of COMM (recommended way) */ + if (!s) + return 0; + while (*++s == ' ') + ; + /* skip over STATE */ + while (*++s == ' ') + ; + errno = 0; + ppid = strtol(s, 0, 10); /* parse PPID */ + if (errno != 0) + return 0; if (ppid == parent) return 0; -- cgit 1.4.1