From: <zub...@gm...> - 2014-05-29 14:16:44
|
From: Zubin Mithra <zub...@gm...> * util.c (print_abspath): New function that converts a relative to an absolute path. * util.c (get_tracee_cwd): New function that finds the current working directory of the tracee. * (printpathn): Use print_abspath to print out links if `-yy` flag is used. Signed-off-by: Zubin Mithra <zub...@gm...> --- defs.h | 2 ++ util.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/defs.h b/defs.h index 5381e60..25d845d 100644 --- a/defs.h +++ b/defs.h @@ -631,6 +631,8 @@ extern const char *signame(int); extern void pathtrace_select(const char *); extern int pathtrace_match(struct tcb *); extern int getfdpath(struct tcb *, int, char *, unsigned); +extern int get_tracee_cwd(struct tcb *, char *); +extern bool print_abspath(struct tcb *, char *, int); extern const char *xlookup(const struct xlat *, int); diff --git a/util.c b/util.c index b1f1e90..68af3ae 100644 --- a/util.c +++ b/util.c @@ -593,9 +593,17 @@ printpathn(struct tcb *tcp, long addr, int n) n++; outstr = alloca(4 * n); /* 4*(n-1) + 3 for quotes and NUL */ string_quote(path, outstr, -1, n); - tprints(outstr); - if (!nul_seen) - tprints("..."); + if (show_fd_path == 2) { + /* "..." is printed if the length of current working + directory + length of outstr > 4096 */ + if (print_abspath(tcp, outstr, nul_seen)) + tprints("..."); + } + else { + tprints(outstr); + if (!nul_seen) + tprints("..."); + } } } @@ -1562,3 +1570,60 @@ returns_fd(struct tcb *tcp) return 1; return 0; } + +/* Return the current working directory of the tracee process, + with a trailing slash. */ +int +get_tracee_cwd(struct tcb *tcp, char *cwd) +{ + int link_size = sizeof("/proc/%u/cwd") + sizeof(int) * 3; + char linkpath[link_size]; + ssize_t n; + + snprintf(linkpath, link_size, "/proc/%u/cwd", tcp->pid); + n = readlink(linkpath, cwd, MAXPATHLEN); + + /* If readlink fails, something is abnormal(path > 4096) about + the traced process and its cwd, so return an empty cwd. */ + if (n == -1) + cwd[0] = '\0'; + + if (n >= 0) { + cwd[n] = '/'; + cwd[n+1] = '\0'; + } + return n; +} + +bool +print_abspath(struct tcb *tcp, char *outstr, int nulseen) +{ + char cwd[MAXPATHLEN + 2]; + char quoted_path[MAXPATHLEN+2]; + char *ptr = NULL; + char *abspath = NULL; + char *unquoted_outstr = NULL; + + /* Just print it out if its an absolute path */ + if (outstr[1] == '/') { + tprints(outstr); + return 0; + } + + int len = get_tracee_cwd(tcp, cwd); + if (len == -1) { + /* There was a problem getting the cwd, so we print the + relative path we have */ + tprints(outstr); + if (!nulseen) return 1; + } + + /* If the combined lengths of the absolute path and the + relative paths > 4096, we just print out the cwd, followed by + the relative path, without calling realpath on the combination */ + tprintf("\"%s%s", cwd, outstr+1); + if (strlen(outstr) + strlen(cwd) - /* 2 quotes in outstr */ 2 > MAXPATHLEN) + return 1; + + return 0; +} -- 1.8.4 |