[{"id":3397,"web_url":"https://patchwork.libcamera.org/comment/3397/","msgid":"<20200110225549.GA4859@pendragon.ideasonboard.com>","date":"2020-01-10T22:55:49","subject":"Re: [libcamera-devel] [PATCH v3 01/33] libcamera: Add\n\tFileDescriptor to help pass numerical fds around","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nThank you for the patch.\n\nOn Fri, Jan 10, 2020 at 08:37:36PM +0100, Niklas Söderlund wrote:\n> Add a helper to make it easier to pass file descriptors around. The\n> helper class duplicates the fd which decouples it from the original fd\n> which could be closed by its owner while the new FileDescriptor remains\n> valid.\n\nThe documentation is now out of sync with the code. I'll provide an\nupdated version of this patch.\n\n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> ---\n>  include/libcamera/file_descriptor.h |  46 ++++++++\n>  include/libcamera/meson.build       |   1 +\n>  src/libcamera/file_descriptor.cpp   | 170 ++++++++++++++++++++++++++++\n>  src/libcamera/meson.build           |   1 +\n>  4 files changed, 218 insertions(+)\n>  create mode 100644 include/libcamera/file_descriptor.h\n>  create mode 100644 src/libcamera/file_descriptor.cpp\n> \n> diff --git a/include/libcamera/file_descriptor.h b/include/libcamera/file_descriptor.h\n> new file mode 100644\n> index 0000000000000000..f08c105998cc7559\n> --- /dev/null\n> +++ b/include/libcamera/file_descriptor.h\n> @@ -0,0 +1,46 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2019, Google Inc.\n> + *\n> + * file_descriptor.h - File descriptor wrapper\n> + */\n> +#ifndef __LIBCAMERA_FILE_DESCRIPTOR_H__\n> +#define __LIBCAMERA_FILE_DESCRIPTOR_H__\n> +\n> +#include <memory>\n> +\n> +namespace libcamera {\n> +\n> +class FileDescriptor final\n> +{\n> +public:\n> +\texplicit FileDescriptor(int fd = -1);\n> +\tFileDescriptor(const FileDescriptor &other);\n> +\tFileDescriptor(FileDescriptor &&other);\n> +\t~FileDescriptor();\n> +\n> +\tFileDescriptor &operator=(const FileDescriptor &other);\n> +\tFileDescriptor &operator=(FileDescriptor &&other);\n> +\n> +\tint fd() const { return fd_ ? fd_->fd() : -1; }\n> +\tFileDescriptor dup() const;\n\nDo you think dup() is a good name, or should this be called duplicate()\n? Or clone() ?\n\n> +\n> +private:\n> +\tclass Storage\n\nI think we need a better name (I know, I picked this one :-)) in order\nto reference this from the documentation. Do you think FD would be a\ngood class name ? Or Descriptor ? Or something else ?\n\n> +\t{\n> +\tpublic:\n> +\t\tStorage(int fd);\n> +\t\t~Storage();\n> +\n> +\t\tint fd() const { return fd_; }\n> +\n> +\tprivate:\n> +\t\tint fd_;\n> +\t};\n> +\n> +\tstd::shared_ptr<Storage> fd_;\n> +};\n> +\n> +} /* namespace libcamera */\n> +\n> +#endif /* __LIBCAMERA_FILE_DESCRIPTOR_H__ */\n> diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> index 99abf06099407c1f..543e6773cc5158a0 100644\n> --- a/include/libcamera/meson.build\n> +++ b/include/libcamera/meson.build\n> @@ -6,6 +6,7 @@ libcamera_api = files([\n>      'controls.h',\n>      'event_dispatcher.h',\n>      'event_notifier.h',\n> +    'file_descriptor.h',\n>      'geometry.h',\n>      'logging.h',\n>      'object.h',\n> diff --git a/src/libcamera/file_descriptor.cpp b/src/libcamera/file_descriptor.cpp\n> new file mode 100644\n> index 0000000000000000..2e531f40696be16c\n> --- /dev/null\n> +++ b/src/libcamera/file_descriptor.cpp\n> @@ -0,0 +1,170 @@\n> +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> +/*\n> + * Copyright (C) 2019, Google Inc.\n> + *\n> + * file_descriptor.cpp - File descriptor wrapper\n> + */\n> +\n> +#include <libcamera/file_descriptor.h>\n> +\n> +#include <string.h>\n> +#include <unistd.h>\n> +#include <utility>\n> +\n> +#include \"log.h\"\n> +\n> +/**\n> + * \\file file_descriptor.h\n> + * \\brief File descriptor wrapper\n> + */\n> +\n> +namespace libcamera {\n> +\n> +LOG_DEFINE_CATEGORY(FileDescriptor)\n> +\n> +/**\n> + * \\class FileDescriptor\n> + * \\brief RAII-style wrapper for file descriptors\n> + *\n> + * The FileDescriptor class wraps a file descriptor (expressed as a signed\n> + * integer) to provide an RAII-style mechanism for owning the file descriptor.\n> + * When constructed, the FileDescriptor instance duplicates a given file\n> + * descriptor and takes ownership of the duplicate as a resource. The copy\n> + * constructor and assignment operator duplicate the file descriptor, while the\n> + * move versions of those methods move the resource and make the original\n> + * FileDescriptor invalid. When the FileDescriptor is deleted, it closes the\n> + * file descriptor it owns, if any.\n> + */\n> +\n> +/**\n> + * \\brief Create a FileDescriptor wrapping a copy of a given \\a fd\n> + * \\param[in] fd File descriptor\n> + *\n> + * Construct a FileDescriptor from a numerical file descriptor duplicates the\n> + * \\a fd and takes ownership of the copy. The original \\a fd is left untouched,\n> + * and the caller is responsible for closing it when appropriate. The duplicated\n> + * file descriptor will be closed automatically when the FileDescriptor instance\n> + * is destroyed.\n> + */\n> +FileDescriptor::FileDescriptor(int fd)\n> +{\n> +\tfd_ = std::make_shared<Storage>(fd);\n> +}\n> +\n> +/**\n> + * \\brief Copy constructor, create a FileDescriptor from a copy of \\a other\n> + * \\param[in] other The other FileDescriptor\n> + *\n> + * Construct a FileDescriptor from another FileDescriptor duplicates the\n> + * wrapped numerical file descriptor and takes ownership of the copy. The\n> + * original FileDescriptor is left untouched, and the caller is responsible for\n> + * closing it when appropriate. The duplicated file descriptor will be closed\n> + * automatically when this FileDescriptor instance is destroyed.\n> + */\n> +FileDescriptor::FileDescriptor(const FileDescriptor &other)\n> +\t: fd_(other.fd_)\n> +{\n> +}\n> +\n> +/**\n> + * \\brief Move constructor, create a FileDescriptor by taking over \\a other\n> + * \\param[in] other The other FileDescriptor\n> + *\n> + * Construct a FileDescriptor by taking over a wrapped numerical file\n> + * descriptor and taking ownership of it. The \\a other FileDescriptor is\n> + * invalidated and set to -1. The taken over file descriptor will be closed\n> + * automatically when this FileDescriptor instance is destroyed.\n> + */\n> +FileDescriptor::FileDescriptor(FileDescriptor &&other)\n> +\t: fd_(std::move(other.fd_))\n> +{\n> +}\n> +\n> +/**\n> + * \\brief Destroy the managed file descriptor\n> + *\n> + * If the managed file descriptor, as returned by fd(), is not equal to -1, the\n> + * file descriptor is closed.\n> + */\n> +FileDescriptor::~FileDescriptor()\n> +{\n> +}\n> +\n> +/**\n> + * \\brief Copy assignment operator, replace the wrapped file descriptor with a\n> + * duplicate from \\a other\n> + * \\param[in] other The other FileDescriptor\n> + *\n> + * Close the wrapped file descriptor (if any) and duplicate the file descriptor\n> + * from \\a other. The \\a other FileDescriptor is left untouched, and the caller\n> + * is responsible for destroying it when appropriate. The duplicated file\n> + * descriptor will be closed automatically when this FileDescriptor instance is\n> + * destroyed.\n> + *\n> + * \\return A reference to this FileDescriptor\n> + */\n> +FileDescriptor &FileDescriptor::operator=(const FileDescriptor &other)\n> +{\n> +\tfd_ = other.fd_;\n> +\n> +\treturn *this;\n> +}\n> +\n> +/**\n> + * \\brief Move assignment operator, replace the wrapped file descriptor by\n> + * taking over \\a other\n> + * \\param[in] other The other FileDescriptor\n> + *\n> + * Close the wrapped file descriptor (if any) and take over the file descriptor\n> + * from \\a other. The \\a other FileDescriptor is invalidated and set to -1. The\n> + * taken over file descriptor will be closed automatically when this\n> + * FileDescriptor instance is destroyed.\n> + *\n> + * \\return A reference to this FileDescriptor\n> + */\n> +FileDescriptor &FileDescriptor::operator=(FileDescriptor &&other)\n> +{\n> +\tfd_ = std::move(other.fd_);\n> +\n> +\treturn *this;\n> +}\n> +\n> +/**\n> + * \\fn FileDescriptor::fd()\n> + * \\brief Retrieve the numerical file descriptor\n> + * \\return The numerical file descriptor, which may be -1 if the FileDescriptor\n> + * instance doesn't own a file descriptor\n> + */\n> +\n> +/**\n> + * \\brief Duplicate a FileDescriptor\n> + * \\return A new FileDescriptor instance wrapping a duplicate of the original\n> + * file descriptor\n> + */\n> +FileDescriptor FileDescriptor::dup() const\n> +{\n> +\treturn FileDescriptor(fd_ ? fd_->fd() : -1);\n> +}\n> +\n> +FileDescriptor::Storage::Storage(int fd)\n> +\t: fd_(-1)\n> +{\n> +\tif (fd < 0)\n> +\t\treturn;\n> +\n> +\t/* Failing to dup() a fd should not happen and is fatal. */\n> +\tfd_ = ::dup(fd);\n> +\tif (fd_ == -1) {\n> +\t\tint ret = -errno;\n> +\t\tLOG(FileDescriptor, Fatal)\n> +\t\t\t<< \"Failed to dup() fd: \" << strerror(-ret);\n> +\t}\n> +}\n> +\n> +FileDescriptor::Storage::~Storage()\n> +{\n> +\tif (fd_ != -1)\n> +\t\tclose(fd_);\n> +}\n> +\n> +} /* namespace libcamera */\n> diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> index c4f965bd7413b37e..722c5bc15afe52ef 100644\n> --- a/src/libcamera/meson.build\n> +++ b/src/libcamera/meson.build\n> @@ -14,6 +14,7 @@ libcamera_sources = files([\n>      'event_dispatcher.cpp',\n>      'event_dispatcher_poll.cpp',\n>      'event_notifier.cpp',\n> +    'file_descriptor.cpp',\n>      'formats.cpp',\n>      'geometry.cpp',\n>      'ipa_context_wrapper.cpp',","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 6AEF160698\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Jan 2020 23:56:35 +0100 (CET)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id C527852F;\n\tFri, 10 Jan 2020 23:56:34 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1578696995;\n\tbh=J8U6cSRo6ts5rL+MBcJVoxUuw/modkApq/sdztAb/yA=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=evWBTZc+uCsd8Jg23xHtXB/U6lcbU/XNJKftf98jC79KI6XgHfqd9auvcIMXopIaL\n\trh9fDNUgZShPrKm9GKUOwe8BcLGeX1L7a9FzY+pfLHRGIVi3XklTLZQvypjagGVkyK\n\tvMyhthF/ww9wFOMymkbGBFJx8mxboYyHk631PXZc=","Date":"Sat, 11 Jan 2020 00:55:49 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200110225549.GA4859@pendragon.ideasonboard.com>","References":"<20200110193808.2266294-1-niklas.soderlund@ragnatech.se>\n\t<20200110193808.2266294-2-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200110193808.2266294-2-niklas.soderlund@ragnatech.se>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v3 01/33] libcamera: Add\n\tFileDescriptor to help pass numerical fds around","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Fri, 10 Jan 2020 22:56:35 -0000"}},{"id":3400,"web_url":"https://patchwork.libcamera.org/comment/3400/","msgid":"<20200110231505.GA697401@oden.dyn.berto.se>","date":"2020-01-10T23:15:05","subject":"Re: [libcamera-devel] [PATCH v3 01/33] libcamera: Add\n\tFileDescriptor to help pass numerical fds around","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your feedback.\n\nOn 2020-01-11 00:55:49 +0200, Laurent Pinchart wrote:\n> Hi Niklas,\n> \n> Thank you for the patch.\n> \n> On Fri, Jan 10, 2020 at 08:37:36PM +0100, Niklas Söderlund wrote:\n> > Add a helper to make it easier to pass file descriptors around. The\n> > helper class duplicates the fd which decouples it from the original fd\n> > which could be closed by its owner while the new FileDescriptor remains\n> > valid.\n> \n> The documentation is now out of sync with the code. I'll provide an\n> updated version of this patch.\n\nThanks :-)\n\nMore comments bellow.\n\n> \n> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > ---\n> >  include/libcamera/file_descriptor.h |  46 ++++++++\n> >  include/libcamera/meson.build       |   1 +\n> >  src/libcamera/file_descriptor.cpp   | 170 ++++++++++++++++++++++++++++\n> >  src/libcamera/meson.build           |   1 +\n> >  4 files changed, 218 insertions(+)\n> >  create mode 100644 include/libcamera/file_descriptor.h\n> >  create mode 100644 src/libcamera/file_descriptor.cpp\n> > \n> > diff --git a/include/libcamera/file_descriptor.h b/include/libcamera/file_descriptor.h\n> > new file mode 100644\n> > index 0000000000000000..f08c105998cc7559\n> > --- /dev/null\n> > +++ b/include/libcamera/file_descriptor.h\n> > @@ -0,0 +1,46 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2019, Google Inc.\n> > + *\n> > + * file_descriptor.h - File descriptor wrapper\n> > + */\n> > +#ifndef __LIBCAMERA_FILE_DESCRIPTOR_H__\n> > +#define __LIBCAMERA_FILE_DESCRIPTOR_H__\n> > +\n> > +#include <memory>\n> > +\n> > +namespace libcamera {\n> > +\n> > +class FileDescriptor final\n> > +{\n> > +public:\n> > +\texplicit FileDescriptor(int fd = -1);\n> > +\tFileDescriptor(const FileDescriptor &other);\n> > +\tFileDescriptor(FileDescriptor &&other);\n> > +\t~FileDescriptor();\n> > +\n> > +\tFileDescriptor &operator=(const FileDescriptor &other);\n> > +\tFileDescriptor &operator=(FileDescriptor &&other);\n> > +\n> > +\tint fd() const { return fd_ ? fd_->fd() : -1; }\n> > +\tFileDescriptor dup() const;\n> \n> Do you think dup() is a good name, or should this be called duplicate()\n> ? Or clone() ?\n\nI rather like dup() since this is a low level wrapper around a fd so it \nfeels natural to keep to operation names close to the syscalls.  But I \nhave no strong feeling, duplicate() and clone() also conveys the intent.\n\n> \n> > +\n> > +private:\n> > +\tclass Storage\n> \n> I think we need a better name (I know, I picked this one :-))\n\n:-P\n\n> in order\n> to reference this from the documentation. Do you think FD would be a\n> good class name ? Or Descriptor ? Or something else ?\n\nI rather liked FileDescriptor::Storage as it clearly shows this is the \nshared storage. I'm fine with Descriptor too, but FD feels wrong.\n\n> \n> > +\t{\n> > +\tpublic:\n> > +\t\tStorage(int fd);\n> > +\t\t~Storage();\n> > +\n> > +\t\tint fd() const { return fd_; }\n> > +\n> > +\tprivate:\n> > +\t\tint fd_;\n> > +\t};\n> > +\n> > +\tstd::shared_ptr<Storage> fd_;\n> > +};\n> > +\n> > +} /* namespace libcamera */\n> > +\n> > +#endif /* __LIBCAMERA_FILE_DESCRIPTOR_H__ */\n> > diff --git a/include/libcamera/meson.build b/include/libcamera/meson.build\n> > index 99abf06099407c1f..543e6773cc5158a0 100644\n> > --- a/include/libcamera/meson.build\n> > +++ b/include/libcamera/meson.build\n> > @@ -6,6 +6,7 @@ libcamera_api = files([\n> >      'controls.h',\n> >      'event_dispatcher.h',\n> >      'event_notifier.h',\n> > +    'file_descriptor.h',\n> >      'geometry.h',\n> >      'logging.h',\n> >      'object.h',\n> > diff --git a/src/libcamera/file_descriptor.cpp b/src/libcamera/file_descriptor.cpp\n> > new file mode 100644\n> > index 0000000000000000..2e531f40696be16c\n> > --- /dev/null\n> > +++ b/src/libcamera/file_descriptor.cpp\n> > @@ -0,0 +1,170 @@\n> > +/* SPDX-License-Identifier: LGPL-2.1-or-later */\n> > +/*\n> > + * Copyright (C) 2019, Google Inc.\n> > + *\n> > + * file_descriptor.cpp - File descriptor wrapper\n> > + */\n> > +\n> > +#include <libcamera/file_descriptor.h>\n> > +\n> > +#include <string.h>\n> > +#include <unistd.h>\n> > +#include <utility>\n> > +\n> > +#include \"log.h\"\n> > +\n> > +/**\n> > + * \\file file_descriptor.h\n> > + * \\brief File descriptor wrapper\n> > + */\n> > +\n> > +namespace libcamera {\n> > +\n> > +LOG_DEFINE_CATEGORY(FileDescriptor)\n> > +\n> > +/**\n> > + * \\class FileDescriptor\n> > + * \\brief RAII-style wrapper for file descriptors\n> > + *\n> > + * The FileDescriptor class wraps a file descriptor (expressed as a signed\n> > + * integer) to provide an RAII-style mechanism for owning the file descriptor.\n> > + * When constructed, the FileDescriptor instance duplicates a given file\n> > + * descriptor and takes ownership of the duplicate as a resource. The copy\n> > + * constructor and assignment operator duplicate the file descriptor, while the\n> > + * move versions of those methods move the resource and make the original\n> > + * FileDescriptor invalid. When the FileDescriptor is deleted, it closes the\n> > + * file descriptor it owns, if any.\n> > + */\n> > +\n> > +/**\n> > + * \\brief Create a FileDescriptor wrapping a copy of a given \\a fd\n> > + * \\param[in] fd File descriptor\n> > + *\n> > + * Construct a FileDescriptor from a numerical file descriptor duplicates the\n> > + * \\a fd and takes ownership of the copy. The original \\a fd is left untouched,\n> > + * and the caller is responsible for closing it when appropriate. The duplicated\n> > + * file descriptor will be closed automatically when the FileDescriptor instance\n> > + * is destroyed.\n> > + */\n> > +FileDescriptor::FileDescriptor(int fd)\n> > +{\n> > +\tfd_ = std::make_shared<Storage>(fd);\n> > +}\n> > +\n> > +/**\n> > + * \\brief Copy constructor, create a FileDescriptor from a copy of \\a other\n> > + * \\param[in] other The other FileDescriptor\n> > + *\n> > + * Construct a FileDescriptor from another FileDescriptor duplicates the\n> > + * wrapped numerical file descriptor and takes ownership of the copy. The\n> > + * original FileDescriptor is left untouched, and the caller is responsible for\n> > + * closing it when appropriate. The duplicated file descriptor will be closed\n> > + * automatically when this FileDescriptor instance is destroyed.\n> > + */\n> > +FileDescriptor::FileDescriptor(const FileDescriptor &other)\n> > +\t: fd_(other.fd_)\n> > +{\n> > +}\n> > +\n> > +/**\n> > + * \\brief Move constructor, create a FileDescriptor by taking over \\a other\n> > + * \\param[in] other The other FileDescriptor\n> > + *\n> > + * Construct a FileDescriptor by taking over a wrapped numerical file\n> > + * descriptor and taking ownership of it. The \\a other FileDescriptor is\n> > + * invalidated and set to -1. The taken over file descriptor will be closed\n> > + * automatically when this FileDescriptor instance is destroyed.\n> > + */\n> > +FileDescriptor::FileDescriptor(FileDescriptor &&other)\n> > +\t: fd_(std::move(other.fd_))\n> > +{\n> > +}\n> > +\n> > +/**\n> > + * \\brief Destroy the managed file descriptor\n> > + *\n> > + * If the managed file descriptor, as returned by fd(), is not equal to -1, the\n> > + * file descriptor is closed.\n> > + */\n> > +FileDescriptor::~FileDescriptor()\n> > +{\n> > +}\n> > +\n> > +/**\n> > + * \\brief Copy assignment operator, replace the wrapped file descriptor with a\n> > + * duplicate from \\a other\n> > + * \\param[in] other The other FileDescriptor\n> > + *\n> > + * Close the wrapped file descriptor (if any) and duplicate the file descriptor\n> > + * from \\a other. The \\a other FileDescriptor is left untouched, and the caller\n> > + * is responsible for destroying it when appropriate. The duplicated file\n> > + * descriptor will be closed automatically when this FileDescriptor instance is\n> > + * destroyed.\n> > + *\n> > + * \\return A reference to this FileDescriptor\n> > + */\n> > +FileDescriptor &FileDescriptor::operator=(const FileDescriptor &other)\n> > +{\n> > +\tfd_ = other.fd_;\n> > +\n> > +\treturn *this;\n> > +}\n> > +\n> > +/**\n> > + * \\brief Move assignment operator, replace the wrapped file descriptor by\n> > + * taking over \\a other\n> > + * \\param[in] other The other FileDescriptor\n> > + *\n> > + * Close the wrapped file descriptor (if any) and take over the file descriptor\n> > + * from \\a other. The \\a other FileDescriptor is invalidated and set to -1. The\n> > + * taken over file descriptor will be closed automatically when this\n> > + * FileDescriptor instance is destroyed.\n> > + *\n> > + * \\return A reference to this FileDescriptor\n> > + */\n> > +FileDescriptor &FileDescriptor::operator=(FileDescriptor &&other)\n> > +{\n> > +\tfd_ = std::move(other.fd_);\n> > +\n> > +\treturn *this;\n> > +}\n> > +\n> > +/**\n> > + * \\fn FileDescriptor::fd()\n> > + * \\brief Retrieve the numerical file descriptor\n> > + * \\return The numerical file descriptor, which may be -1 if the FileDescriptor\n> > + * instance doesn't own a file descriptor\n> > + */\n> > +\n> > +/**\n> > + * \\brief Duplicate a FileDescriptor\n> > + * \\return A new FileDescriptor instance wrapping a duplicate of the original\n> > + * file descriptor\n> > + */\n> > +FileDescriptor FileDescriptor::dup() const\n> > +{\n> > +\treturn FileDescriptor(fd_ ? fd_->fd() : -1);\n> > +}\n> > +\n> > +FileDescriptor::Storage::Storage(int fd)\n> > +\t: fd_(-1)\n> > +{\n> > +\tif (fd < 0)\n> > +\t\treturn;\n> > +\n> > +\t/* Failing to dup() a fd should not happen and is fatal. */\n> > +\tfd_ = ::dup(fd);\n> > +\tif (fd_ == -1) {\n> > +\t\tint ret = -errno;\n> > +\t\tLOG(FileDescriptor, Fatal)\n> > +\t\t\t<< \"Failed to dup() fd: \" << strerror(-ret);\n> > +\t}\n> > +}\n> > +\n> > +FileDescriptor::Storage::~Storage()\n> > +{\n> > +\tif (fd_ != -1)\n> > +\t\tclose(fd_);\n> > +}\n> > +\n> > +} /* namespace libcamera */\n> > diff --git a/src/libcamera/meson.build b/src/libcamera/meson.build\n> > index c4f965bd7413b37e..722c5bc15afe52ef 100644\n> > --- a/src/libcamera/meson.build\n> > +++ b/src/libcamera/meson.build\n> > @@ -14,6 +14,7 @@ libcamera_sources = files([\n> >      'event_dispatcher.cpp',\n> >      'event_dispatcher_poll.cpp',\n> >      'event_notifier.cpp',\n> > +    'file_descriptor.cpp',\n> >      'formats.cpp',\n> >      'geometry.cpp',\n> >      'ipa_context_wrapper.cpp',\n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lj1-x244.google.com (mail-lj1-x244.google.com\n\t[IPv6:2a00:1450:4864:20::244])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 292166067C\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat, 11 Jan 2020 00:15:07 +0100 (CET)","by mail-lj1-x244.google.com with SMTP id h23so3796258ljc.8\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 10 Jan 2020 15:15:07 -0800 (PST)","from localhost (h-93-159.A463.priv.bahnhof.se. [46.59.93.159])\n\tby smtp.gmail.com with ESMTPSA id\n\tp136sm1752034lfa.8.2020.01.10.15.15.05\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tFri, 10 Jan 2020 15:15:05 -0800 (PST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=88KAsJtVra1288QTxwnXTdgy/KRLe6IH3yrdf9wfNP8=;\n\tb=L4J6PNjQqV/GrecuXybrQ1LQBxGlu8X8HnbWx92fZuNUYctgn9sXyhdlnh+GocKEgd\n\tKOfoopdv0jHn6ZgqL7jLR0WXLrER+RdfWEsUvVJGBtRVSX3HKwt0bHpCbU0JzQjqEWF0\n\tV/eH1O+ZIa7Qd6nkdX4tJtUghrLnLfG1Qh14t97RHLzYwCd9MJIbPvRDcDKf/8mPaQYT\n\tXHXsyeIePMsbcW0o9ebYGDVq3ag8oBB0uM8QkwW/eM/z/I94IFgDQzLYmG09lN6++c2U\n\tCsy504Wx/3xN6WLD+50emhhRwr1hhkCjw9jwwFjFEq/B6rNP7Isp3A9+8l07jWfP3mjd\n\tFt4g==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=88KAsJtVra1288QTxwnXTdgy/KRLe6IH3yrdf9wfNP8=;\n\tb=Mo9RJlfHJ3kRmw40EzdSHW3jgCQF9TZWN8YT3J45+fHg2/8HFazib7CFZXkLl0VJcp\n\tWR5eqJAbvHD/OLS4JOOGxj7KzlSsgzgYzwYE6dykR/JqnhVTY8E8HCLyjX9gk+C+gq6R\n\tQHI/RoXZlsee6GxVmXJMJ6xTwM+e51aPo7O89DbQ8lYaqABclvbWzaeK/UASV/thRIGR\n\tHZgX34QCv1zyBI0cHP2sH4I4yJfBPxK+3il7Qttc86SRakT4anyrYzD8cZa55QX7ob61\n\tTXSDj8GmXl2ZNJU/HNl/1BOulJeNqP64WrP69FeMaEo6uck3knLGo8DbiLGXZAZHnscH\n\t10Ww==","X-Gm-Message-State":"APjAAAW26/WIZyrYOf12uHZBJ6uLcH0AEnsATxdw7HXJDDI2D5zRSeds\n\t3mef578iuibHAomdHT2kc7faqA==","X-Google-Smtp-Source":"APXvYqwlOtcCPw5UreGyXV76rjlILRvkcCIWDmngnI2d3Ka+mciQe1H18imYTQNFS+nPeKxodVO30A==","X-Received":"by 2002:a2e:8916:: with SMTP id d22mr3995148lji.19.1578698106304;\n\tFri, 10 Jan 2020 15:15:06 -0800 (PST)","Date":"Sat, 11 Jan 2020 00:15:05 +0100","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200110231505.GA697401@oden.dyn.berto.se>","References":"<20200110193808.2266294-1-niklas.soderlund@ragnatech.se>\n\t<20200110193808.2266294-2-niklas.soderlund@ragnatech.se>\n\t<20200110225549.GA4859@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200110225549.GA4859@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v3 01/33] libcamera: Add\n\tFileDescriptor to help pass numerical fds around","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Fri, 10 Jan 2020 23:15:07 -0000"}}]