mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-12-09 12:24:35 +03:00
In some cases (well, majority), open() is either rewritten to open64(), either by plain '#define open open64') or at assembly level (using __REDIRECT macro). See <fcntl.h> for more info. This didn't really matter to us, because we do not chain load two mocks that would need to reimplement open() at the same time. But this is soon going to change. The problem is, that VIR_MOCK_REAL_INIT(open) glances over aforementioned rewrite and initializes real_open pointer to open() from the standard C library. But it needs to point to open() (well, open64()) from the next mock on the list. Therefore, init real_open to open64(). But of course, this is all glibc specific and for example musl does the oposite (#define open64 open). Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
161 lines
3.4 KiB
C
161 lines
3.4 KiB
C
/*
|
|
* Copyright (C) 2016 Red Hat, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see
|
|
* <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#ifdef WITH_NSS
|
|
# include "virmock.h"
|
|
# include <sys/types.h>
|
|
# include <dirent.h>
|
|
# include <sys/stat.h>
|
|
# include <fcntl.h>
|
|
# include <unistd.h>
|
|
|
|
# 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);
|
|
|
|
# define LEASEDIR LOCALSTATEDIR "/lib/libvirt/dnsmasq/"
|
|
|
|
/*
|
|
* Functions to load the symbols and init the environment
|
|
*/
|
|
static void
|
|
init_syms(void)
|
|
{
|
|
if (real_open)
|
|
return;
|
|
|
|
# if defined(__GLIBC__) && defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
|
|
VIR_MOCK_REAL_INIT_ALIASED(open, "open64");
|
|
# else
|
|
VIR_MOCK_REAL_INIT(open);
|
|
# endif
|
|
# if WITH___OPEN_2
|
|
VIR_MOCK_REAL_INIT(__open_2);
|
|
# endif
|
|
VIR_MOCK_REAL_INIT(opendir);
|
|
VIR_MOCK_REAL_INIT(access);
|
|
}
|
|
|
|
static int
|
|
getrealpath(char **newpath,
|
|
const char *path)
|
|
{
|
|
if (STRPREFIX(path, LEASEDIR)) {
|
|
*newpath = g_strdup_printf("%s/nssdata/%s",
|
|
abs_srcdir,
|
|
path + strlen(LEASEDIR));
|
|
} else {
|
|
*newpath = g_strdup(path);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
open(const char *path, int flags, ...)
|
|
{
|
|
int ret;
|
|
char *newpath = NULL;
|
|
|
|
init_syms();
|
|
|
|
if (STRPREFIX(path, LEASEDIR) &&
|
|
getrealpath(&newpath, path) < 0)
|
|
return -1;
|
|
|
|
if (flags & O_CREAT) {
|
|
va_list ap;
|
|
mode_t mode;
|
|
va_start(ap, flags);
|
|
mode = (mode_t) va_arg(ap, int);
|
|
va_end(ap);
|
|
ret = real_open(newpath ? newpath : path, flags, mode);
|
|
} else {
|
|
ret = real_open(newpath ? newpath : path, flags);
|
|
}
|
|
|
|
free(newpath);
|
|
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)
|
|
{
|
|
DIR *ret;
|
|
char *newpath = NULL;
|
|
|
|
init_syms();
|
|
|
|
if (STRPREFIX(path, LEASEDIR) &&
|
|
getrealpath(&newpath, path) < 0)
|
|
return NULL;
|
|
|
|
ret = real_opendir(newpath ? newpath : path);
|
|
|
|
free(newpath);
|
|
return ret;
|
|
}
|
|
|
|
int
|
|
access(const char *path, int mode)
|
|
{
|
|
int ret;
|
|
char *newpath = NULL;
|
|
|
|
init_syms();
|
|
|
|
if (STRPREFIX(path, LEASEDIR) &&
|
|
getrealpath(&newpath, path) < 0)
|
|
return -1;
|
|
|
|
ret = real_access(newpath ? newpath : path, mode);
|
|
|
|
free(newpath);
|
|
return ret;
|
|
}
|
|
#else
|
|
/* Nothing to override if NSS plugin is not enabled */
|
|
#endif
|