[libcamera-devel,v4,14/22] libcamera: v4l2_device: Use UniqueFD for a file descriptor
diff mbox series

Message ID 20211130033820.18235-15-laurent.pinchart@ideasonboard.com
State Accepted
Headers show
Series
  • libcamera: Introduce UniqueFD
Related show

Commit Message

Laurent Pinchart Nov. 30, 2021, 3:38 a.m. UTC
From: Hirokazu Honda <hiroh@chromium.org>

Manages a file descriptor owned by V4L2Device for a v4l2 device node
by UniqueFD.

Signed-off-by: Hirokazu Honda <hiroh@chromium.org>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Hirokazu Honda <hiroh@chromium.org>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
---
Changes since v2:

- Fix errno handling
---
 include/libcamera/internal/v4l2_device.h |  9 +++++----
 src/libcamera/v4l2_device.cpp            | 23 ++++++++++-------------
 src/libcamera/v4l2_videodevice.cpp       | 16 ++++++----------
 3 files changed, 21 insertions(+), 27 deletions(-)

Patch
diff mbox series

diff --git a/include/libcamera/internal/v4l2_device.h b/include/libcamera/internal/v4l2_device.h
index 7816a290141d..8886b750ae29 100644
--- a/include/libcamera/internal/v4l2_device.h
+++ b/include/libcamera/internal/v4l2_device.h
@@ -16,6 +16,7 @@ 
 #include <libcamera/base/log.h>
 #include <libcamera/base/signal.h>
 #include <libcamera/base/span.h>
+#include <libcamera/base/unique_fd.h>
 
 #include <libcamera/controls.h>
 
@@ -27,7 +28,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_; }
 
@@ -49,11 +50,11 @@  protected:
 	~V4L2Device();
 
 	int open(unsigned int flags);
-	int setFd(int fd);
+	int setFd(UniqueFD fd);
 
 	int ioctl(unsigned long request, void *argp);
 
-	int fd() const { return fd_; }
+	int fd() const { return fd_.get(); }
 
 private:
 	static ControlType v4l2CtrlType(uint32_t ctrlType);
@@ -72,7 +73,7 @@  private:
 	ControlIdMap controlIdMap_;
 	ControlInfoMap controls_;
 	std::string deviceNode_;
-	int fd_;
+	UniqueFD fd_;
 
 	EventNotifier *fdEventNotifier_;
 	bool frameStartEnabled_;
diff --git a/src/libcamera/v4l2_device.cpp b/src/libcamera/v4l2_device.cpp
index 9c783c9cbed1..39f360091f64 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)
 {
 }
@@ -81,15 +81,15 @@  int V4L2Device::open(unsigned int flags)
 		return -EBUSY;
 	}
 
-	int ret = syscall(SYS_openat, AT_FDCWD, deviceNode_.c_str(), flags);
-	if (ret < 0) {
-		ret = -errno;
+	UniqueFD fd(syscall(SYS_openat, AT_FDCWD, deviceNode_.c_str(), flags));
+	if (!fd.isValid()) {
+		int ret = -errno;
 		LOG(V4L2, Error) << "Failed to open V4L2 device: "
 				 << strerror(-ret);
 		return ret;
 	}
 
-	setFd(ret);
+	setFd(std::move(fd));
 
 	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(UniqueFD 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();
 }
 
 /**
@@ -440,7 +437,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 0a85bcf6b3ff..c95626d33cc3 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -24,6 +24,7 @@ 
 #include <libcamera/base/event_notifier.h>
 #include <libcamera/base/file_descriptor.h>
 #include <libcamera/base/log.h>
+#include <libcamera/base/unique_fd.h>
 #include <libcamera/base/utils.h>
 
 #include "libcamera/internal/formats.h"
@@ -620,22 +621,17 @@  int V4L2VideoDevice::open()
  */
 int V4L2VideoDevice::open(int handle, enum v4l2_buf_type type)
 {
-	int ret;
-	int newFd;
-
-	newFd = dup(handle);
-	if (newFd < 0) {
-		ret = -errno;
+	UniqueFD newFd(dup(handle));
+	if (!newFd.isValid()) {
 		LOG(V4L2, Error) << "Failed to duplicate file handle: "
-				 << strerror(-ret);
-		return ret;
+				 << strerror(errno);
+		return -errno;
 	}
 
-	ret = V4L2Device::setFd(newFd);
+	int ret = V4L2Device::setFd(std::move(newFd));
 	if (ret < 0) {
 		LOG(V4L2, Error) << "Failed to set file handle: "
 				 << strerror(-ret);
-		::close(newFd);
 		return ret;
 	}