aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil-cisco@xs4all.nl>2018-12-10 10:50:02 +0100
committerHans Verkuil <hverkuil-cisco@xs4all.nl>2018-12-10 10:51:10 +0100
commit74d4691313a485439e45dcd0881c91ccdd40ea9b (patch)
treec4874946d5eed59621b90c418a5c3b12cc6fc49b
parent00228fe5b596bef81870765c4e27258aeec2d72f (diff)
v4l2-compliance: add filehandles class
Add a simple class to store filehandles. The destructor will close all pending filehandles on error. This ensures that when working with requests no request or media filehandles remain open after a test fails. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
-rw-r--r--utils/v4l2-compliance/v4l2-compliance.h28
-rw-r--r--utils/v4l2-compliance/v4l2-test-buffers.cpp24
2 files changed, 42 insertions, 10 deletions
diff --git a/utils/v4l2-compliance/v4l2-compliance.h b/utils/v4l2-compliance/v4l2-compliance.h
index b6d3e72c..eb051adc 100644
--- a/utils/v4l2-compliance/v4l2-compliance.h
+++ b/utils/v4l2-compliance/v4l2-compliance.h
@@ -140,6 +140,34 @@ struct node : public base_node, public cv4l_fd {
}
};
+class filehandles {
+public:
+ filehandles() {}
+ ~filehandles()
+ {
+ for (auto iter = fhs.begin(); iter != fhs.end(); ++iter)
+ close(*iter);
+ }
+
+ int add(int fd)
+ {
+ if (fd >= 0)
+ fhs.insert(fd);
+ return fd;
+ }
+
+ void del(int fd)
+ {
+ if (fd >= 0) {
+ fhs.erase(fd);
+ close(fd);
+ }
+ }
+
+private:
+ std::set<int> fhs;
+};
+
#define info(fmt, args...) \
do { \
if (show_info) \
diff --git a/utils/v4l2-compliance/v4l2-test-buffers.cpp b/utils/v4l2-compliance/v4l2-test-buffers.cpp
index 24b74bda..70e9301d 100644
--- a/utils/v4l2-compliance/v4l2-test-buffers.cpp
+++ b/utils/v4l2-compliance/v4l2-test-buffers.cpp
@@ -1467,7 +1467,8 @@ int testDmaBuf(struct node *expbuf_node, struct node *node, unsigned frame_count
int testRequests(struct node *node, bool test_streaming)
{
- int media_fd = mi_get_media_fd(node->g_fd(), node->bus_info);
+ filehandles fhs;
+ int media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info));
int req_fd;
qctrl_map::iterator iter;
struct test_query_ext_ctrl valid_qctrl;
@@ -1517,6 +1518,7 @@ int testRequests(struct node *node, bool test_streaming)
fail_on_test(doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls) != EINVAL);
}
fail_on_test(doioctl_fd(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd));
+ fhs.add(req_fd);
fail_on_test(req_fd < 0);
if (have_controls) {
ctrls.request_fd = req_fd;
@@ -1524,17 +1526,18 @@ int testRequests(struct node *node, bool test_streaming)
}
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_QUEUE, 0) != ENOENT);
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_REINIT, 0));
- close(media_fd);
+ fhs.del(media_fd);
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_QUEUE, 0) != ENOENT);
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_REINIT, 0));
- close(req_fd);
+ fhs.del(req_fd);
if (have_controls)
fail_on_test(doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls) != EINVAL);
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_QUEUE, 0) != EBADF);
fail_on_test(doioctl_fd(req_fd, MEDIA_REQUEST_IOC_REINIT, 0) != EBADF);
- media_fd = mi_get_media_fd(node->g_fd(), node->bus_info);
+ media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info));
fail_on_test(doioctl_fd(media_fd, MEDIA_IOC_REQUEST_ALLOC, &req_fd));
+ fhs.add(req_fd);
ctrls.count = 1;
ctrls.controls = &ctrl;
if (have_controls) {
@@ -1558,8 +1561,8 @@ int testRequests(struct node *node, bool test_streaming)
fail_on_test(doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls) != EACCES);
}
ctrl.id = valid_qctrl.id;
- close(req_fd);
- close(media_fd);
+ fhs.del(req_fd);
+ fhs.del(media_fd);
node->reopen();
int type = node->g_type();
@@ -1593,14 +1596,15 @@ int testRequests(struct node *node, bool test_streaming)
unsigned num_requests = 2 * num_bufs;
last_seq.init();
- media_fd = mi_get_media_fd(node->g_fd(), node->bus_info);
+ media_fd = fhs.add(mi_get_media_fd(node->g_fd(), node->bus_info));
for (unsigned i = 0; i < num_requests; i++) {
fail_on_test(doioctl_fd(media_fd, MEDIA_IOC_REQUEST_ALLOC, &buf_req_fds[i]));
+ fhs.add(buf_req_fds[i]);
fail_on_test(buf_req_fds[i] < 0);
fail_on_test(!doioctl_fd(buf_req_fds[i], MEDIA_REQUEST_IOC_QUEUE, 0));
}
- close(media_fd);
+ fhs.del(media_fd);
buffer buf(q);
@@ -1750,13 +1754,13 @@ int testRequests(struct node *node, bool test_streaming)
fail_on_test(buf.querybuf(node, i));
fail_on_test(buf.g_flags() & V4L2_BUF_FLAG_REQUEST_FD);
fail_on_test(buf.g_request_fd());
- close(buf_req_fds[i]);
+ fhs.del(buf_req_fds[i]);
ctrls.request_fd = buf_req_fds[i];
fail_on_test(!doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls));
}
for (unsigned i = 0; i < num_requests; i++)
if (buf_req_fds[i] >= 0)
- close(buf_req_fds[i]);
+ fhs.del(buf_req_fds[i]);
ctrls.which = 0;
fail_on_test(doioctl(node, VIDIOC_G_EXT_CTRLS, &ctrls));

Privacy Policy