diff options
author | Adrian Kummerlaender | 2016-02-16 23:55:40 +0100 |
---|---|---|
committer | Adrian Kummerlaender | 2016-02-16 23:55:40 +0100 |
commit | 98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb (patch) | |
tree | 226264f5c53e851e0ff69ee1903f0d88eff4413e | |
parent | e0b000a61f54db41286ededcc795318c79715d6e (diff) | |
download | change-98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb.tar change-98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb.tar.gz change-98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb.tar.bz2 change-98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb.tar.lz change-98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb.tar.xz change-98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb.tar.zst change-98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb.zip |
Move actual function pointers to function local static variables
The previous approach of storing them in static variables of the `actual` namespace and initializing them statically did not work out as it is not guaranteed that they are initialized before any interposed function is called.
-rw-r--r-- | src/actual.h | 46 | ||||
-rw-r--r-- | src/change_log.cc | 58 |
2 files changed, 59 insertions, 45 deletions
diff --git a/src/actual.h b/src/actual.h index af64ec3..cb08d42 100644 --- a/src/actual.h +++ b/src/actual.h @@ -12,49 +12,21 @@ #include <memory> #include <cstring> -namespace { - template <class Result, typename... Arguments> - using function_ptr = Result(*)(Arguments...); - - template <typename FunctionPtr> - FunctionPtr get_actual_function(const std::string& symbol_name) { - const void* symbol_address{ dlsym(RTLD_NEXT, symbol_name.c_str()) }; - - FunctionPtr actual_function{}; - std::memcpy(&actual_function, &symbol_address, sizeof(symbol_address)); - - return actual_function; - } -} - namespace actual { - static auto write = get_actual_function< - function_ptr<ssize_t, int, const void*, size_t> - >("write"); - - static auto writev = get_actual_function< - function_ptr<ssize_t, int, const iovec*, int> - >("writev"); - static auto rename = get_actual_function< - function_ptr<int, const char*, const char*> - >("rename"); +template <class Result, typename... Arguments> +using ptr = Result(*)(Arguments...); - static auto rmdir = get_actual_function< - function_ptr<int, const char*> - >("rmdir"); +template <typename FunctionPtr> +FunctionPtr get_ptr(const std::string& symbol_name) { + const void* symbol_address{ dlsym(RTLD_NEXT, symbol_name.c_str()) }; - static auto unlink = get_actual_function< - function_ptr<int, const char*> - >("unlink"); + FunctionPtr actual_function{}; + std::memcpy(&actual_function, &symbol_address, sizeof(symbol_address)); - static auto unlinkat = get_actual_function< - function_ptr<int, int, const char*, int> - >("unlinkat"); + return actual_function; +} - static auto mmap = get_actual_function< - function_ptr<void*, void*, size_t, int, int, int, off_t> - >("mmap"); } #endif // CHANGE_SRC_ACTUAL_FUNCTION_H_ diff --git a/src/change_log.cc b/src/change_log.cc index f1279d2..e0dc179 100644 --- a/src/change_log.cc +++ b/src/change_log.cc @@ -1,4 +1,4 @@ -#include "actual_function.h" +#include "actual.h" #include "utility/io.h" #include "utility/logger.h" @@ -82,49 +82,91 @@ inline void track_remove(const std::string& path) { } ssize_t write(int fd, const void* buffer, size_t count) { + static actual::ptr<ssize_t, int, const void*, size_t> actual_write{}; + + if ( !actual_write ) { + actual_write = actual::get_ptr<decltype(actual_write)>("write"); + } + track_write(fd); - return actual::write(fd, buffer, count); + return actual_write(fd, buffer, count); } ssize_t writev(int fd, const iovec* iov, int iovcnt) { + static actual::ptr<ssize_t, int, const iovec*, int> actual_writev{}; + + if ( !actual_writev ) { + actual_writev = actual::get_ptr<decltype(actual_writev)>("writev"); + } + track_write(fd); - return actual::writev(fd, iov, iovcnt); + return actual_writev(fd, iov, iovcnt); } void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) { + static actual::ptr<void*, void*, size_t, int, int, int, off_t> actual_mmap{}; + + if ( !actual_mmap ) { + actual_mmap = actual::get_ptr<decltype(actual_mmap)>("mmap"); + } + if ( prot & PROT_WRITE ) { track_write(fd); } - return actual::mmap(addr, length, prot, flags, fd, offset); + return actual_mmap(addr, length, prot, flags, fd, offset); } int rename(const char* old_path, const char* new_path) { + static actual::ptr<int, const char*, const char*> actual_rename{}; + + if ( !actual_rename ) { + actual_rename = actual::get_ptr<decltype(actual_rename)>("rename"); + } + track_rename(old_path, new_path); - return actual::rename(old_path, new_path); + return actual_rename(old_path, new_path); } int rmdir(const char* path) { + static actual::ptr<int, const char*> actual_rmdir{}; + + if ( !actual_rmdir ) { + actual_rmdir = actual::get_ptr<decltype(actual_rmdir)>("rmdir"); + } + track_remove(path); - return actual::rmdir(path); + return actual_rmdir(path); } int unlink(const char* path) { + static actual::ptr<int, const char*> actual_unlink{}; + + if ( !actual_unlink ) { + actual_unlink = actual::get_ptr<decltype(actual_unlink)>("unlink"); + } + track_remove(path); - return actual::unlink(path); + return actual_unlink(path); } int unlinkat(int dirfd, const char* path, int flags) { + static actual::ptr<int, int, const char*, int> actual_unlinkat{}; + + if ( !actual_unlinkat ) { + actual_unlinkat = actual::get_ptr<decltype(actual_unlinkat)>("unlinkat"); + } + if ( dirfd == AT_FDCWD ) { track_remove(path); } else { track_remove(utility::get_file_path(dirfd) + path); } - return actual::unlinkat(dirfd, path, flags); + return actual_unlinkat(dirfd, path, flags); } |