[{"id":38017,"web_url":"https://patchwork.libcamera.org/comment/38017/","msgid":"<20260129151600.GE3317328@killaraus>","date":"2026-01-29T15:16:00","subject":"Re: [PATCH v2] test: Remove uses of `O_TMPFILE`","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"On Thu, Jan 29, 2026 at 12:00:07PM +0100, Barnabás Pőcze wrote:\n> `O_TMPFILE` requires file system support, which may not be available in\n> certain environments, usually containerized ones. So do not use it.\n> \n> A new function is added for tests to be able to create unnamed temporary\n> files using `libcamera::MemFd` as the implementation.\n> \n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n> ---\n> changes in v2:\n>   * add function to create unnamed temporary files\n> \n> v1: https://patchwork.libcamera.org/patch/26010/\n> ---\n>  test/ipc/unixsocket.cpp  | 34 ++++++++++++++--------------------\n>  test/libtest/meson.build |  1 +\n>  test/libtest/misc.cpp    | 19 +++++++++++++++++++\n>  test/libtest/misc.h      | 17 +++++++++++++++++\n>  test/log/log_api.cpp     | 14 ++++++--------\n>  test/shared-fd.cpp       |  3 ++-\n>  test/unique-fd.cpp       |  3 ++-\n>  7 files changed, 61 insertions(+), 30 deletions(-)\n>  create mode 100644 test/libtest/misc.cpp\n>  create mode 100644 test/libtest/misc.h\n> \n> diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\n> index f39bd986b..0e603a69c 100644\n> --- a/test/ipc/unixsocket.cpp\n> +++ b/test/ipc/unixsocket.cpp\n> @@ -23,6 +23,7 @@\n> \n>  #include \"libcamera/internal/ipc_unixsocket.h\"\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  #define CMD_CLOSE\t0\n> @@ -137,11 +138,11 @@ private:\n>  \t\t}\n> \n>  \t\tcase CMD_JOIN: {\n> -\t\t\tint outfd = open(\"/tmp\", O_TMPFILE | O_RDWR,\n> -\t\t\t\t\t S_IRUSR | S_IWUSR);\n> -\t\t\tif (outfd < 0) {\n> +\t\t\tauto outfd = test::createTemporaryFile();\n\n\t\t\tUniqueFd outfd = ...\n\n> +\t\t\tif (!outfd.isValid()) {\n> +\t\t\t\tret = errno;\n>  \t\t\t\tcerr << \"Create out file failed\" << endl;\n> -\t\t\t\tstop(outfd);\n> +\t\t\t\tstop(ret);\n>  \t\t\t\treturn;\n>  \t\t\t}\n> \n> @@ -152,15 +153,13 @@ private:\n> \n>  \t\t\t\t\tif (num < 0) {\n>  \t\t\t\t\t\tcerr << \"Read failed\" << endl;\n> -\t\t\t\t\t\tclose(outfd);\n\nI like how we can now drop the close() calls.\n\n>  \t\t\t\t\t\tstop(-EIO);\n>  \t\t\t\t\t\treturn;\n>  \t\t\t\t\t} else if (!num)\n>  \t\t\t\t\t\tbreak;\n> \n> -\t\t\t\t\tif (write(outfd, buf, num) < 0) {\n> +\t\t\t\t\tif (write(outfd.get(), buf, num) < 0) {\n>  \t\t\t\t\t\tcerr << \"Write failed\" << endl;\n> -\t\t\t\t\t\tclose(outfd);\n>  \t\t\t\t\t\tstop(-EIO);\n>  \t\t\t\t\t\treturn;\n>  \t\t\t\t\t}\n> @@ -169,9 +168,9 @@ private:\n>  \t\t\t\tclose(fd);\n>  \t\t\t}\n> \n> -\t\t\tlseek(outfd, 0, 0);\n> +\t\t\tlseek(outfd.get(), 0, SEEK_SET);\n>  \t\t\tresponse.data.push_back(CMD_JOIN);\n> -\t\t\tresponse.fds.push_back(outfd);\n> +\t\t\tresponse.fds.push_back(outfd.get());\n> \n>  \t\t\tret = ipc_.send(response);\n>  \t\t\tif (ret < 0) {\n> @@ -179,8 +178,6 @@ private:\n>  \t\t\t\tstop(ret);\n>  \t\t\t}\n> \n> -\t\t\tclose(outfd);\n> -\n>  \t\t\tbreak;\n>  \t\t}\n> \n> @@ -315,22 +312,21 @@ protected:\n>  \t\t\t\"Foo\",\n>  \t\t\t\"Bar\",\n>  \t\t};\n> -\t\tint fds[2];\n> +\t\tstd::array<UniqueFD, 2> fds;\n> \n>  \t\tfor (unsigned int i = 0; i < std::size(strings); i++) {\n>  \t\t\tunsigned int len = strlen(strings[i]);\n> \n> -\t\t\tfds[i] = open(\"/tmp\", O_TMPFILE | O_RDWR,\n> -\t\t\t\t      S_IRUSR | S_IWUSR);\n> -\t\t\tif (fds[i] < 0)\n> +\t\t\tfds[i] = test::createTemporaryFile();\n> +\t\t\tif (!fds[i].isValid())\n>  \t\t\t\treturn TestFail;\n> \n> -\t\t\tret = write(fds[i], strings[i], len);\n> +\t\t\tret = write(fds[i].get(), strings[i], len);\n>  \t\t\tif (ret < 0)\n>  \t\t\t\treturn TestFail;\n> \n> -\t\t\tlseek(fds[i], 0, 0);\n> -\t\t\tmessage.fds.push_back(fds[i]);\n> +\t\t\tlseek(fds[i].get(), 0, SEEK_SET);\n> +\t\t\tmessage.fds.push_back(fds[i].get());\n>  \t\t}\n> \n>  \t\tmessage.data.push_back(CMD_JOIN);\n> @@ -343,8 +339,6 @@ protected:\n>  \t\t\tunsigned int len = strlen(strings[i]);\n>  \t\t\tstd::vector<char> buf(len);\n> \n> -\t\t\tclose(fds[i]);\n> -\n>  \t\t\tif (read(response.fds[0], buf.data(), len) <= 0)\n>  \t\t\t\treturn TestFail;\n> \n> diff --git a/test/libtest/meson.build b/test/libtest/meson.build\n> index 351629f3c..fd89f8047 100644\n> --- a/test/libtest/meson.build\n> +++ b/test/libtest/meson.build\n> @@ -3,6 +3,7 @@\n>  libtest_sources = files([\n>      'buffer_source.cpp',\n>      'camera_test.cpp',\n> +    'misc.cpp',\n>      'test.cpp',\n>  ])\n> \n> diff --git a/test/libtest/misc.cpp b/test/libtest/misc.cpp\n> new file mode 100644\n> index 000000000..d4506c869\n> --- /dev/null\n> +++ b/test/libtest/misc.cpp\n> @@ -0,0 +1,19 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2026, Ideas on Board Oy\n> + *\n> + * libcamera test miscellaneous utilities\n> + */\n> +\n> +#include \"misc.h\"\n> +\n> +#include <libcamera/base/memfd.h>\n> +\n> +namespace test {\n> +\n> +libcamera::UniqueFD createTemporaryFile()\n> +{\n> +\treturn libcamera::MemFd::create(\"libcamera-test-temporary-file\", 0);\n> +}\n> +\n> +} /* namespace test */\n\nI wouldn't object moving this to test.cpp and test.h, in case you were\nconsidering that. misc is fine too.\n\n> diff --git a/test/libtest/misc.h b/test/libtest/misc.h\n> new file mode 100644\n> index 000000000..a7b4acbeb\n> --- /dev/null\n> +++ b/test/libtest/misc.h\n> @@ -0,0 +1,17 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2026, Ideas on Board Oy\n> + *\n> + * libcamera test miscellaneous utilities\n> + */\n> +\n> +#pragma once\n> +\n> +#include <libcamera/base/unique_fd.h>\n> +\n> +namespace test {\n> +\n> +[[nodiscard]]\n> +libcamera::UniqueFD createTemporaryFile();\n> +\n> +}\n> diff --git a/test/log/log_api.cpp b/test/log/log_api.cpp\n> index 8d19cf0ce..684abf8b8 100644\n> --- a/test/log/log_api.cpp\n> +++ b/test/log/log_api.cpp\n> @@ -20,6 +20,7 @@\n> \n>  #include <libcamera/logging.h>\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  using namespace std;\n> @@ -109,18 +110,17 @@ protected:\n> \n>  \tint testFile()\n>  \t{\n> -\t\tint fd = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n> -\t\tif (fd < 0) {\n> +\t\tauto fd = test::createTemporaryFile();\n\n\t\tUniqueFd fd = ...\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\t\tif (!fd.isValid()) {\n>  \t\t\tcerr << \"Failed to open tmp log file\" << endl;\n>  \t\t\treturn TestFail;\n>  \t\t}\n> \n>  \t\tchar path[32];\n> -\t\tsnprintf(path, sizeof(path), \"/proc/self/fd/%u\", fd);\n> +\t\tsnprintf(path, sizeof(path), \"/proc/self/fd/%u\", fd.get());\n> \n>  \t\tif (logSetFile(path) < 0) {\n>  \t\t\tcerr << \"Failed to set log file\" << endl;\n> -\t\t\tclose(fd);\n>  \t\t\treturn TestFail;\n>  \t\t}\n> \n> @@ -128,13 +128,11 @@ protected:\n> \n>  \t\tchar buf[1000];\n>  \t\tmemset(buf, 0, sizeof(buf));\n> -\t\tlseek(fd, 0, SEEK_SET);\n> -\t\tif (read(fd, buf, sizeof(buf)) < 0) {\n> +\t\tlseek(fd.get(), 0, SEEK_SET);\n> +\t\tif (read(fd.get(), buf, sizeof(buf)) < 0) {\n>  \t\t\tcerr << \"Failed to read tmp log file\" << endl;\n> -\t\t\tclose(fd);\n>  \t\t\treturn TestFail;\n>  \t\t}\n> -\t\tclose(fd);\n> \n>  \t\tistringstream iss(buf);\n>  \t\treturn verifyOutput(iss);\n> diff --git a/test/shared-fd.cpp b/test/shared-fd.cpp\n> index 57199dfe7..26e3140ad 100644\n> --- a/test/shared-fd.cpp\n> +++ b/test/shared-fd.cpp\n> @@ -14,6 +14,7 @@\n>  #include <libcamera/base/shared_fd.h>\n>  #include <libcamera/base/utils.h>\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  using namespace libcamera;\n> @@ -27,7 +28,7 @@ protected:\n>  \t\tdesc1_ = nullptr;\n>  \t\tdesc2_ = nullptr;\n> \n> -\t\tfd_ = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n> +\t\tfd_ = test::createTemporaryFile().release();\n>  \t\tif (fd_ < 0)\n>  \t\t\treturn TestFail;\n> \n> diff --git a/test/unique-fd.cpp b/test/unique-fd.cpp\n> index e556439ea..280205980 100644\n> --- a/test/unique-fd.cpp\n> +++ b/test/unique-fd.cpp\n> @@ -14,6 +14,7 @@\n>  #include <libcamera/base/unique_fd.h>\n>  #include <libcamera/base/utils.h>\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  using namespace libcamera;\n> @@ -189,7 +190,7 @@ protected:\n>  private:\n>  \tint createFd()\n>  \t{\n> -\t\tfd_ = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n> +\t\tfd_ = test::createTemporaryFile().release();\n>  \t\tif (fd_ < 0)\n>  \t\t\treturn TestFail;\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 297EBBD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tThu, 29 Jan 2026 15:16:04 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 52E2961FC6;\n\tThu, 29 Jan 2026 16:16:03 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id A59D6615B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 29 Jan 2026 16:16:01 +0100 (CET)","from killaraus.ideasonboard.com\n\t(2001-14ba-703d-e500--2a1.rev.dnainternet.fi\n\t[IPv6:2001:14ba:703d:e500::2a1])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id A78AD6A6;\n\tThu, 29 Jan 2026 16:15:23 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"QLZy09Do\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1769699723;\n\tbh=ArLAvIVVTYaWg3vj1XSoVwQGS8bn3Cb2hQPr1CJ5gCE=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=QLZy09Dosg3AGk0x99pbXPmfYKKWKIeyDyyICVkcNg1snAjOXia4lt2RyeIz1gMWm\n\ta8gZhhhN1tbLeqB6JBH8Lio2IPNbM++kTU9+Q7GiCIXGkcCDgCOZp9HkoBhA9O9CmX\n\tDt+HtrZD50z04ZrAEa5a6yreDHdMvTdXavnRb6Ko=","Date":"Thu, 29 Jan 2026 17:16:00 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Subject":"Re: [PATCH v2] test: Remove uses of `O_TMPFILE`","Message-ID":"<20260129151600.GE3317328@killaraus>","References":"<20260129110007.1221054-1-barnabas.pocze@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20260129110007.1221054-1-barnabas.pocze@ideasonboard.com>","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38138,"web_url":"https://patchwork.libcamera.org/comment/38138/","msgid":"<177059613092.607498.1447219652784821583@neptunite.rasen.tech>","date":"2026-02-09T00:15:30","subject":"Re: [PATCH v2] test: Remove uses of `O_TMPFILE`","submitter":{"id":17,"url":"https://patchwork.libcamera.org/api/people/17/","name":"Paul Elder","email":"paul.elder@ideasonboard.com"},"content":"Quoting Barnabás Pőcze (2026-01-29 20:00:07)\n> `O_TMPFILE` requires file system support, which may not be available in\n> certain environments, usually containerized ones. So do not use it.\n\nAh, I hadn't realized that.\n\n> \n> A new function is added for tests to be able to create unnamed temporary\n> files using `libcamera::MemFd` as the implementation.\n\nOh neat!\n\n> \n> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n\nWith the changes Laurent suggested,\n\nReviewed-by: Paul Elder <paul.elder@ideasonboard.com>\n\n> ---\n> changes in v2:\n>   * add function to create unnamed temporary files\n> \n> v1: https://patchwork.libcamera.org/patch/26010/\n> ---\n>  test/ipc/unixsocket.cpp  | 34 ++++++++++++++--------------------\n>  test/libtest/meson.build |  1 +\n>  test/libtest/misc.cpp    | 19 +++++++++++++++++++\n>  test/libtest/misc.h      | 17 +++++++++++++++++\n>  test/log/log_api.cpp     | 14 ++++++--------\n>  test/shared-fd.cpp       |  3 ++-\n>  test/unique-fd.cpp       |  3 ++-\n>  7 files changed, 61 insertions(+), 30 deletions(-)\n>  create mode 100644 test/libtest/misc.cpp\n>  create mode 100644 test/libtest/misc.h\n> \n> diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\n> index f39bd986b..0e603a69c 100644\n> --- a/test/ipc/unixsocket.cpp\n> +++ b/test/ipc/unixsocket.cpp\n> @@ -23,6 +23,7 @@\n> \n>  #include \"libcamera/internal/ipc_unixsocket.h\"\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  #define CMD_CLOSE      0\n> @@ -137,11 +138,11 @@ private:\n>                 }\n> \n>                 case CMD_JOIN: {\n> -                       int outfd = open(\"/tmp\", O_TMPFILE | O_RDWR,\n> -                                        S_IRUSR | S_IWUSR);\n> -                       if (outfd < 0) {\n> +                       auto outfd = test::createTemporaryFile();\n> +                       if (!outfd.isValid()) {\n> +                               ret = errno;\n>                                 cerr << \"Create out file failed\" << endl;\n> -                               stop(outfd);\n> +                               stop(ret);\n>                                 return;\n>                         }\n> \n> @@ -152,15 +153,13 @@ private:\n> \n>                                         if (num < 0) {\n>                                                 cerr << \"Read failed\" << endl;\n> -                                               close(outfd);\n>                                                 stop(-EIO);\n>                                                 return;\n>                                         } else if (!num)\n>                                                 break;\n> \n> -                                       if (write(outfd, buf, num) < 0) {\n> +                                       if (write(outfd.get(), buf, num) < 0) {\n>                                                 cerr << \"Write failed\" << endl;\n> -                                               close(outfd);\n>                                                 stop(-EIO);\n>                                                 return;\n>                                         }\n> @@ -169,9 +168,9 @@ private:\n>                                 close(fd);\n>                         }\n> \n> -                       lseek(outfd, 0, 0);\n> +                       lseek(outfd.get(), 0, SEEK_SET);\n>                         response.data.push_back(CMD_JOIN);\n> -                       response.fds.push_back(outfd);\n> +                       response.fds.push_back(outfd.get());\n> \n>                         ret = ipc_.send(response);\n>                         if (ret < 0) {\n> @@ -179,8 +178,6 @@ private:\n>                                 stop(ret);\n>                         }\n> \n> -                       close(outfd);\n> -\n>                         break;\n>                 }\n> \n> @@ -315,22 +312,21 @@ protected:\n>                         \"Foo\",\n>                         \"Bar\",\n>                 };\n> -               int fds[2];\n> +               std::array<UniqueFD, 2> fds;\n> \n>                 for (unsigned int i = 0; i < std::size(strings); i++) {\n>                         unsigned int len = strlen(strings[i]);\n> \n> -                       fds[i] = open(\"/tmp\", O_TMPFILE | O_RDWR,\n> -                                     S_IRUSR | S_IWUSR);\n> -                       if (fds[i] < 0)\n> +                       fds[i] = test::createTemporaryFile();\n> +                       if (!fds[i].isValid())\n>                                 return TestFail;\n> \n> -                       ret = write(fds[i], strings[i], len);\n> +                       ret = write(fds[i].get(), strings[i], len);\n>                         if (ret < 0)\n>                                 return TestFail;\n> \n> -                       lseek(fds[i], 0, 0);\n> -                       message.fds.push_back(fds[i]);\n> +                       lseek(fds[i].get(), 0, SEEK_SET);\n> +                       message.fds.push_back(fds[i].get());\n>                 }\n> \n>                 message.data.push_back(CMD_JOIN);\n> @@ -343,8 +339,6 @@ protected:\n>                         unsigned int len = strlen(strings[i]);\n>                         std::vector<char> buf(len);\n> \n> -                       close(fds[i]);\n> -\n>                         if (read(response.fds[0], buf.data(), len) <= 0)\n>                                 return TestFail;\n> \n> diff --git a/test/libtest/meson.build b/test/libtest/meson.build\n> index 351629f3c..fd89f8047 100644\n> --- a/test/libtest/meson.build\n> +++ b/test/libtest/meson.build\n> @@ -3,6 +3,7 @@\n>  libtest_sources = files([\n>      'buffer_source.cpp',\n>      'camera_test.cpp',\n> +    'misc.cpp',\n>      'test.cpp',\n>  ])\n> \n> diff --git a/test/libtest/misc.cpp b/test/libtest/misc.cpp\n> new file mode 100644\n> index 000000000..d4506c869\n> --- /dev/null\n> +++ b/test/libtest/misc.cpp\n> @@ -0,0 +1,19 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2026, Ideas on Board Oy\n> + *\n> + * libcamera test miscellaneous utilities\n> + */\n> +\n> +#include \"misc.h\"\n> +\n> +#include <libcamera/base/memfd.h>\n> +\n> +namespace test {\n> +\n> +libcamera::UniqueFD createTemporaryFile()\n> +{\n> +       return libcamera::MemFd::create(\"libcamera-test-temporary-file\", 0);\n> +}\n> +\n> +} /* namespace test */\n> diff --git a/test/libtest/misc.h b/test/libtest/misc.h\n> new file mode 100644\n> index 000000000..a7b4acbeb\n> --- /dev/null\n> +++ b/test/libtest/misc.h\n> @@ -0,0 +1,17 @@\n> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n> +/*\n> + * Copyright (C) 2026, Ideas on Board Oy\n> + *\n> + * libcamera test miscellaneous utilities\n> + */\n> +\n> +#pragma once\n> +\n> +#include <libcamera/base/unique_fd.h>\n> +\n> +namespace test {\n> +\n> +[[nodiscard]]\n> +libcamera::UniqueFD createTemporaryFile();\n> +\n> +}\n> diff --git a/test/log/log_api.cpp b/test/log/log_api.cpp\n> index 8d19cf0ce..684abf8b8 100644\n> --- a/test/log/log_api.cpp\n> +++ b/test/log/log_api.cpp\n> @@ -20,6 +20,7 @@\n> \n>  #include <libcamera/logging.h>\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  using namespace std;\n> @@ -109,18 +110,17 @@ protected:\n> \n>         int testFile()\n>         {\n> -               int fd = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n> -               if (fd < 0) {\n> +               auto fd = test::createTemporaryFile();\n> +               if (!fd.isValid()) {\n>                         cerr << \"Failed to open tmp log file\" << endl;\n>                         return TestFail;\n>                 }\n> \n>                 char path[32];\n> -               snprintf(path, sizeof(path), \"/proc/self/fd/%u\", fd);\n> +               snprintf(path, sizeof(path), \"/proc/self/fd/%u\", fd.get());\n> \n>                 if (logSetFile(path) < 0) {\n>                         cerr << \"Failed to set log file\" << endl;\n> -                       close(fd);\n>                         return TestFail;\n>                 }\n> \n> @@ -128,13 +128,11 @@ protected:\n> \n>                 char buf[1000];\n>                 memset(buf, 0, sizeof(buf));\n> -               lseek(fd, 0, SEEK_SET);\n> -               if (read(fd, buf, sizeof(buf)) < 0) {\n> +               lseek(fd.get(), 0, SEEK_SET);\n> +               if (read(fd.get(), buf, sizeof(buf)) < 0) {\n>                         cerr << \"Failed to read tmp log file\" << endl;\n> -                       close(fd);\n>                         return TestFail;\n>                 }\n> -               close(fd);\n> \n>                 istringstream iss(buf);\n>                 return verifyOutput(iss);\n> diff --git a/test/shared-fd.cpp b/test/shared-fd.cpp\n> index 57199dfe7..26e3140ad 100644\n> --- a/test/shared-fd.cpp\n> +++ b/test/shared-fd.cpp\n> @@ -14,6 +14,7 @@\n>  #include <libcamera/base/shared_fd.h>\n>  #include <libcamera/base/utils.h>\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  using namespace libcamera;\n> @@ -27,7 +28,7 @@ protected:\n>                 desc1_ = nullptr;\n>                 desc2_ = nullptr;\n> \n> -               fd_ = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n> +               fd_ = test::createTemporaryFile().release();\n>                 if (fd_ < 0)\n>                         return TestFail;\n> \n> diff --git a/test/unique-fd.cpp b/test/unique-fd.cpp\n> index e556439ea..280205980 100644\n> --- a/test/unique-fd.cpp\n> +++ b/test/unique-fd.cpp\n> @@ -14,6 +14,7 @@\n>  #include <libcamera/base/unique_fd.h>\n>  #include <libcamera/base/utils.h>\n> \n> +#include \"misc.h\"\n>  #include \"test.h\"\n> \n>  using namespace libcamera;\n> @@ -189,7 +190,7 @@ protected:\n>  private:\n>         int createFd()\n>         {\n> -               fd_ = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n> +               fd_ = test::createTemporaryFile().release();\n>                 if (fd_ < 0)\n>                         return TestFail;\n> \n> --\n> 2.52.0","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 416D3BD78E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  9 Feb 2026 00:15:41 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 1E94D620B8;\n\tMon,  9 Feb 2026 01:15:40 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 40CE0615B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  9 Feb 2026 01:15:38 +0100 (CET)","from neptunite.rasen.tech (unknown\n\t[IPv6:2404:7a81:160:2100:1d5b:ed88:18ac:b4])\n\tby perceval.ideasonboard.com (Postfix) with UTF8SMTPSA id 39A80C6C;\n\tMon,  9 Feb 2026 01:14:51 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"LOQ/9iGl\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1770596092;\n\tbh=6LLFq78zCBdGva0Rah9GbCXGHkc3TzDcQxCq+QiKUPk=;\n\th=In-Reply-To:References:Subject:From:To:Date:From;\n\tb=LOQ/9iGlIIcF0i8Ig04GT+0aULh1OFT/mvVfSG/0EYo9Js85g76SdZ+EyWYJK0NK4\n\tltRZLR7pGCs/0SznJZxaqMo9chEz9ibWzk6Qp71RWPYrwnymjDD08MtGRvE0m7pliK\n\tT7l+q0/uTKMcBDZwJK0mSf7Lr0PItWQiz/THlLKY=","Content-Type":"text/plain; charset=\"utf-8\"","MIME-Version":"1.0","Content-Transfer-Encoding":"quoted-printable","In-Reply-To":"<20260129110007.1221054-1-barnabas.pocze@ideasonboard.com>","References":"<20260129110007.1221054-1-barnabas.pocze@ideasonboard.com>","Subject":"Re: [PATCH v2] test: Remove uses of `O_TMPFILE`","From":"Paul Elder <paul.elder@ideasonboard.com>","To":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>,\n\tlibcamera-devel@lists.libcamera.org","Date":"Mon, 09 Feb 2026 09:15:30 +0900","Message-ID":"<177059613092.607498.1447219652784821583@neptunite.rasen.tech>","User-Agent":"alot/0.0.0","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}},{"id":38143,"web_url":"https://patchwork.libcamera.org/comment/38143/","msgid":"<7f25a858-c3ab-40e9-aa0b-dbcbcba28770@ideasonboard.com>","date":"2026-02-09T10:05:20","subject":"Re: [PATCH v2] test: Remove uses of `O_TMPFILE`","submitter":{"id":216,"url":"https://patchwork.libcamera.org/api/people/216/","name":"Barnabás Pőcze","email":"barnabas.pocze@ideasonboard.com"},"content":"2026. 01. 29. 16:16 keltezéssel, Laurent Pinchart írta:\n> On Thu, Jan 29, 2026 at 12:00:07PM +0100, Barnabás Pőcze wrote:\n>> `O_TMPFILE` requires file system support, which may not be available in\n>> certain environments, usually containerized ones. So do not use it.\n>>\n>> A new function is added for tests to be able to create unnamed temporary\n>> files using `libcamera::MemFd` as the implementation.\n>>\n>> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>\n>> ---\n>> changes in v2:\n>>    * add function to create unnamed temporary files\n>>\n>> v1: https://patchwork.libcamera.org/patch/26010/\n>> ---\n>>   test/ipc/unixsocket.cpp  | 34 ++++++++++++++--------------------\n>>   test/libtest/meson.build |  1 +\n>>   test/libtest/misc.cpp    | 19 +++++++++++++++++++\n>>   test/libtest/misc.h      | 17 +++++++++++++++++\n>>   test/log/log_api.cpp     | 14 ++++++--------\n>>   test/shared-fd.cpp       |  3 ++-\n>>   test/unique-fd.cpp       |  3 ++-\n>>   7 files changed, 61 insertions(+), 30 deletions(-)\n>>   create mode 100644 test/libtest/misc.cpp\n>>   create mode 100644 test/libtest/misc.h\n>>\n>> diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp\n>> index f39bd986b..0e603a69c 100644\n>> --- a/test/ipc/unixsocket.cpp\n>> +++ b/test/ipc/unixsocket.cpp\n>> @@ -23,6 +23,7 @@\n>>\n>>   #include \"libcamera/internal/ipc_unixsocket.h\"\n>>\n>> +#include \"misc.h\"\n>>   #include \"test.h\"\n>>\n>>   #define CMD_CLOSE\t0\n>> @@ -137,11 +138,11 @@ private:\n>>   \t\t}\n>>\n>>   \t\tcase CMD_JOIN: {\n>> -\t\t\tint outfd = open(\"/tmp\", O_TMPFILE | O_RDWR,\n>> -\t\t\t\t\t S_IRUSR | S_IWUSR);\n>> -\t\t\tif (outfd < 0) {\n>> +\t\t\tauto outfd = test::createTemporaryFile();\n> \n> \t\t\tUniqueFd outfd = ...\n\nOk.\n\n\n> \n>> +\t\t\tif (!outfd.isValid()) {\n>> +\t\t\t\tret = errno;\n>>   \t\t\t\tcerr << \"Create out file failed\" << endl;\n>> -\t\t\t\tstop(outfd);\n>> +\t\t\t\tstop(ret);\n>>   \t\t\t\treturn;\n>>   \t\t\t}\n>>\n>> @@ -152,15 +153,13 @@ private:\n>>\n>>   \t\t\t\t\tif (num < 0) {\n>>   \t\t\t\t\t\tcerr << \"Read failed\" << endl;\n>> -\t\t\t\t\t\tclose(outfd);\n> \n> I like how we can now drop the close() calls.\n> \n>>   \t\t\t\t\t\tstop(-EIO);\n>>   \t\t\t\t\t\treturn;\n>>   \t\t\t\t\t} else if (!num)\n>>   \t\t\t\t\t\tbreak;\n>>\n>> -\t\t\t\t\tif (write(outfd, buf, num) < 0) {\n>> +\t\t\t\t\tif (write(outfd.get(), buf, num) < 0) {\n>>   \t\t\t\t\t\tcerr << \"Write failed\" << endl;\n>> -\t\t\t\t\t\tclose(outfd);\n>>   \t\t\t\t\t\tstop(-EIO);\n>>   \t\t\t\t\t\treturn;\n>>   \t\t\t\t\t}\n>> @@ -169,9 +168,9 @@ private:\n>>   \t\t\t\tclose(fd);\n>>   \t\t\t}\n>>\n>> -\t\t\tlseek(outfd, 0, 0);\n>> +\t\t\tlseek(outfd.get(), 0, SEEK_SET);\n>>   \t\t\tresponse.data.push_back(CMD_JOIN);\n>> -\t\t\tresponse.fds.push_back(outfd);\n>> +\t\t\tresponse.fds.push_back(outfd.get());\n>>\n>>   \t\t\tret = ipc_.send(response);\n>>   \t\t\tif (ret < 0) {\n>> @@ -179,8 +178,6 @@ private:\n>>   \t\t\t\tstop(ret);\n>>   \t\t\t}\n>>\n>> -\t\t\tclose(outfd);\n>> -\n>>   \t\t\tbreak;\n>>   \t\t}\n>>\n>> @@ -315,22 +312,21 @@ protected:\n>>   \t\t\t\"Foo\",\n>>   \t\t\t\"Bar\",\n>>   \t\t};\n>> -\t\tint fds[2];\n>> +\t\tstd::array<UniqueFD, 2> fds;\n>>\n>>   \t\tfor (unsigned int i = 0; i < std::size(strings); i++) {\n>>   \t\t\tunsigned int len = strlen(strings[i]);\n>>\n>> -\t\t\tfds[i] = open(\"/tmp\", O_TMPFILE | O_RDWR,\n>> -\t\t\t\t      S_IRUSR | S_IWUSR);\n>> -\t\t\tif (fds[i] < 0)\n>> +\t\t\tfds[i] = test::createTemporaryFile();\n>> +\t\t\tif (!fds[i].isValid())\n>>   \t\t\t\treturn TestFail;\n>>\n>> -\t\t\tret = write(fds[i], strings[i], len);\n>> +\t\t\tret = write(fds[i].get(), strings[i], len);\n>>   \t\t\tif (ret < 0)\n>>   \t\t\t\treturn TestFail;\n>>\n>> -\t\t\tlseek(fds[i], 0, 0);\n>> -\t\t\tmessage.fds.push_back(fds[i]);\n>> +\t\t\tlseek(fds[i].get(), 0, SEEK_SET);\n>> +\t\t\tmessage.fds.push_back(fds[i].get());\n>>   \t\t}\n>>\n>>   \t\tmessage.data.push_back(CMD_JOIN);\n>> @@ -343,8 +339,6 @@ protected:\n>>   \t\t\tunsigned int len = strlen(strings[i]);\n>>   \t\t\tstd::vector<char> buf(len);\n>>\n>> -\t\t\tclose(fds[i]);\n>> -\n>>   \t\t\tif (read(response.fds[0], buf.data(), len) <= 0)\n>>   \t\t\t\treturn TestFail;\n>>\n>> diff --git a/test/libtest/meson.build b/test/libtest/meson.build\n>> index 351629f3c..fd89f8047 100644\n>> --- a/test/libtest/meson.build\n>> +++ b/test/libtest/meson.build\n>> @@ -3,6 +3,7 @@\n>>   libtest_sources = files([\n>>       'buffer_source.cpp',\n>>       'camera_test.cpp',\n>> +    'misc.cpp',\n>>       'test.cpp',\n>>   ])\n>>\n>> diff --git a/test/libtest/misc.cpp b/test/libtest/misc.cpp\n>> new file mode 100644\n>> index 000000000..d4506c869\n>> --- /dev/null\n>> +++ b/test/libtest/misc.cpp\n>> @@ -0,0 +1,19 @@\n>> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n>> +/*\n>> + * Copyright (C) 2026, Ideas on Board Oy\n>> + *\n>> + * libcamera test miscellaneous utilities\n>> + */\n>> +\n>> +#include \"misc.h\"\n>> +\n>> +#include <libcamera/base/memfd.h>\n>> +\n>> +namespace test {\n>> +\n>> +libcamera::UniqueFD createTemporaryFile()\n>> +{\n>> +\treturn libcamera::MemFd::create(\"libcamera-test-temporary-file\", 0);\n>> +}\n>> +\n>> +} /* namespace test */\n> \n> I wouldn't object moving this to test.cpp and test.h, in case you were\n> considering that. misc is fine too.\n\nI'll move it.\n\n\n> \n>> diff --git a/test/libtest/misc.h b/test/libtest/misc.h\n>> new file mode 100644\n>> index 000000000..a7b4acbeb\n>> --- /dev/null\n>> +++ b/test/libtest/misc.h\n>> @@ -0,0 +1,17 @@\n>> +/* SPDX-License-Identifier: GPL-2.0-or-later */\n>> +/*\n>> + * Copyright (C) 2026, Ideas on Board Oy\n>> + *\n>> + * libcamera test miscellaneous utilities\n>> + */\n>> +\n>> +#pragma once\n>> +\n>> +#include <libcamera/base/unique_fd.h>\n>> +\n>> +namespace test {\n>> +\n>> +[[nodiscard]]\n>> +libcamera::UniqueFD createTemporaryFile();\n>> +\n>> +}\n>> diff --git a/test/log/log_api.cpp b/test/log/log_api.cpp\n>> index 8d19cf0ce..684abf8b8 100644\n>> --- a/test/log/log_api.cpp\n>> +++ b/test/log/log_api.cpp\n>> @@ -20,6 +20,7 @@\n>>\n>>   #include <libcamera/logging.h>\n>>\n>> +#include \"misc.h\"\n>>   #include \"test.h\"\n>>\n>>   using namespace std;\n>> @@ -109,18 +110,17 @@ protected:\n>>\n>>   \tint testFile()\n>>   \t{\n>> -\t\tint fd = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n>> -\t\tif (fd < 0) {\n>> +\t\tauto fd = test::createTemporaryFile();\n> \n> \t\tUniqueFd fd = ...\n\nOk.\n\n\n> \n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> \n>> +\t\tif (!fd.isValid()) {\n>>   \t\t\tcerr << \"Failed to open tmp log file\" << endl;\n>>   \t\t\treturn TestFail;\n>>   \t\t}\n>>\n>>   \t\tchar path[32];\n>> -\t\tsnprintf(path, sizeof(path), \"/proc/self/fd/%u\", fd);\n>> +\t\tsnprintf(path, sizeof(path), \"/proc/self/fd/%u\", fd.get());\n>>\n>>   \t\tif (logSetFile(path) < 0) {\n>>   \t\t\tcerr << \"Failed to set log file\" << endl;\n>> -\t\t\tclose(fd);\n>>   \t\t\treturn TestFail;\n>>   \t\t}\n>>\n>> @@ -128,13 +128,11 @@ protected:\n>>\n>>   \t\tchar buf[1000];\n>>   \t\tmemset(buf, 0, sizeof(buf));\n>> -\t\tlseek(fd, 0, SEEK_SET);\n>> -\t\tif (read(fd, buf, sizeof(buf)) < 0) {\n>> +\t\tlseek(fd.get(), 0, SEEK_SET);\n>> +\t\tif (read(fd.get(), buf, sizeof(buf)) < 0) {\n>>   \t\t\tcerr << \"Failed to read tmp log file\" << endl;\n>> -\t\t\tclose(fd);\n>>   \t\t\treturn TestFail;\n>>   \t\t}\n>> -\t\tclose(fd);\n>>\n>>   \t\tistringstream iss(buf);\n>>   \t\treturn verifyOutput(iss);\n>> diff --git a/test/shared-fd.cpp b/test/shared-fd.cpp\n>> index 57199dfe7..26e3140ad 100644\n>> --- a/test/shared-fd.cpp\n>> +++ b/test/shared-fd.cpp\n>> @@ -14,6 +14,7 @@\n>>   #include <libcamera/base/shared_fd.h>\n>>   #include <libcamera/base/utils.h>\n>>\n>> +#include \"misc.h\"\n>>   #include \"test.h\"\n>>\n>>   using namespace libcamera;\n>> @@ -27,7 +28,7 @@ protected:\n>>   \t\tdesc1_ = nullptr;\n>>   \t\tdesc2_ = nullptr;\n>>\n>> -\t\tfd_ = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n>> +\t\tfd_ = test::createTemporaryFile().release();\n>>   \t\tif (fd_ < 0)\n>>   \t\t\treturn TestFail;\n>>\n>> diff --git a/test/unique-fd.cpp b/test/unique-fd.cpp\n>> index e556439ea..280205980 100644\n>> --- a/test/unique-fd.cpp\n>> +++ b/test/unique-fd.cpp\n>> @@ -14,6 +14,7 @@\n>>   #include <libcamera/base/unique_fd.h>\n>>   #include <libcamera/base/utils.h>\n>>\n>> +#include \"misc.h\"\n>>   #include \"test.h\"\n>>\n>>   using namespace libcamera;\n>> @@ -189,7 +190,7 @@ protected:\n>>   private:\n>>   \tint createFd()\n>>   \t{\n>> -\t\tfd_ = open(\"/tmp\", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);\n>> +\t\tfd_ = test::createTemporaryFile().release();\n>>   \t\tif (fd_ < 0)\n>>   \t\t\treturn TestFail;\n>>\n>","headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 3208AC3220\n\tfor <parsemail@patchwork.libcamera.org>;\n\tMon,  9 Feb 2026 10:05:26 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 6E4FF620BC;\n\tMon,  9 Feb 2026 11:05:25 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 09B3C615B2\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon,  9 Feb 2026 11:05:24 +0100 (CET)","from [192.168.33.63] (185.221.141.206.nat.pool.zt.hu\n\t[185.221.141.206])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 52867BD2;\n\tMon,  9 Feb 2026 11:04:38 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"Aan1UT6V\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1770631478;\n\tbh=ocdjjjIFMlCszG+76BEizo0s8D3ntSIawWWmAkBJeFM=;\n\th=Date:Subject:To:Cc:References:From:In-Reply-To:From;\n\tb=Aan1UT6VRNy2ddJflgrSjrvDjAtH49G8UbmxgCkEpHzUKIMiCN2r/BsOKXZW0yXCJ\n\taj+is6x4D/ocCTqmeOtluCSwh879KysGnUidT1rXKa/M1aLbD6sgzfmKFasyO4Spu7\n\tROymxLrwwwuCsdnVKiTlQGhz8LsrC/l2ELkVjFj4=","Message-ID":"<7f25a858-c3ab-40e9-aa0b-dbcbcba28770@ideasonboard.com>","Date":"Mon, 9 Feb 2026 11:05:20 +0100","MIME-Version":"1.0","User-Agent":"Mozilla Thunderbird","Subject":"Re: [PATCH v2] test: Remove uses of `O_TMPFILE`","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","References":"<20260129110007.1221054-1-barnabas.pocze@ideasonboard.com>\n\t<20260129151600.GE3317328@killaraus>","From":"=?utf-8?q?Barnab=C3=A1s_P=C5=91cze?= <barnabas.pocze@ideasonboard.com>","Content-Language":"en-US, hu-HU","In-Reply-To":"<20260129151600.GE3317328@killaraus>","Content-Type":"text/plain; charset=UTF-8; format=flowed","Content-Transfer-Encoding":"8bit","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>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]