diff options
author | Chris West (Faux) <git@goeswhere.com> | 2018-02-08 10:40:08 +0000 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2018-02-08 14:57:55 +0100 |
commit | 7ff44f4b90a718195d4521b3caa48eeeb7699fbf (patch) | |
tree | 38d9f581282ddc57d3082f6d3c5aa0bfc81c4b11 | |
parent | 4fb94664c8534663a6d3dd575e6645881ea05a43 (diff) | |
download | extrace-7ff44f4b90a718195d4521b3caa48eeeb7699fbf.tar.gz extrace-7ff44f4b90a718195d4521b3caa48eeeb7699fbf.tar.xz extrace-7ff44f4b90a718195d4521b3caa48eeeb7699fbf.zip |
extrace: use openat() for speedup
This reduces the timeframe where the inherently racy access to /proc is done, and removes some unnecessary snprintf. Closes: #2 [via git-merge-pr]
-rw-r--r-- | extrace.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/extrace.c b/extrace.c index 30a8c43..25d16ac 100644 --- a/extrace.c +++ b/extrace.c @@ -107,6 +107,13 @@ struct { } pid_db[PID_DB_SIZE]; static int +open_proc_dir(pid_t pid) { + char name[48]; + snprintf(name, sizeof name, "/proc/%d", pid); + return open(name, O_DIRECTORY); +} + +static int pid_depth(pid_t pid) { pid_t ppid = 0; @@ -231,14 +238,14 @@ print_shquoted(const char *s) } static void -print_env(pid_t pid) +print_env(int proc_dir_fd) { - char name[PATH_MAX]; + int fd; FILE *env; fprintf(output, " "); - snprintf(name, sizeof name, "/proc/%d/environ", pid); - if ((env = fopen(name, "r"))) { + fd = openat(proc_dir_fd, "environ", O_RDONLY); + if (fd >= 0 && (env = fdopen(fd, "r"))) { char *line = 0, *eq = 0; size_t linelen = 0; while (getdelim(&line, &linelen, '\0', env) >= 0) { @@ -264,7 +271,7 @@ print_env(pid_t pid) static void handle_msg(struct cn_msg *cn_hdr) { - char cmdline[CMDLINE_MAX], name[PATH_MAX]; + char cmdline[CMDLINE_MAX]; char exe[PATH_MAX]; char cwd[PATH_MAX]; char *argvrest; @@ -275,10 +282,17 @@ handle_msg(struct cn_msg *cn_hdr) if (ev->what == PROC_EVENT_EXEC) { pid_t pid = ev->event_data.exec.process_pid; int i = 0; + int proc_dir_fd = open_proc_dir(pid); + if (proc_dir_fd < 0) { + /* TODO: warn we dropped something? */ + return; + } d = pid_depth(pid); - if (d < 0) + if (d < 0) { + close(proc_dir_fd); return; + } if (show_exit || !flat) { for (i = 0; i < PID_DB_SIZE - 1; i++) @@ -293,11 +307,9 @@ handle_msg(struct cn_msg *cn_hdr) pid_db[i].start = ev->timestamp_ns; } - snprintf(name, sizeof name, "/proc/%d/cmdline", pid); - memset(&cmdline, 0, sizeof cmdline); - fd = open(name, O_RDONLY); - if (fd > 0) { + fd = openat(proc_dir_fd, "cmdline", O_RDONLY); + if (fd >= 0) { r = read(fd, cmdline, sizeof cmdline); close(fd); @@ -305,8 +317,7 @@ handle_msg(struct cn_msg *cn_hdr) cmdline[r] = 0; if (full_path) { - snprintf(name, sizeof name, "/proc/%d/exe", pid); - r2 = readlink(name, exe, sizeof exe); + r2 = readlinkat(proc_dir_fd, "exe", exe, sizeof exe); if (r2 > 0) exe[r2] = 0; } @@ -315,8 +326,7 @@ handle_msg(struct cn_msg *cn_hdr) } if (show_cwd) { - snprintf(name, sizeof name, "/proc/%d/cwd", pid); - r3 = readlink(name, cwd, sizeof cwd); + r3 = readlinkat(proc_dir_fd, "cwd", cwd, sizeof cwd); if (r3 > 0) cwd[r3] = 0; } @@ -351,9 +361,10 @@ handle_msg(struct cn_msg *cn_hdr) if (r == sizeof cmdline) fprintf(output, "... <truncated>"); - if (show_env) { - print_env(pid); - } + if (show_env) + print_env(proc_dir_fd); + + close(proc_dir_fd); fprintf(output, "\n"); fflush(output); |