[v2] test: Remove uses of `O_TMPFILE`
diff mbox series

Message ID 20260129110007.1221054-1-barnabas.pocze@ideasonboard.com
State Accepted
Headers show
Series
  • [v2] test: Remove uses of `O_TMPFILE`
Related show

Commit Message

Barnabás Pőcze Jan. 29, 2026, 11 a.m. UTC
`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

Comments

Laurent Pinchart Jan. 29, 2026, 3:16 p.m. UTC | #1
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;
>
Paul Elder Feb. 9, 2026, 12:15 a.m. UTC | #2
Quoting Barnabás Pőcze (2026-01-29 20:00:07)
> `O_TMPFILE` requires file system support, which may not be available in
> certain environments, usually containerized ones. So do not use it.

Ah, I hadn't realized that.

> 
> A new function is added for tests to be able to create unnamed temporary
> files using `libcamera::MemFd` as the implementation.

Oh neat!

> 
> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>

With the changes Laurent suggested,

Reviewed-by: Paul Elder <paul.elder@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();
> +                       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;
> 
> --
> 2.52.0
Barnabás Pőcze Feb. 9, 2026, 10:05 a.m. UTC | #3
2026. 01. 29. 16:16 keltezéssel, Laurent Pinchart írta:
> 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 = ...

Ok.


> 
>> +			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.

I'll move it.


> 
>> 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 = ...

Ok.


> 
> 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;
>>
>

Patch
diff mbox series

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;