[libcamera-devel] [PATCH v3 13/17] libcamera: v4l2_device: Use UniqueFD for a file descriptor

Hirokazu Honda hiroh at chromium.org
Mon Nov 29 14:58:28 CET 2021


Hi Laurent,

On Mon, Nov 29, 2021 at 8:58 AM Laurent Pinchart
<laurent.pinchart at ideasonboard.com> wrote:
>
> From: Hirokazu Honda <hiroh at chromium.org>
>
> Manages a file descriptor owned by V4L2Device for a v4l2 device node
> by UniqueFD.
>
> Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
> Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>

Reviewed-by: Hirokazu Honda <hiroh at chromium.org> if applicable.
> ---
> 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(-)
>
> 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;
>         }
>
> --
> Regards,
>
> Laurent Pinchart
>


More information about the libcamera-devel mailing list