diff options
Diffstat (limited to 'lib/intercept')
-rw-r--r-- | lib/intercept/intercept.cpp | 15 | ||||
-rw-r--r-- | lib/intercept/intercept.h | 21 |
2 files changed, 31 insertions, 5 deletions
diff --git a/lib/intercept/intercept.cpp b/lib/intercept/intercept.cpp index 7a33b610..72bd8d4e 100644 --- a/lib/intercept/intercept.cpp +++ b/lib/intercept/intercept.cpp @@ -15,7 +15,6 @@ #include <sys/syscall.h> #endif #include <sys/types.h> -#include <unistd.h> #ifdef HAVE_SYS_UIO_H #include <sys/uio.h> @@ -132,7 +131,7 @@ void intercept_setup_error(const char *filename, unsigned int errorafter, int er intercept_delay_ms = 0; } -void intercept_setup_delay(const char *filename, unsigned int delay_after, +void intercept_setup_delay(const char *filename, unsigned int delay_after, int delay_ms, int syscall_to_delay, int num_delays) { BOX_TRACE("Setup for delay: " << filename << @@ -243,6 +242,10 @@ extern "C" int open(const char *path, int flags, ...) #endif // DEFINE_ONLY_OPEN64 { + // Some newer architectures don't have an open() syscall, but use openat() instead. + // In these cases we will need to call sys_openat() instead of sys_open(). + // https://chromium.googlesource.com/linux-syscall-support/ + if(intercept_count > 0) { if(intercept_filename != NULL && @@ -265,6 +268,8 @@ extern "C" int #ifdef PLATFORM_NO_SYSCALL int r = TEST_open(path, flags, mode); +#elif HAVE_DECL_SYS_OPENAT && !HAVE_DECL_SYS_OPEN + int r = syscall(SYS_openat, AT_FDCWD, path, flags, mode); #else int r = syscall(SYS_open, path, flags, mode); #endif @@ -390,7 +395,7 @@ lseek(int fildes, off_t offset, int whence) #else #ifdef HAVE_LSEEK_DUMMY_PARAM off_t r = syscall(SYS_lseek, fildes, 0 /* extra 0 required here! */, offset, whence); - #elif defined(_FILE_OFFSET_BITS) + #elif defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 32 // Don't bother trying to call SYS__llseek on 32 bit since it is // fiddly and not needed for the tests off_t r = syscall(SYS_lseek, fildes, (uint32_t)offset, whence); @@ -514,7 +519,7 @@ DIR *opendir(const char *dirname) { if (opendir_real == NULL) { - opendir_real = (opendir_t*)find_function("opendir"); + opendir_real = (opendir_t*)find_function(FUNC_OPENDIR); } if (opendir_real == NULL) @@ -547,7 +552,7 @@ struct dirent *readdir(DIR *dir) if (readdir_real == NULL) { - readdir_real = (readdir_t*)find_function("readdir"); + readdir_real = (readdir_t*)find_function(FUNC_READDIR); } if (readdir_real == NULL) diff --git a/lib/intercept/intercept.h b/lib/intercept/intercept.h index 80a17d3f..4de5f9f2 100644 --- a/lib/intercept/intercept.h +++ b/lib/intercept/intercept.h @@ -13,6 +13,18 @@ #include <dirent.h> +#ifdef __NetBSD__ //__NetBSD_Version__ is defined in sys/param.h +#include <sys/param.h> +#endif + +#if defined __NetBSD_Version__ && __NetBSD_Version__ >= 399000800 //3.99.8 vers. +#define FUNC_OPENDIR "__opendir30" +#define FUNC_READDIR "__readdir30" +#else +#define FUNC_OPENDIR "opendir" +#define FUNC_READDIR "readdir" +#endif + #include <sys/types.h> #include <sys/stat.h> @@ -50,5 +62,14 @@ void intercept_setup_stat_post_hook (lstat_post_hook_t hookfn); void intercept_clear_setup(); +// Some newer architectures don't have an open() syscall, but use openat() instead. +// In these cases we define SYS_open (which is otherwise undefined) to equal SYS_openat +// (which is defined) so that everywhere else we can call intercept_setup_error(SYS_open) +// without caring about the difference. +// https://chromium.googlesource.com/linux-syscall-support/ +#if !HAVE_DECL_SYS_OPEN && HAVE_DECL_SYS_OPENAT +# define SYS_open SYS_openat +#endif + #endif // !PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE #endif // !INTERCEPT_H |