The ksft_exit_fail_perror function previously only accepted a single string
argument, which limited its flexibility for providing specific context to
failure messages.
This change updates ksft_exit_fail_perror to support variable arguments,
similar to ksft_exit_fail_msg. Adding the __printf(1, 2) attribute enables
compile-time checking for format string correctness.
Signed-off-by: Chunyu Hu <chuhu@redhat.com>
---
Changes in v7:
- new patch to convert ksft_exit_fail_perror support variable arguments
---
tools/testing/selftests/kselftest.h | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
index afbcf8412ae5..11cabdabb3f6 100644
--- a/tools/testing/selftests/kselftest.h
+++ b/tools/testing/selftests/kselftest.h
@@ -43,7 +43,7 @@
* the program is aborting before finishing all tests):
*
* ksft_exit_fail_msg(fmt, ...);
- * ksft_exit_fail_perror(msg);
+ * ksft_exit_fail_perror(fmt, ...);
*
*/
#ifndef __KSELFTEST_H
@@ -417,9 +417,24 @@ static inline __noreturn __printf(1, 2) void ksft_exit_fail_msg(const char *msg,
exit(KSFT_FAIL);
}
-static inline __noreturn void ksft_exit_fail_perror(const char *msg)
+static inline __noreturn __printf(1, 2) void ksft_exit_fail_perror(const char *msg, ...)
{
- ksft_exit_fail_msg("%s: %s (%d)\n", msg, strerror(errno), errno);
+ va_list args;
+ char *buf = NULL;
+ int saved_errno = errno;
+
+ va_start(args, msg);
+ if (vasprintf(&buf, msg, args) == -1) {
+ va_end(args);
+ ksft_exit_fail_msg("vasprintf failed: %s (%d)\n", strerror(saved_errno),
+ saved_errno);
+ }
+ va_end(args);
+
+ errno = saved_errno;
+ ksft_exit_fail_msg("%s: %s (%d)\n", buf, strerror(errno), errno);
+
+ free(buf);
}
static inline __noreturn void ksft_exit_xfail(void)
--
2.53.0
On Mon, Mar 30, 2026 at 11:15:00PM +0800, Chunyu Hu wrote:
> The ksft_exit_fail_perror function previously only accepted a single string
> argument, which limited its flexibility for providing specific context to
> failure messages.
>
> This change updates ksft_exit_fail_perror to support variable arguments,
> similar to ksft_exit_fail_msg. Adding the __printf(1, 2) attribute enables
> compile-time checking for format string correctness.
>
> Signed-off-by: Chunyu Hu <chuhu@redhat.com>
> ---
> Changes in v7:
> - new patch to convert ksft_exit_fail_perror support variable arguments
> ---
> tools/testing/selftests/kselftest.h | 21 ++++++++++++++++++---
> 1 file changed, 18 insertions(+), 3 deletions(-)
>
> diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
> index afbcf8412ae5..11cabdabb3f6 100644
> --- a/tools/testing/selftests/kselftest.h
> +++ b/tools/testing/selftests/kselftest.h
> @@ -43,7 +43,7 @@
> * the program is aborting before finishing all tests):
> *
> * ksft_exit_fail_msg(fmt, ...);
> - * ksft_exit_fail_perror(msg);
> + * ksft_exit_fail_perror(fmt, ...);
> *
> */
> #ifndef __KSELFTEST_H
> @@ -417,9 +417,24 @@ static inline __noreturn __printf(1, 2) void ksft_exit_fail_msg(const char *msg,
> exit(KSFT_FAIL);
> }
>
> -static inline __noreturn void ksft_exit_fail_perror(const char *msg)
> +static inline __noreturn __printf(1, 2) void ksft_exit_fail_perror(const char *msg, ...)
> {
> - ksft_exit_fail_msg("%s: %s (%d)\n", msg, strerror(errno), errno);
> + va_list args;
> + char *buf = NULL;
> + int saved_errno = errno;
> +
> + va_start(args, msg);
> + if (vasprintf(&buf, msg, args) == -1) {
kernel test robot reported compile error on this, as the vasprintf
required _GNU_SOURCE. Looks like it's not appropriate to be used
in the common header. Looks like it can be replaced with a buf and
vsnprintf instead.
char buf[512];
va_start(args, msg);
vsnprintf(buf, sizeof(buf), msg, args);
```
In file included from za-fork.c:12:
../../kselftest.h: In function 'ksft_exit_fail_perror':
>> ../../kselftest.h:427:13: error: implicit declaration of function 'vasprintf'; did you mean 'vsprintf'? [-Wimplicit-function-declaration]
427 | if (vasprintf(&buf, msg, args) == -1) {
| ^~~~~~~~~
| vsprintf
--
In file included from basic-gcs.c:16:
tools/testing/selftests/kselftest.h: In function 'ksft_exit_fail_perror':
>> tools/testing/selftests/kselftest.h:427:13: error: implicit declaration of function 'vasprintf'; did you mean 'vsprintf'? [-Wimplicit-function-declaration]
427 | if (vasprintf(&buf, msg, args) == -1) {
| ^~~~~~~~~
| vsprintf
```
> + va_end(args);
> + ksft_exit_fail_msg("vasprintf failed: %s (%d)\n", strerror(saved_errno),
> + saved_errno);
> + }
> + va_end(args);
> +
> + errno = saved_errno;
> + ksft_exit_fail_msg("%s: %s (%d)\n", buf, strerror(errno), errno);
> +
> + free(buf);
> }
>
> static inline __noreturn void ksft_exit_xfail(void)
> --
> 2.53.0
>
On Tue, 31 Mar 2026 18:31:42 +0800 Chunyu Hu <chuhu@redhat.com> wrote:
> > - ksft_exit_fail_msg("%s: %s (%d)\n", msg, strerror(errno), errno);
> > + va_list args;
> > + char *buf = NULL;
> > + int saved_errno = errno;
> > +
> > + va_start(args, msg);
> > + if (vasprintf(&buf, msg, args) == -1) {
>
> kernel test robot reported compile error on this, as the vasprintf
> required _GNU_SOURCE. Looks like it's not appropriate to be used
> in the common header. Looks like it can be replaced with a buf and
> vsnprintf instead.
I like vasprintf()!
"#define _GNU_SOURCE" occurs 402 times in selftests/, so perhaps we can
find a way to keep it?
(err, *why* 402 times? Can't it be just once?)
© 2016 - 2026 Red Hat, Inc.