[libcamera-devel] [RFC PATCH 06/10] libcamera: V4L2Device: Use ScopedFD for a file descriptor

Hirokazu Honda hiroh at chromium.org
Thu Apr 15 10:38:39 CEST 2021


V4L2Device owns a file descriptor for a v4l2 device node. It
should be managed by ScopedFD avoid the leakage.

Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
---
 include/libcamera/internal/v4l2_device.h |  9 +++++----
 src/libcamera/v4l2_device.cpp            | 17 +++++++----------
 src/libcamera/v4l2_videodevice.cpp       |  3 ++-
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h
index d006bf68..e0262de0 100644
--- a/include/libcamera/internal/v4l2_device.h
+++ b/include/libcamera/internal/v4l2_device.h
@@ -13,6 +13,7 @@
 
 #include <linux/videodev2.h>
 
+#include <libcamera/scoped_file_descriptor.h>
 #include <libcamera/signal.h>
 
 #include "libcamera/internal/log.h"
@@ -26,7 +27,7 @@ class V4L2Device : protected Loggable
 {
 public:
 	void close();
-	bool isOpen() const { return fd_ != -1; }
+	bool isOpen() const { return fd_.isValid(); }
 
 	const ControlInfoMap &controls() const { return controls_; }
 
@@ -46,11 +47,11 @@ protected:
 	~V4L2Device();
 
 	int open(unsigned int flags);
-	int setFd(int fd);
+	int setFd(ScopedFD fd);
 
 	int ioctl(unsigned long request, void *argp);
 
-	int fd() const { return fd_; }
+	int fd() const { return fd_.get(); }
 
 private:
 	void listControls();
@@ -64,7 +65,7 @@ private:
 	std::vector<std::unique_ptr<V4L2ControlId>> controlIds_;
 	ControlInfoMap controls_;
 	std::string deviceNode_;
-	int fd_;
+	ScopedFD fd_;
 
 	EventNotifier *fdEventNotifier_;
 	bool frameStartEnabled_;
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index decd19ef..4fbb2d60 100644
--- a/src/libcamera/v4l2_device.cpp
+++ b/src/libcamera/v4l2_device.cpp
@@ -53,7 +53,7 @@ LOG_DEFINE_CATEGORY(V4L2)
  * at open() time, and the \a logTag to prefix log messages with.
  */
 V4L2Device::V4L2Device(const std::string &deviceNode)
-	: deviceNode_(deviceNode), fd_(-1), fdEventNotifier_(nullptr),
+	: deviceNode_(deviceNode), fdEventNotifier_(nullptr),
 	  frameStartEnabled_(false)
 {
 }
@@ -89,7 +89,7 @@ int V4L2Device::open(unsigned int flags)
 		return ret;
 	}
 
-	setFd(ret);
+	setFd(ScopedFD(ret));
 
 	listControls();
 
@@ -112,14 +112,14 @@ int V4L2Device::open(unsigned int flags)
  *
  * \return 0 on success or a negative error code otherwise
  */
-int V4L2Device::setFd(int fd)
+int V4L2Device::setFd(ScopedFD fd)
 {
 	if (isOpen())
 		return -EBUSY;
 
-	fd_ = fd;
+	fd_ = std::move(fd);
 
-	fdEventNotifier_ = new EventNotifier(fd_, EventNotifier::Exception);
+	fdEventNotifier_ = new EventNotifier(fd_.get(), EventNotifier::Exception);
 	fdEventNotifier_->activated.connect(this, &V4L2Device::eventAvailable);
 	fdEventNotifier_->setEnabled(false);
 
@@ -138,10 +138,7 @@ void V4L2Device::close()
 
 	delete fdEventNotifier_;
 
-	if (::close(fd_) < 0)
-		LOG(V4L2, Error) << "Failed to close V4L2 device: "
-				 << strerror(errno);
-	fd_ = -1;
+	fd_.reset();
 }
 
 /**
@@ -449,7 +446,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp)
 	 * Printing out an error message is usually better performed
 	 * in the caller, which can provide more context.
 	 */
-	if (::ioctl(fd_, request, argp) < 0)
+	if (::ioctl(fd_.get(), request, argp) < 0)
 		return -errno;
 
 	return 0;
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 12c09dc7..0bf3b5f5 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -22,6 +22,7 @@
 #include <linux/version.h>
 
 #include <libcamera/file_descriptor.h>
+#include <libcamera/scoped_file_descriptor.h>
 
 #include "libcamera/internal/event_notifier.h"
 #include "libcamera/internal/log.h"
@@ -614,7 +615,7 @@ int V4L2VideoDevice::open(int handle, enum v4l2_buf_type type)
 		return ret;
 	}
 
-	ret = V4L2Device::setFd(newFd);
+	ret = V4L2Device::setFd(ScopedFD(newFd));
 	if (ret < 0) {
 		LOG(V4L2, Error) << "Failed to set file handle: "
 				 << strerror(-ret);
-- 
2.31.1.368.gbe11c130af-goog



More information about the libcamera-devel mailing list