summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/defs.h12
-rw-r--r--src/util.c42
2 files changed, 47 insertions, 7 deletions
diff --git a/src/defs.h b/src/defs.h
index 397237598..eb8675757 100644
--- a/src/defs.h
+++ b/src/defs.h
@@ -658,6 +658,18 @@ static inline int set_tcb_priv_ulong(struct tcb *tcp, unsigned long val)
return set_tcb_priv_data(tcp, (void *) val, 0);
}
+struct finfo {
+ const char *path;
+ enum {
+ FINFO_UNSET,
+ FINFO_DEV_BLK,
+ FINFO_DEV_CHR,
+ } type;
+ struct {
+ unsigned int major, minor;
+ } dev;
+};
+
/**
* @return 0 on success, -1 on error.
*/
diff --git a/src/util.c b/src/util.c
index d76d5887c..1d140fa91 100644
--- a/src/util.c
+++ b/src/util.c
@@ -647,33 +647,61 @@ printsocket(struct tcb *tcp, int fd, const char *path)
return true;
}
-static bool
-printdev(struct tcb *tcp, int fd, const char *path)
+static struct finfo *
+get_finfo_for_dev(const char *path, struct finfo *finfo)
{
strace_stat_t st;
+ finfo->path = path;
+ finfo->type = FINFO_UNSET;
+
if (path[0] != '/')
- return false;
+ return finfo;
if (stat_file(path, &st)) {
debug_func_perror_msg("stat(\"%s\")", path);
- return false;
+ return finfo;
}
switch (st.st_mode & S_IFMT) {
case S_IFBLK:
+ finfo->type = FINFO_DEV_BLK;
+ break;
case S_IFCHR:
+ finfo->type = FINFO_DEV_CHR;
+ break;
+ default:
+ return finfo;
+ }
+
+ finfo->dev.major = major(st.st_rdev);
+ finfo->dev.minor = minor(st.st_rdev);
+
+ return finfo;
+}
+
+static bool
+printdev(struct tcb *tcp, int fd, const char *path)
+{
+ struct finfo finfo_buf;
+ const struct finfo *finfo = get_finfo_for_dev(path, &finfo_buf);
+
+ switch (finfo->type) {
+ case FINFO_DEV_BLK:
+ case FINFO_DEV_CHR:
tprint_associated_info_begin();
- print_quoted_string_ex(path, strlen(path),
+ print_quoted_string_ex(finfo->path, strlen(finfo->path),
QUOTE_OMIT_LEADING_TRAILING_QUOTES,
"<>");
tprint_associated_info_begin();
tprintf_string("%s %u:%u",
- S_ISBLK(st.st_mode)? "block" : "char",
- major(st.st_rdev), minor(st.st_rdev));
+ (finfo->type == FINFO_DEV_BLK)? "block" : "char",
+ finfo->dev.major, finfo->dev.minor);
tprint_associated_info_end();
tprint_associated_info_end();
return true;
+ default:
+ break;
}
return false;