[PATCH] Convert relative to absolute paths in printpathn
zubin.mithra at gmail.com
zubin.mithra at gmail.com
Wed May 28 16:42:41 UTC 2014
From: Zubin Mithra <zubin.mithra at gmail.com>
* 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 <zubin.mithra at gmail.com>
---
defs.h | 2 ++
util.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 89 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..6da6d00 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,79 @@ 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 0;
+ }
+
+ /* 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 */
+ if (strlen(outstr) + strlen(cwd) - /* 2 quotes in outstr */ 2 > MAXPATHLEN) {
+ tprintf("\"%s%s", cwd, outstr+1);
+ return 1;
+ }
+
+ /* Remove quotes at the start and end */
+ unquoted_outstr = outstr + 1;
+ unquoted_outstr[strlen(unquoted_outstr)-1] = '\0';
+
+ strncat(cwd, unquoted_outstr, MAXPATHLEN-len);
+ ptr = realpath(cwd, abspath);
+ if (ptr != NULL) {
+ snprintf(quoted_path, MAXPATHLEN, "\"%s\"", ptr);
+ tprints(quoted_path);
+ free(ptr);
+ return 0;
+ }
+ /* realpath failed for some reason, so we print the
+ relative path that we have */
+ else {
+ tprintf("\"%s%s", cwd, outstr+1);
+ return 0;
+ }
+ return 0;
+}
--
1.8.4
More information about the Strace-devel
mailing list