summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasatake YAMATO <yamato@redhat.com>2022-03-11 16:47:17 +0900
committerDmitry V. Levin <ldv@strace.io>2023-02-19 08:00:00 +0000
commit0958b5fcd336ca7b5a8da957df0fcb7f8526ff17 (patch)
tree1f3468da910a84eac6a7bcb0c1aba7c0b11ca632
parent9276a226b1b431acc96c8bd3312a69462d8d8817 (diff)
downloadstrace-0958b5fcd336ca7b5a8da957df0fcb7f8526ff17.tar.gz
util: introduce get_finfo_for_dev function
printdev() function does two things: it first obtains the information about the given fd and then prints it. Introduce get_finfo_for_dev() to implement the first part of printdev(). struct finfo is a new data structure for keeping information passed from get_finfo_for_dev() to printdev(). * src/defs.h (struct finfo): New data structure. * src/utils.c (get_finfo_for_dev): New function derived from printdev. (printdev): Use it. Signed-off-by: Masatake YAMATO <yamato@redhat.com> Signed-off-by: Dmitry V. Levin <ldv@strace.io>
-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;