mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-26 05:56:14 +01:00
tests/gutils-user-database: Fix test on macOS
Use DYLD interposing on macOS
This commit is contained in:
parent
91b41f5234
commit
991cb9ef8c
@ -25,57 +25,67 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#undef getpwuid
|
#ifndef __APPLE__
|
||||||
|
|
||||||
static struct passwd my_pw;
|
#define GET_REAL(func) \
|
||||||
|
(real_##func = dlsym (RTLD_NEXT, #func))
|
||||||
|
|
||||||
|
#define DEFINE_WRAPPER(return_type, func, argument_list) \
|
||||||
|
static return_type (* real_##func) argument_list; \
|
||||||
|
return_type func argument_list
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define GET_REAL(func) \
|
||||||
|
func
|
||||||
|
|
||||||
|
/* https://opensource.apple.com/source/dyld/dyld-852.2/include/mach-o/dyld-interposing.h */
|
||||||
|
#define DYLD_INTERPOSE(_replacement,_replacee) \
|
||||||
|
__attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \
|
||||||
|
__attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee };
|
||||||
|
|
||||||
|
#define DEFINE_WRAPPER(return_type, func, argument_list) \
|
||||||
|
static return_type wrap_##func argument_list; \
|
||||||
|
DYLD_INTERPOSE(wrap_##func, func) \
|
||||||
|
static return_type wrap_##func argument_list
|
||||||
|
|
||||||
|
#endif /* __APPLE__ */
|
||||||
|
|
||||||
/* This is used in gutils.c used to make sure utility functions
|
/* This is used in gutils.c used to make sure utility functions
|
||||||
* handling user information do not crash on bad data (for example
|
* handling user information do not crash on bad data (for example
|
||||||
* caused by getpwuid returning some NULL elements.
|
* caused by getpwuid returning some NULL elements.
|
||||||
*/
|
*/
|
||||||
struct passwd *
|
|
||||||
getpwuid (uid_t uid)
|
#undef getpwuid
|
||||||
|
|
||||||
|
static struct passwd my_pw;
|
||||||
|
|
||||||
|
DEFINE_WRAPPER (struct passwd *, getpwuid, (uid_t uid))
|
||||||
{
|
{
|
||||||
static struct passwd *(*real_getpwuid) (uid_t);
|
struct passwd *pw = GET_REAL (getpwuid) (uid);
|
||||||
struct passwd *pw;
|
|
||||||
|
|
||||||
if (real_getpwuid == NULL)
|
|
||||||
real_getpwuid = dlsym (RTLD_NEXT, "getpwuid");
|
|
||||||
|
|
||||||
pw = real_getpwuid (uid);
|
|
||||||
my_pw = *pw;
|
my_pw = *pw;
|
||||||
my_pw.pw_name = NULL;
|
my_pw.pw_name = NULL;
|
||||||
return &my_pw;
|
return &my_pw;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
DEFINE_WRAPPER (int, getpwnam_r, (const char *name,
|
||||||
getpwnam_r (const char *name, struct passwd *pwd, char buf[], size_t buflen, struct passwd **result)
|
struct passwd *pwd,
|
||||||
|
char buf[],
|
||||||
|
size_t buflen,
|
||||||
|
struct passwd **result))
|
||||||
{
|
{
|
||||||
int code;
|
int code = GET_REAL (getpwnam_r) (name, pwd, buf, buflen, result);
|
||||||
|
|
||||||
int (*real_getpwnam_r) (const char *,
|
|
||||||
struct passwd *,
|
|
||||||
char[],
|
|
||||||
size_t,
|
|
||||||
struct passwd **) = dlsym (RTLD_NEXT, "getpwnam_r");
|
|
||||||
|
|
||||||
code = real_getpwnam_r (name, pwd, buf, buflen, result);
|
|
||||||
pwd->pw_name = NULL;
|
pwd->pw_name = NULL;
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
DEFINE_WRAPPER (int, getpwuid_r, (uid_t uid,
|
||||||
getpwuid_r (uid_t uid, struct passwd *restrict pwd, char buf[], size_t buflen, struct passwd **result)
|
struct passwd *restrict pwd,
|
||||||
|
char buf[],
|
||||||
|
size_t buflen,
|
||||||
|
struct passwd **result))
|
||||||
{
|
{
|
||||||
int code;
|
int code = GET_REAL (getpwuid_r) (uid, pwd, buf, buflen, result);
|
||||||
|
|
||||||
int (*real_getpwuid_r) (uid_t,
|
|
||||||
struct passwd *,
|
|
||||||
char[],
|
|
||||||
size_t,
|
|
||||||
struct passwd **) = dlsym (RTLD_NEXT, "getpwuid_r");
|
|
||||||
|
|
||||||
code = real_getpwuid_r (uid, pwd, buf, buflen, result);
|
|
||||||
pwd->pw_name = NULL;
|
pwd->pw_name = NULL;
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
@ -234,14 +234,20 @@ else
|
|||||||
install_tag : 'tests',
|
install_tag : 'tests',
|
||||||
install: installed_tests_enabled)
|
install: installed_tests_enabled)
|
||||||
|
|
||||||
|
if host_system not in ['ios', 'darwin']
|
||||||
|
var_preload = 'LD_PRELOAD'
|
||||||
|
else
|
||||||
|
var_preload = 'DYLD_INSERT_LIBRARIES'
|
||||||
|
endif
|
||||||
|
|
||||||
glib_tests += {
|
glib_tests += {
|
||||||
'gutils-user-database' : {
|
'gutils-user-database' : {
|
||||||
'depends' : [],
|
'depends' : [],
|
||||||
'env' : {
|
'env' : {
|
||||||
'LD_PRELOAD': getpwuid_preload.full_path()
|
var_preload: getpwuid_preload.full_path()
|
||||||
},
|
},
|
||||||
'installed_tests_env' : {
|
'installed_tests_env' : {
|
||||||
'LD_PRELOAD': installed_tests_execdir / fs.name(getpwuid_preload.full_path())
|
var_preload: installed_tests_execdir / fs.name(getpwuid_preload.full_path())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user