aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2016-02-16 23:55:40 +0100
committerAdrian Kummerlaender2016-02-16 23:55:40 +0100
commit98f68dd9bb0318acfaaf7f2e7ad571a19729a8bb (patch)
tree226264f5c53e851e0ff69ee1903f0d88eff4413e
parente0b000a61f54db41286ededcc795318c79715d6e (diff)
downloadchange-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.h46
-rw-r--r--src/change_log.cc58
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);
}