| Message ID | 20260129110007.1221054-1-barnabas.pocze@ideasonboard.com |
|---|---|
| State | New |
| Headers | show |
| Series |
|
| Related | show |
On Thu, Jan 29, 2026 at 12:00:07PM +0100, Barnabás Pőcze wrote: > `O_TMPFILE` requires file system support, which may not be available in > certain environments, usually containerized ones. So do not use it. > > A new function is added for tests to be able to create unnamed temporary > files using `libcamera::MemFd` as the implementation. > > Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> > --- > changes in v2: > * add function to create unnamed temporary files > > v1: https://patchwork.libcamera.org/patch/26010/ > --- > test/ipc/unixsocket.cpp | 34 ++++++++++++++-------------------- > test/libtest/meson.build | 1 + > test/libtest/misc.cpp | 19 +++++++++++++++++++ > test/libtest/misc.h | 17 +++++++++++++++++ > test/log/log_api.cpp | 14 ++++++-------- > test/shared-fd.cpp | 3 ++- > test/unique-fd.cpp | 3 ++- > 7 files changed, 61 insertions(+), 30 deletions(-) > create mode 100644 test/libtest/misc.cpp > create mode 100644 test/libtest/misc.h > > diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp > index f39bd986b..0e603a69c 100644 > --- a/test/ipc/unixsocket.cpp > +++ b/test/ipc/unixsocket.cpp > @@ -23,6 +23,7 @@ > > #include "libcamera/internal/ipc_unixsocket.h" > > +#include "misc.h" > #include "test.h" > > #define CMD_CLOSE 0 > @@ -137,11 +138,11 @@ private: > } > > case CMD_JOIN: { > - int outfd = open("/tmp", O_TMPFILE | O_RDWR, > - S_IRUSR | S_IWUSR); > - if (outfd < 0) { > + auto outfd = test::createTemporaryFile(); UniqueFd outfd = ... > + if (!outfd.isValid()) { > + ret = errno; > cerr << "Create out file failed" << endl; > - stop(outfd); > + stop(ret); > return; > } > > @@ -152,15 +153,13 @@ private: > > if (num < 0) { > cerr << "Read failed" << endl; > - close(outfd); I like how we can now drop the close() calls. > stop(-EIO); > return; > } else if (!num) > break; > > - if (write(outfd, buf, num) < 0) { > + if (write(outfd.get(), buf, num) < 0) { > cerr << "Write failed" << endl; > - close(outfd); > stop(-EIO); > return; > } > @@ -169,9 +168,9 @@ private: > close(fd); > } > > - lseek(outfd, 0, 0); > + lseek(outfd.get(), 0, SEEK_SET); > response.data.push_back(CMD_JOIN); > - response.fds.push_back(outfd); > + response.fds.push_back(outfd.get()); > > ret = ipc_.send(response); > if (ret < 0) { > @@ -179,8 +178,6 @@ private: > stop(ret); > } > > - close(outfd); > - > break; > } > > @@ -315,22 +312,21 @@ protected: > "Foo", > "Bar", > }; > - int fds[2]; > + std::array<UniqueFD, 2> fds; > > for (unsigned int i = 0; i < std::size(strings); i++) { > unsigned int len = strlen(strings[i]); > > - fds[i] = open("/tmp", O_TMPFILE | O_RDWR, > - S_IRUSR | S_IWUSR); > - if (fds[i] < 0) > + fds[i] = test::createTemporaryFile(); > + if (!fds[i].isValid()) > return TestFail; > > - ret = write(fds[i], strings[i], len); > + ret = write(fds[i].get(), strings[i], len); > if (ret < 0) > return TestFail; > > - lseek(fds[i], 0, 0); > - message.fds.push_back(fds[i]); > + lseek(fds[i].get(), 0, SEEK_SET); > + message.fds.push_back(fds[i].get()); > } > > message.data.push_back(CMD_JOIN); > @@ -343,8 +339,6 @@ protected: > unsigned int len = strlen(strings[i]); > std::vector<char> buf(len); > > - close(fds[i]); > - > if (read(response.fds[0], buf.data(), len) <= 0) > return TestFail; > > diff --git a/test/libtest/meson.build b/test/libtest/meson.build > index 351629f3c..fd89f8047 100644 > --- a/test/libtest/meson.build > +++ b/test/libtest/meson.build > @@ -3,6 +3,7 @@ > libtest_sources = files([ > 'buffer_source.cpp', > 'camera_test.cpp', > + 'misc.cpp', > 'test.cpp', > ]) > > diff --git a/test/libtest/misc.cpp b/test/libtest/misc.cpp > new file mode 100644 > index 000000000..d4506c869 > --- /dev/null > +++ b/test/libtest/misc.cpp > @@ -0,0 +1,19 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * Copyright (C) 2026, Ideas on Board Oy > + * > + * libcamera test miscellaneous utilities > + */ > + > +#include "misc.h" > + > +#include <libcamera/base/memfd.h> > + > +namespace test { > + > +libcamera::UniqueFD createTemporaryFile() > +{ > + return libcamera::MemFd::create("libcamera-test-temporary-file", 0); > +} > + > +} /* namespace test */ I wouldn't object moving this to test.cpp and test.h, in case you were considering that. misc is fine too. > diff --git a/test/libtest/misc.h b/test/libtest/misc.h > new file mode 100644 > index 000000000..a7b4acbeb > --- /dev/null > +++ b/test/libtest/misc.h > @@ -0,0 +1,17 @@ > +/* SPDX-License-Identifier: GPL-2.0-or-later */ > +/* > + * Copyright (C) 2026, Ideas on Board Oy > + * > + * libcamera test miscellaneous utilities > + */ > + > +#pragma once > + > +#include <libcamera/base/unique_fd.h> > + > +namespace test { > + > +[[nodiscard]] > +libcamera::UniqueFD createTemporaryFile(); > + > +} > diff --git a/test/log/log_api.cpp b/test/log/log_api.cpp > index 8d19cf0ce..684abf8b8 100644 > --- a/test/log/log_api.cpp > +++ b/test/log/log_api.cpp > @@ -20,6 +20,7 @@ > > #include <libcamera/logging.h> > > +#include "misc.h" > #include "test.h" > > using namespace std; > @@ -109,18 +110,17 @@ protected: > > int testFile() > { > - int fd = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); > - if (fd < 0) { > + auto fd = test::createTemporaryFile(); UniqueFd fd = ... Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > + if (!fd.isValid()) { > cerr << "Failed to open tmp log file" << endl; > return TestFail; > } > > char path[32]; > - snprintf(path, sizeof(path), "/proc/self/fd/%u", fd); > + snprintf(path, sizeof(path), "/proc/self/fd/%u", fd.get()); > > if (logSetFile(path) < 0) { > cerr << "Failed to set log file" << endl; > - close(fd); > return TestFail; > } > > @@ -128,13 +128,11 @@ protected: > > char buf[1000]; > memset(buf, 0, sizeof(buf)); > - lseek(fd, 0, SEEK_SET); > - if (read(fd, buf, sizeof(buf)) < 0) { > + lseek(fd.get(), 0, SEEK_SET); > + if (read(fd.get(), buf, sizeof(buf)) < 0) { > cerr << "Failed to read tmp log file" << endl; > - close(fd); > return TestFail; > } > - close(fd); > > istringstream iss(buf); > return verifyOutput(iss); > diff --git a/test/shared-fd.cpp b/test/shared-fd.cpp > index 57199dfe7..26e3140ad 100644 > --- a/test/shared-fd.cpp > +++ b/test/shared-fd.cpp > @@ -14,6 +14,7 @@ > #include <libcamera/base/shared_fd.h> > #include <libcamera/base/utils.h> > > +#include "misc.h" > #include "test.h" > > using namespace libcamera; > @@ -27,7 +28,7 @@ protected: > desc1_ = nullptr; > desc2_ = nullptr; > > - fd_ = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); > + fd_ = test::createTemporaryFile().release(); > if (fd_ < 0) > return TestFail; > > diff --git a/test/unique-fd.cpp b/test/unique-fd.cpp > index e556439ea..280205980 100644 > --- a/test/unique-fd.cpp > +++ b/test/unique-fd.cpp > @@ -14,6 +14,7 @@ > #include <libcamera/base/unique_fd.h> > #include <libcamera/base/utils.h> > > +#include "misc.h" > #include "test.h" > > using namespace libcamera; > @@ -189,7 +190,7 @@ protected: > private: > int createFd() > { > - fd_ = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); > + fd_ = test::createTemporaryFile().release(); > if (fd_ < 0) > return TestFail; >
diff --git a/test/ipc/unixsocket.cpp b/test/ipc/unixsocket.cpp index f39bd986b..0e603a69c 100644 --- a/test/ipc/unixsocket.cpp +++ b/test/ipc/unixsocket.cpp @@ -23,6 +23,7 @@ #include "libcamera/internal/ipc_unixsocket.h" +#include "misc.h" #include "test.h" #define CMD_CLOSE 0 @@ -137,11 +138,11 @@ private: } case CMD_JOIN: { - int outfd = open("/tmp", O_TMPFILE | O_RDWR, - S_IRUSR | S_IWUSR); - if (outfd < 0) { + auto outfd = test::createTemporaryFile(); + if (!outfd.isValid()) { + ret = errno; cerr << "Create out file failed" << endl; - stop(outfd); + stop(ret); return; } @@ -152,15 +153,13 @@ private: if (num < 0) { cerr << "Read failed" << endl; - close(outfd); stop(-EIO); return; } else if (!num) break; - if (write(outfd, buf, num) < 0) { + if (write(outfd.get(), buf, num) < 0) { cerr << "Write failed" << endl; - close(outfd); stop(-EIO); return; } @@ -169,9 +168,9 @@ private: close(fd); } - lseek(outfd, 0, 0); + lseek(outfd.get(), 0, SEEK_SET); response.data.push_back(CMD_JOIN); - response.fds.push_back(outfd); + response.fds.push_back(outfd.get()); ret = ipc_.send(response); if (ret < 0) { @@ -179,8 +178,6 @@ private: stop(ret); } - close(outfd); - break; } @@ -315,22 +312,21 @@ protected: "Foo", "Bar", }; - int fds[2]; + std::array<UniqueFD, 2> fds; for (unsigned int i = 0; i < std::size(strings); i++) { unsigned int len = strlen(strings[i]); - fds[i] = open("/tmp", O_TMPFILE | O_RDWR, - S_IRUSR | S_IWUSR); - if (fds[i] < 0) + fds[i] = test::createTemporaryFile(); + if (!fds[i].isValid()) return TestFail; - ret = write(fds[i], strings[i], len); + ret = write(fds[i].get(), strings[i], len); if (ret < 0) return TestFail; - lseek(fds[i], 0, 0); - message.fds.push_back(fds[i]); + lseek(fds[i].get(), 0, SEEK_SET); + message.fds.push_back(fds[i].get()); } message.data.push_back(CMD_JOIN); @@ -343,8 +339,6 @@ protected: unsigned int len = strlen(strings[i]); std::vector<char> buf(len); - close(fds[i]); - if (read(response.fds[0], buf.data(), len) <= 0) return TestFail; diff --git a/test/libtest/meson.build b/test/libtest/meson.build index 351629f3c..fd89f8047 100644 --- a/test/libtest/meson.build +++ b/test/libtest/meson.build @@ -3,6 +3,7 @@ libtest_sources = files([ 'buffer_source.cpp', 'camera_test.cpp', + 'misc.cpp', 'test.cpp', ]) diff --git a/test/libtest/misc.cpp b/test/libtest/misc.cpp new file mode 100644 index 000000000..d4506c869 --- /dev/null +++ b/test/libtest/misc.cpp @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2026, Ideas on Board Oy + * + * libcamera test miscellaneous utilities + */ + +#include "misc.h" + +#include <libcamera/base/memfd.h> + +namespace test { + +libcamera::UniqueFD createTemporaryFile() +{ + return libcamera::MemFd::create("libcamera-test-temporary-file", 0); +} + +} /* namespace test */ diff --git a/test/libtest/misc.h b/test/libtest/misc.h new file mode 100644 index 000000000..a7b4acbeb --- /dev/null +++ b/test/libtest/misc.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2026, Ideas on Board Oy + * + * libcamera test miscellaneous utilities + */ + +#pragma once + +#include <libcamera/base/unique_fd.h> + +namespace test { + +[[nodiscard]] +libcamera::UniqueFD createTemporaryFile(); + +} diff --git a/test/log/log_api.cpp b/test/log/log_api.cpp index 8d19cf0ce..684abf8b8 100644 --- a/test/log/log_api.cpp +++ b/test/log/log_api.cpp @@ -20,6 +20,7 @@ #include <libcamera/logging.h> +#include "misc.h" #include "test.h" using namespace std; @@ -109,18 +110,17 @@ protected: int testFile() { - int fd = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); - if (fd < 0) { + auto fd = test::createTemporaryFile(); + if (!fd.isValid()) { cerr << "Failed to open tmp log file" << endl; return TestFail; } char path[32]; - snprintf(path, sizeof(path), "/proc/self/fd/%u", fd); + snprintf(path, sizeof(path), "/proc/self/fd/%u", fd.get()); if (logSetFile(path) < 0) { cerr << "Failed to set log file" << endl; - close(fd); return TestFail; } @@ -128,13 +128,11 @@ protected: char buf[1000]; memset(buf, 0, sizeof(buf)); - lseek(fd, 0, SEEK_SET); - if (read(fd, buf, sizeof(buf)) < 0) { + lseek(fd.get(), 0, SEEK_SET); + if (read(fd.get(), buf, sizeof(buf)) < 0) { cerr << "Failed to read tmp log file" << endl; - close(fd); return TestFail; } - close(fd); istringstream iss(buf); return verifyOutput(iss); diff --git a/test/shared-fd.cpp b/test/shared-fd.cpp index 57199dfe7..26e3140ad 100644 --- a/test/shared-fd.cpp +++ b/test/shared-fd.cpp @@ -14,6 +14,7 @@ #include <libcamera/base/shared_fd.h> #include <libcamera/base/utils.h> +#include "misc.h" #include "test.h" using namespace libcamera; @@ -27,7 +28,7 @@ protected: desc1_ = nullptr; desc2_ = nullptr; - fd_ = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); + fd_ = test::createTemporaryFile().release(); if (fd_ < 0) return TestFail; diff --git a/test/unique-fd.cpp b/test/unique-fd.cpp index e556439ea..280205980 100644 --- a/test/unique-fd.cpp +++ b/test/unique-fd.cpp @@ -14,6 +14,7 @@ #include <libcamera/base/unique_fd.h> #include <libcamera/base/utils.h> +#include "misc.h" #include "test.h" using namespace libcamera; @@ -189,7 +190,7 @@ protected: private: int createFd() { - fd_ = open("/tmp", O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR); + fd_ = test::createTemporaryFile().release(); if (fd_ < 0) return TestFail;
`O_TMPFILE` requires file system support, which may not be available in certain environments, usually containerized ones. So do not use it. A new function is added for tests to be able to create unnamed temporary files using `libcamera::MemFd` as the implementation. Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> --- changes in v2: * add function to create unnamed temporary files v1: https://patchwork.libcamera.org/patch/26010/ --- test/ipc/unixsocket.cpp | 34 ++++++++++++++-------------------- test/libtest/meson.build | 1 + test/libtest/misc.cpp | 19 +++++++++++++++++++ test/libtest/misc.h | 17 +++++++++++++++++ test/log/log_api.cpp | 14 ++++++-------- test/shared-fd.cpp | 3 ++- test/unique-fd.cpp | 3 ++- 7 files changed, 61 insertions(+), 30 deletions(-) create mode 100644 test/libtest/misc.cpp create mode 100644 test/libtest/misc.h -- 2.52.0