diff --git a/meson.build b/meson.build index 9842886bbb..b1b55b0d25 100644 --- a/meson.build +++ b/meson.build @@ -604,6 +604,12 @@ stat_functions = [ functions += stat_functions +open_functions = [ + '__open_2', +] + +functions += open_functions + foreach function : functions if cc.has_function(function) conf.set('WITH_@0@'.format(function.to_upper()), 1) @@ -618,6 +624,13 @@ foreach function : stat_functions endforeach +foreach function : open_functions + if cc.has_header_symbol('fcntl.h', function) + conf.set('WITH_@0@_DECL'.format(function.to_upper()), 1) + endif +endforeach + + # various header checks headers = [ diff --git a/tests/nssmock.c b/tests/nssmock.c index 9ead6d8f97..3493119f3b 100644 --- a/tests/nssmock.c +++ b/tests/nssmock.c @@ -29,6 +29,9 @@ # include "configmake.h" static int (*real_open)(const char *path, int flags, ...); +# if WITH___OPEN_2 +static int (*real___open_2)(const char *path, int flags); +# endif static DIR * (*real_opendir)(const char *name); static int (*real_access)(const char *path, int mode); @@ -44,6 +47,9 @@ init_syms(void) return; VIR_MOCK_REAL_INIT(open); +# if WITH___OPEN_2 + VIR_MOCK_REAL_INIT(__open_2); +# endif VIR_MOCK_REAL_INIT(opendir); VIR_MOCK_REAL_INIT(access); } @@ -90,6 +96,26 @@ open(const char *path, int flags, ...) return ret; } +# if WITH___OPEN_2 +int +__open_2(const char *path, int flags) +{ + int ret; + char *newpath = NULL; + + init_syms(); + + if (STRPREFIX(path, LEASEDIR) && + getrealpath(&newpath, path) < 0) + return -1; + + ret = real___open_2(newpath ? newpath : path, flags); + + free(newpath); + return ret; +} +# endif + DIR * opendir(const char *path) { diff --git a/tests/qemusecuritymock.c b/tests/qemusecuritymock.c index a6f9d6b917..80d59536b1 100644 --- a/tests/qemusecuritymock.c +++ b/tests/qemusecuritymock.c @@ -58,6 +58,9 @@ static int (*real_chown)(const char *path, uid_t uid, gid_t gid); static int (*real_open)(const char *path, int flags, ...); +#if WITH___OPEN_2 +static int (*real___open_2)(const char *path, int flags); +#endif static int (*real_close)(int fd); #ifdef WITH_SELINUX static int (*real_setfilecon_raw)(const char *path, const char *context); @@ -112,6 +115,9 @@ init_syms(void) VIR_MOCK_REAL_INIT(chown); VIR_MOCK_REAL_INIT(open); +#if WITH___OPEN_2 + VIR_MOCK_REAL_INIT(__open_2); +#endif VIR_MOCK_REAL_INIT(close); #ifdef WITH_SELINUX VIR_MOCK_REAL_INIT(setfilecon_raw); @@ -324,6 +330,24 @@ open(const char *path, int flags, ...) } +#if WITH___OPEN_2 +int +__open_2(const char *path, int flags) +{ + int ret; + + init_syms(); + + if (getenv(ENVVAR)) { + ret = 42; /* Some dummy FD */ + } else { + ret = real___open_2(path, flags); + } + + return ret; +} +#endif + int close(int fd) { diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c index 777d60b152..d922f30f34 100644 --- a/tests/vircgroupmock.c +++ b/tests/vircgroupmock.c @@ -30,6 +30,9 @@ # include "vircgroupv2devices.h" static int (*real_open)(const char *path, int flags, ...); +# if WITH___OPEN_2 +static int (*real___open_2)(const char *path, int flags); +# endif static FILE *(*real_fopen)(const char *path, const char *mode); static int (*real_access)(const char *path, int mode); static int (*real_mkdir)(const char *path, mode_t mode); @@ -302,6 +305,9 @@ static void init_syms(void) VIR_MOCK_REAL_INIT(access); VIR_MOCK_REAL_INIT(mkdir); VIR_MOCK_REAL_INIT(open); +# if WITH___OPEN_2 + VIR_MOCK_REAL_INIT(__open_2); +# endif } @@ -589,6 +595,42 @@ int open(const char *path, int flags, ...) return ret; } +# if WITH___OPEN_2 +int +__open_2(const char *path, int flags) +{ + int ret; + char *newpath = NULL; + + init_syms(); + + if (STREQ(path, SYSFS_CPU_PRESENT)) { + init_sysfs(); + if (asprintf(&newpath, "%s/%s", + fakesysfscgroupdir, + SYSFS_CPU_PRESENT_MOCKED) < 0) { + errno = ENOMEM; + return -1; + } + } + + if (STRPREFIX(path, SYSFS_CGROUP_PREFIX)) { + init_sysfs(); + if (asprintf(&newpath, "%s%s", + fakesysfscgroupdir, + path + strlen(SYSFS_CGROUP_PREFIX)) < 0) { + errno = ENOMEM; + return -1; + } + } + + ret = real___open_2(newpath ? newpath : path, flags); + + free(newpath); + return ret; +} +# endif + bool virCgroupV2DevicesAvailable(virCgroup *group G_GNUC_UNUSED) { diff --git a/tests/virfilewrapper.c b/tests/virfilewrapper.c index 9cdfcfdc3f..908f7142c2 100644 --- a/tests/virfilewrapper.c +++ b/tests/virfilewrapper.c @@ -38,6 +38,9 @@ static const char **prefixes; /* TODO: callbacks */ static int (*real_open)(const char *path, int flags, ...); +# if WITH___OPEN_2 +static int (*real___open_2)(const char *path, int flags); +# endif static FILE *(*real_fopen)(const char *path, const char *mode); static int (*real_access)(const char *path, int mode); static int (*real_mkdir)(const char *path, mode_t mode); @@ -54,6 +57,9 @@ static void init_syms(void) VIR_MOCK_REAL_INIT(access); VIR_MOCK_REAL_INIT(mkdir); VIR_MOCK_REAL_INIT(open); +# if WITH___OPEN_2 + VIR_MOCK_REAL_INIT(__open_2); +# endif # if defined(__APPLE__) && defined(__x86_64__) VIR_MOCK_REAL_INIT_ALIASED(opendir, "opendir$INODE64"); # else @@ -176,6 +182,18 @@ int open(const char *path, int flags, ...) return real_open(newpath ? newpath : path, flags, mode); } +# if WITH___OPEN_2 +int +__open_2(const char *path, int flags) +{ + g_autofree char *newpath = NULL; + + PATH_OVERRIDE(newpath, path); + + return real___open_2(newpath ? newpath : path, flags); +} +# endif + DIR *opendir(const char *path) { g_autofree char *newpath = NULL; diff --git a/tests/virmock.h b/tests/virmock.h index 300ba17174..178d0a15f0 100644 --- a/tests/virmock.h +++ b/tests/virmock.h @@ -27,6 +27,10 @@ #include "internal.h" +#ifndef WITH___OPEN_2_DECL +int __open_2 (const char *__path, int __oflag); +#endif + #define VIR_MOCK_COUNT_ARGS(...) VIR_MOCK_ARG27(__VA_ARGS__, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) #define VIR_MOCK_ARG27(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, ...) _27 #define VIR_MOCK_ARG_PASTE(a, b, ...) a##b(__VA_ARGS__) diff --git a/tests/virpcimock.c b/tests/virpcimock.c index 2f98b0cf13..5b923c63ce 100644 --- a/tests/virpcimock.c +++ b/tests/virpcimock.c @@ -36,9 +36,9 @@ static int (*real_access)(const char *path, int mode); static int (*real_open)(const char *path, int flags, ...); -# ifdef __GLIBC__ +# if WITH___OPEN_2 static int (*real___open_2)(const char *path, int flags); -# endif /* ! __GLIBC__ */ +# endif /* ! WITH___OPEN_2 */ static int (*real_close)(int fd); static DIR * (*real_opendir)(const char *name); static char *(*real_virFileCanonicalizePath)(const char *path); @@ -945,9 +945,9 @@ init_syms(void) VIR_MOCK_REAL_INIT(access); VIR_MOCK_REAL_INIT(open); -# ifdef __GLIBC__ +# if WITH___OPEN_2 VIR_MOCK_REAL_INIT(__open_2); -# endif /* ! __GLIBC__ */ +# endif /* WITH___OPEN_2 */ VIR_MOCK_REAL_INIT(close); # if defined(__APPLE__) && defined(__x86_64__) VIR_MOCK_REAL_INIT_ALIASED(opendir, "opendir$INODE64"); @@ -1110,12 +1110,7 @@ open(const char *path, int flags, ...) } -# ifdef __GLIBC__ -/* in some cases this function may not be present in headers, so we need - * a declaration to silence the compiler */ -int -__open_2(const char *path, int flags); - +# if WITH___OPEN_2 int __open_2(const char *path, int flags) { @@ -1139,7 +1134,7 @@ __open_2(const char *path, int flags) return ret; } -# endif /* ! __GLIBC__ */ +# endif /* WITH___OPEN_2 */ DIR * opendir(const char *path) diff --git a/tests/virtestmock.c b/tests/virtestmock.c index 19559aee7a..5b25b380e5 100644 --- a/tests/virtestmock.c +++ b/tests/virtestmock.c @@ -29,6 +29,9 @@ #include "virfile.h" static int (*real_open)(const char *path, int flags, ...); +#if WITH___OPEN_2 +static int (*real___open_2)(const char *path, int flags); +#endif static FILE *(*real_fopen)(const char *path, const char *mode); static int (*real_access)(const char *path, int mode); static int (*real_connect)(int fd, const struct sockaddr *addr, socklen_t addrlen); @@ -44,6 +47,9 @@ static void init_syms(void) return; VIR_MOCK_REAL_INIT(open); +#if WITH___OPEN_2 + VIR_MOCK_REAL_INIT(__open_2); +#endif VIR_MOCK_REAL_INIT(fopen); VIR_MOCK_REAL_INIT(access); VIR_MOCK_REAL_INIT(connect); @@ -153,6 +159,20 @@ int open(const char *path, int flags, ...) return ret; } + +#if WITH___OPEN_2 +int +__open_2(const char *path, int flags) +{ + init_syms(); + + CHECK_PATH(path); + + return real___open_2(path, flags); +} +#endif + + FILE *fopen(const char *path, const char *mode) { init_syms(); diff --git a/tests/virusbmock.c b/tests/virusbmock.c index 570f7c28eb..e148296b7c 100644 --- a/tests/virusbmock.c +++ b/tests/virusbmock.c @@ -30,6 +30,9 @@ #define FAKE_USB_SYSFS "virusbtestdata/sys_bus_usb" static int (*real_open)(const char *pathname, int flags, ...); +#if WITH___OPEN_2 +static int (*real___open_2)(const char *path, int flags); +#endif static DIR *(*real_opendir)(const char *name); static void init_syms(void) @@ -38,6 +41,9 @@ static void init_syms(void) return; VIR_MOCK_REAL_INIT(open); +#if WITH___OPEN_2 + VIR_MOCK_REAL_INIT(__open_2); +#endif VIR_MOCK_REAL_INIT(opendir); } @@ -90,3 +96,19 @@ int open(const char *pathname, int flags, ...) ret = real_open(path, flags, mode); return ret; } + +#if WITH___OPEN_2 +int +__open_2(const char *pathname, int flags) +{ + g_autofree char *path = NULL; + + init_syms(); + + path = get_fake_path(pathname); + if (!path) + return -1; + + return real_open(path, flags); +} +#endif