diff options
author | Leah Neukirchen <leah@vuxu.org> | 2018-06-19 17:27:22 +0200 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2018-06-19 17:27:22 +0200 |
commit | 2b7b03c9b0c24f81092331907a7e2a741942f214 (patch) | |
tree | 4c79f903949cf3906b2397f6008482a592d73852 | |
parent | 14818ae3e1f41a9266def200dcbd170ea6b51a3e (diff) | |
download | extrace-2b7b03c9b0c24f81092331907a7e2a741942f214.tar.gz extrace-2b7b03c9b0c24f81092331907a7e2a741942f214.tar.xz extrace-2b7b03c9b0c24f81092331907a7e2a741942f214.zip |
pid_depth: parse /proc/$PID/stat without using brittle fscanf
-rw-r--r-- | extrace.c | 29 |
1 files 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 <sys/types.h> #include <sys/wait.h> +#include <errno.h> #include <fcntl.h> #include <limits.h> #include <pwd.h> @@ -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; |