From d6faad7de2bdbff18da4c5379e97871ec3839e7f Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Sat, 22 Nov 2025 15:32:08 +0000 Subject: [PATCH] test/getrandom-fallbacks: fix open shim types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In C, functions taking a variable number of arguments are not guaranteed to have the same calling convention as functions taking a fixed number of arguments [^0]. Since `open()` and `open64()` are defined as taking a variable number of arguments, the `__wrap_open()` and `__wrap_open64()` mocks must be as well. [^0]: C23 §6.7.7.4¶14 says: "For two function types to be compatible, both shall specify compatible return types. Moreover, the parameter type lists shall agree in the number of parameters and in use of the final ellipsis; corresponding parameters shall have compatible types." This fixes the test on my powerpc64el machine building nixpkgs a8d610af3f1. --- test/getrandom-fallbacks.c | 46 +++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/test/getrandom-fallbacks.c b/test/getrandom-fallbacks.c index b124c181..4048ae29 100644 --- a/test/getrandom-fallbacks.c +++ b/test/getrandom-fallbacks.c @@ -151,13 +151,38 @@ __wrap_syscall(long number, ...) there's no way to _clear_ that flag again. This test chooses to exercise the read-failure path, not the open-failure path. */ #if defined HAVE_SYS_STAT_H && defined HAVE_FCNTL_H && defined HAVE_UNISTD_H + +static bool open_needs_mode(int flags) +{ + if (flags & O_CREAT) + { + return true; + } +#if defined(O_TMPFILE) + if ((flags & O_TMPFILE) == O_TMPFILE) + { + return true; + } +#endif + return false; +} + static bool urandom_should_fail = false; static int urandom_fd = -1; -extern int __wrap_open (const char *, int, mode_t); -extern int __real_open (const char *, int, mode_t); +extern int __wrap_open (const char *, int, ...); +extern int __real_open (const char *, int, ...); int -__wrap_open (const char *path, int flags, mode_t mode) +__wrap_open (const char *path, int flags, ...) { + int mode = 0; + if (open_needs_mode(flags)) + { + va_list args; + va_start(args, flags); + mode = va_arg(args, int); + va_end(args); + } + int ret = __real_open (path, flags, mode); if (ret == -1) return ret; @@ -167,11 +192,20 @@ __wrap_open (const char *path, int flags, mode_t mode) } #ifdef HAVE_OPEN64 -extern int __wrap_open64 (const char *, int, mode_t); -extern int __real_open64 (const char *, int, mode_t); +extern int __wrap_open64 (const char *, int, ...); +extern int __real_open64 (const char *, int, ...); int -__wrap_open64 (const char *path, int flags, mode_t mode) +__wrap_open64 (const char *path, int flags, ...) { + int mode = 0; + if (open_needs_mode(flags)) + { + va_list args; + va_start(args, flags); + mode = va_arg(args, int); + va_end(args); + } + int ret = __real_open64 (path, flags, mode); if (ret == -1) return ret;