aboutsummaryrefslogtreecommitdiffstats
path: root/utils/common/media-info.cpp
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2018-06-23 11:40:44 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2018-06-23 11:40:44 +0200
commit7fba60cae5b9607f90e1b79087e7ab904c3ad38d (patch)
tree84ba01bea878e40e35c34f16883b5ef8cf8c714a /utils/common/media-info.cpp
parent9b69796944cf4082c7c2fce98dc11756c830e127 (diff)
media-info: add new helper functions
Add a helper to obtain the dev_t from a file descriptor: int mi_get_dev_t_from_fd(int fd, dev_t *dev); Add a helper to return the device node path from a dev_t: std::string mi_get_devpath_from_dev_t(dev_t dev); Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Diffstat (limited to 'utils/common/media-info.cpp')
-rw-r--r--utils/common/media-info.cpp58
1 files changed, 54 insertions, 4 deletions
diff --git a/utils/common/media-info.cpp b/utils/common/media-info.cpp
index 52a08cd3..429804e5 100644
--- a/utils/common/media-info.cpp
+++ b/utils/common/media-info.cpp
@@ -146,20 +146,70 @@ static std::string flags2s(unsigned val, const flag_def *def)
return s;
}
-int mi_get_media_fd(int fd)
+int mi_get_dev_t_from_fd(int fd, dev_t *dev)
{
struct stat sb;
- int media_fd = -1;
if (fstat(fd, &sb) == -1) {
fprintf(stderr, "failed to stat file\n");
return -1;
}
+ *dev = sb.st_rdev;
+ return 0;
+}
+
+std::string mi_get_devpath_from_dev_t(dev_t dev)
+{
+ if (!dev)
+ return "";
+
+ std::string media_uevent_path("/sys/dev/char/");
+
+ media_uevent_path += num2s(major(dev), false) + ":" +
+ num2s(minor(dev), false) + "/uevent";
+
+ FILE *uevent_fd = fopen(media_uevent_path.c_str(), "r");
+
+ if (uevent_fd == NULL) {
+ fprintf(stderr, "failed to open %s\n", media_uevent_path.c_str());
+ return "";
+ }
+
+ char *line = NULL;
+ size_t size = 0;
+ std::string devpath;
+
+ for (;;) {
+ ssize_t bytes = getline(&line, &size, uevent_fd);
+
+ if (bytes <= 0)
+ break;
+ line[bytes - 1] = 0;
+ if (memcmp(line, "DEVNAME=", 8) || !line[8])
+ continue;
+ devpath = "/dev/";
+ devpath += line + 8;
+ break;
+ }
+ free(line);
+
+ if (devpath.empty())
+ fprintf(stderr, "failed to find DEVNAME in %s\n", media_uevent_path.c_str());
+ return devpath;
+}
+
+int mi_get_media_fd(int fd)
+{
+ int media_fd = -1;
+ dev_t dev;
+
+ if (mi_get_dev_t_from_fd(fd, &dev) < 0)
+ return -1;
std::string media_path("/sys/dev/char/");
- media_path += num2s(major(sb.st_rdev), false) + ":" +
- num2s(minor(sb.st_rdev), false) + "/device";
+ media_path += num2s(major(dev), false) + ":" +
+ num2s(minor(dev), false) + "/device";
DIR *dp;
struct dirent *ep;

Privacy Policy