summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2006-11-26 19:43:20 +0000
committerChris Wilson <chris+github@qwirx.com>2006-11-26 19:43:20 +0000
commitaa1e32e97f007a547e57cd6be5ecf190b4ff7cfd (patch)
treea021c6b135463207a4bac94ffe61f057b466a820 /test
parentc83d51cd16dd979273a960f8ac9375e10fa93942 (diff)
Moved intercept code to a library module to allow it to be used by
test/bbackupd as well (refs #3)
Diffstat (limited to 'test')
-rw-r--r--test/raidfile/intercept.cpp276
1 files changed, 0 insertions, 276 deletions
diff --git a/test/raidfile/intercept.cpp b/test/raidfile/intercept.cpp
deleted file mode 100644
index 0a5b4ab9..00000000
--- a/test/raidfile/intercept.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-// --------------------------------------------------------------------------
-//
-// File
-// Name: intercept.cpp
-// Purpose: Syscall interception code for the raidfile test
-// Created: 2003/07/22
-//
-// --------------------------------------------------------------------------
-
-#include "Box.h"
-
-#ifdef HAVE_SYS_SYSCALL_H
- #include <sys/syscall.h>
-#endif
-#include <sys/types.h>
-#include <unistd.h>
-
-#ifdef HAVE_SYS_UIO_H
-#include <sys/uio.h>
-#endif
-
-#include <errno.h>
-
-#ifndef PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
-
-#if !defined(HAVE_SYSCALL) && !defined(HAVE___SYSCALL) && !defined(HAVE___SYSCALL_NEED_DEFN)
- #define PLATFORM_NO_SYSCALL
-#endif
-
-#ifdef PLATFORM_NO_SYSCALL
- // For some reason, syscall just doesn't work on Darwin
- // so instead, we build functions using assembler in a varient
- // of the technique used in the Darwin Libc
- extern "C" int
- TEST_open(const char *path, int flags, mode_t mode);
- extern "C" int
- TEST_close(int d);
- extern "C" ssize_t
- TEST_write(int d, const void *buf, size_t nbytes);
- extern "C" ssize_t
- TEST_read(int d, void *buf, size_t nbytes);
- extern "C" ssize_t
- TEST_readv(int d, const struct iovec *iov, int iovcnt);
- extern "C" off_t
- TEST_lseek(int fildes, off_t offset, int whence);
-#else
- #ifdef HAVE___SYSCALL_NEED_DEFN
- // Need this, not declared in syscall.h nor unistd.h
- extern "C" off_t __syscall(quad_t number, ...);
- #endif
- #ifndef HAVE_SYSCALL
- #undef syscall
- #define syscall __syscall
- #endif
-#endif
-
-#include <string.h>
-#include <stdio.h>
-
-#include "MemLeakFindOn.h"
-
-bool intercept_enabled = false;
-const char *intercept_filename = 0;
-int intercept_filedes = -1;
-off_t intercept_errorafter = 0;
-int intercept_errno = 0;
-int intercept_syscall = 0;
-off_t intercept_filepos = 0;
-
-#define SIZE_ALWAYS_ERROR -773
-
-void intercept_clear_setup()
-{
- intercept_enabled = false;
- intercept_filename = 0;
- intercept_filedes = -1;
- intercept_errorafter = 0;
- intercept_syscall = 0;
- intercept_filepos = 0;
-}
-
-bool intercept_triggered()
-{
- return !intercept_enabled;
-}
-
-void intercept_setup_error(const char *filename, unsigned int errorafter, int errortoreturn, int syscalltoerror)
-{
- TRACE4("Setup for error: %s, after %d, err %d, syscall %d\n", filename, errorafter, errortoreturn, syscalltoerror);
- intercept_enabled = true;
- intercept_filename = filename;
- intercept_filedes = -1;
- intercept_errorafter = errorafter;
- intercept_syscall = syscalltoerror;
- intercept_errno = errortoreturn;
- intercept_filepos = 0;
-}
-
-bool intercept_errornow(int d, int size, int syscallnum)
-{
- if(intercept_filedes != -1 && d == intercept_filedes && syscallnum == intercept_syscall)
- {
- //printf("Checking for err, %d, %d, %d\n", d, size, syscallnum);
- if(size == SIZE_ALWAYS_ERROR)
- {
- // Looks good for an error!
- TRACE2("Returning error %d for syscall %d\n", intercept_errno, syscallnum);
- return true;
- }
- // where are we in the file?
- if(intercept_filepos >= intercept_errorafter || intercept_filepos >= ((off_t)intercept_errorafter - size))
- {
- TRACE3("Returning error %d for syscall %d, file pos %d\n", intercept_errno, syscallnum, (int)intercept_filepos);
- return true;
- }
- }
- return false; // no error please!
-}
-
-int intercept_reterr()
-{
- intercept_enabled = false;
- intercept_filename = 0;
- intercept_filedes = -1;
- intercept_errorafter = 0;
- intercept_syscall = 0;
- return intercept_errno;
-}
-
-#define CHECK_FOR_FAKE_ERROR_COND(D, S, CALL, FAILRES) \
- if(intercept_enabled) \
- { \
- if(intercept_errornow(D, S, CALL)) \
- { \
- errno = intercept_reterr(); \
- return FAILRES; \
- } \
- }
-
-extern "C" int
-open(const char *path, int flags, mode_t mode)
-{
- if(intercept_enabled)
- {
- if(intercept_syscall == SYS_open && strcmp(path, intercept_filename) == 0)
- {
- errno = intercept_reterr();
- return -1;
- }
- }
-#ifdef PLATFORM_NO_SYSCALL
- int r = TEST_open(path, flags, mode);
-#else
- int r = syscall(SYS_open, path, flags, mode);
-#endif
- if(intercept_enabled && intercept_filedes == -1)
- {
- // Right file?
- if(strcmp(intercept_filename, path) == 0)
- {
- intercept_filedes = r;
- //printf("Found file to intercept, h = %d\n", r);
- }
- }
- return r;
-}
-
-extern "C" int
-open64(const char *path, int flags, mode_t mode)
-{
- // With _FILE_OFFSET_BITS set to 64 this should really use (flags |
- // O_LARGEFILE) here, but not actually necessary for the tests and not
- // worth the trouble finding O_LARGEFILE
- return open(path, flags, mode);
-}
-
-extern "C" int
-close(int d)
-{
- CHECK_FOR_FAKE_ERROR_COND(d, SIZE_ALWAYS_ERROR, SYS_close, -1);
-#ifdef PLATFORM_NO_SYSCALL
- int r = TEST_close(d);
-#else
- int r = syscall(SYS_close, d);
-#endif
- if(r == 0)
- {
- if(d == intercept_filedes)
- {
- intercept_filedes = -1;
- }
- }
- return r;
-}
-
-extern "C" ssize_t
-write(int d, const void *buf, size_t nbytes)
-{
- CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_write, -1);
-#ifdef PLATFORM_NO_SYSCALL
- int r = TEST_write(d, buf, nbytes);
-#else
- int r = syscall(SYS_write, d, buf, nbytes);
-#endif
- if(r != -1)
- {
- intercept_filepos += r;
- }
- return r;
-}
-
-extern "C" ssize_t
-read(int d, void *buf, size_t nbytes)
-{
- CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_read, -1);
-#ifdef PLATFORM_NO_SYSCALL
- int r = TEST_read(d, buf, nbytes);
-#else
- int r = syscall(SYS_read, d, buf, nbytes);
-#endif
- if(r != -1)
- {
- intercept_filepos += r;
- }
- return r;
-}
-
-extern "C" ssize_t
-readv(int d, const struct iovec *iov, int iovcnt)
-{
- // how many bytes?
- int nbytes = 0;
- for(int b = 0; b < iovcnt; ++b)
- {
- nbytes += iov[b].iov_len;
- }
-
- CHECK_FOR_FAKE_ERROR_COND(d, nbytes, SYS_readv, -1);
-#ifdef PLATFORM_NO_SYSCALL
- int r = TEST_readv(d, iov, iovcnt);
-#else
- int r = syscall(SYS_readv, d, iov, iovcnt);
-#endif
- if(r != -1)
- {
- intercept_filepos += r;
- }
- return r;
-}
-
-extern "C" off_t
-lseek(int fildes, off_t offset, int whence)
-{
- // random magic for lseek syscall, see /usr/src/lib/libc/sys/lseek.c
- CHECK_FOR_FAKE_ERROR_COND(fildes, 0, SYS_lseek, -1);
-#ifdef PLATFORM_NO_SYSCALL
- int r = TEST_lseek(fildes, offset, 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)
- // 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);
- #else
- off_t r = syscall(SYS_lseek, fildes, offset, whence);
- #endif
-#endif
- if(r != -1)
- {
- intercept_filepos = r;
- }
- return r;
-}
-
-#endif // n PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE