libcamera: v4l2_device: Use UniqueFD for a file descriptor
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>
This commit is contained in:
parent
91dcd719d7
commit
cfe4f9622e
3 changed files with 21 additions and 27 deletions
|
@ -16,6 +16,7 @@
|
||||||
#include <libcamera/base/log.h>
|
#include <libcamera/base/log.h>
|
||||||
#include <libcamera/base/signal.h>
|
#include <libcamera/base/signal.h>
|
||||||
#include <libcamera/base/span.h>
|
#include <libcamera/base/span.h>
|
||||||
|
#include <libcamera/base/unique_fd.h>
|
||||||
|
|
||||||
#include <libcamera/controls.h>
|
#include <libcamera/controls.h>
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ class V4L2Device : protected Loggable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void close();
|
void close();
|
||||||
bool isOpen() const { return fd_ != -1; }
|
bool isOpen() const { return fd_.isValid(); }
|
||||||
|
|
||||||
const ControlInfoMap &controls() const { return controls_; }
|
const ControlInfoMap &controls() const { return controls_; }
|
||||||
|
|
||||||
|
@ -49,11 +50,11 @@ protected:
|
||||||
~V4L2Device();
|
~V4L2Device();
|
||||||
|
|
||||||
int open(unsigned int flags);
|
int open(unsigned int flags);
|
||||||
int setFd(int fd);
|
int setFd(UniqueFD fd);
|
||||||
|
|
||||||
int ioctl(unsigned long request, void *argp);
|
int ioctl(unsigned long request, void *argp);
|
||||||
|
|
||||||
int fd() const { return fd_; }
|
int fd() const { return fd_.get(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ControlType v4l2CtrlType(uint32_t ctrlType);
|
static ControlType v4l2CtrlType(uint32_t ctrlType);
|
||||||
|
@ -72,7 +73,7 @@ private:
|
||||||
ControlIdMap controlIdMap_;
|
ControlIdMap controlIdMap_;
|
||||||
ControlInfoMap controls_;
|
ControlInfoMap controls_;
|
||||||
std::string deviceNode_;
|
std::string deviceNode_;
|
||||||
int fd_;
|
UniqueFD fd_;
|
||||||
|
|
||||||
EventNotifier *fdEventNotifier_;
|
EventNotifier *fdEventNotifier_;
|
||||||
bool frameStartEnabled_;
|
bool frameStartEnabled_;
|
||||||
|
|
|
@ -53,7 +53,7 @@ LOG_DEFINE_CATEGORY(V4L2)
|
||||||
* at open() time, and the \a logTag to prefix log messages with.
|
* at open() time, and the \a logTag to prefix log messages with.
|
||||||
*/
|
*/
|
||||||
V4L2Device::V4L2Device(const std::string &deviceNode)
|
V4L2Device::V4L2Device(const std::string &deviceNode)
|
||||||
: deviceNode_(deviceNode), fd_(-1), fdEventNotifier_(nullptr),
|
: deviceNode_(deviceNode), fdEventNotifier_(nullptr),
|
||||||
frameStartEnabled_(false)
|
frameStartEnabled_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -81,15 +81,15 @@ int V4L2Device::open(unsigned int flags)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = syscall(SYS_openat, AT_FDCWD, deviceNode_.c_str(), flags);
|
UniqueFD fd(syscall(SYS_openat, AT_FDCWD, deviceNode_.c_str(), flags));
|
||||||
if (ret < 0) {
|
if (!fd.isValid()) {
|
||||||
ret = -errno;
|
int ret = -errno;
|
||||||
LOG(V4L2, Error) << "Failed to open V4L2 device: "
|
LOG(V4L2, Error) << "Failed to open V4L2 device: "
|
||||||
<< strerror(-ret);
|
<< strerror(-ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
setFd(ret);
|
setFd(std::move(fd));
|
||||||
|
|
||||||
listControls();
|
listControls();
|
||||||
|
|
||||||
|
@ -112,14 +112,14 @@ int V4L2Device::open(unsigned int flags)
|
||||||
*
|
*
|
||||||
* \return 0 on success or a negative error code otherwise
|
* \return 0 on success or a negative error code otherwise
|
||||||
*/
|
*/
|
||||||
int V4L2Device::setFd(int fd)
|
int V4L2Device::setFd(UniqueFD fd)
|
||||||
{
|
{
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
return -EBUSY;
|
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_->activated.connect(this, &V4L2Device::eventAvailable);
|
||||||
fdEventNotifier_->setEnabled(false);
|
fdEventNotifier_->setEnabled(false);
|
||||||
|
|
||||||
|
@ -138,10 +138,7 @@ void V4L2Device::close()
|
||||||
|
|
||||||
delete fdEventNotifier_;
|
delete fdEventNotifier_;
|
||||||
|
|
||||||
if (::close(fd_) < 0)
|
fd_.reset();
|
||||||
LOG(V4L2, Error) << "Failed to close V4L2 device: "
|
|
||||||
<< strerror(errno);
|
|
||||||
fd_ = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -440,7 +437,7 @@ int V4L2Device::ioctl(unsigned long request, void *argp)
|
||||||
* Printing out an error message is usually better performed
|
* Printing out an error message is usually better performed
|
||||||
* in the caller, which can provide more context.
|
* in the caller, which can provide more context.
|
||||||
*/
|
*/
|
||||||
if (::ioctl(fd_, request, argp) < 0)
|
if (::ioctl(fd_.get(), request, argp) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <libcamera/base/event_notifier.h>
|
#include <libcamera/base/event_notifier.h>
|
||||||
#include <libcamera/base/file_descriptor.h>
|
#include <libcamera/base/file_descriptor.h>
|
||||||
#include <libcamera/base/log.h>
|
#include <libcamera/base/log.h>
|
||||||
|
#include <libcamera/base/unique_fd.h>
|
||||||
#include <libcamera/base/utils.h>
|
#include <libcamera/base/utils.h>
|
||||||
|
|
||||||
#include "libcamera/internal/formats.h"
|
#include "libcamera/internal/formats.h"
|
||||||
|
@ -620,22 +621,17 @@ int V4L2VideoDevice::open()
|
||||||
*/
|
*/
|
||||||
int V4L2VideoDevice::open(int handle, enum v4l2_buf_type type)
|
int V4L2VideoDevice::open(int handle, enum v4l2_buf_type type)
|
||||||
{
|
{
|
||||||
int ret;
|
UniqueFD newFd(dup(handle));
|
||||||
int newFd;
|
if (!newFd.isValid()) {
|
||||||
|
|
||||||
newFd = dup(handle);
|
|
||||||
if (newFd < 0) {
|
|
||||||
ret = -errno;
|
|
||||||
LOG(V4L2, Error) << "Failed to duplicate file handle: "
|
LOG(V4L2, Error) << "Failed to duplicate file handle: "
|
||||||
<< strerror(-ret);
|
<< strerror(errno);
|
||||||
return ret;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = V4L2Device::setFd(newFd);
|
int ret = V4L2Device::setFd(std::move(newFd));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG(V4L2, Error) << "Failed to set file handle: "
|
LOG(V4L2, Error) << "Failed to set file handle: "
|
||||||
<< strerror(-ret);
|
<< strerror(-ret);
|
||||||
::close(newFd);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue