diff options
-rw-r--r-- | change_log.cc | 94 | ||||
-rw-r--r-- | io.h | 54 | ||||
-rw-r--r-- | utility.h | 27 |
3 files changed, 99 insertions, 76 deletions
diff --git a/change_log.cc b/change_log.cc index 58ba0db..dc245da 100644 --- a/change_log.cc +++ b/change_log.cc @@ -2,55 +2,16 @@ #define _GNU_SOURCE #endif -#include <unistd.h> -#include <dlfcn.h> -#include <fcntl.h> -#include <sys/stat.h> - -#include <ext/stdio_filebuf.h> - -#include <cstring> -#include <iostream> -#include <utility> +#include <memory> #include <functional> #include <unordered_set> -#include <memory> - -struct FileDescriptorGuard { - FileDescriptorGuard(const std::string& path) { - this->fd = open(path.c_str(), O_WRONLY | O_APPEND); - - if ( !this->fd ) { - this->fd = STDERR_FILENO; - } - } - - ~FileDescriptorGuard() { - close(this->fd); - } - - int fd; -}; - -class LogGuard { - public: - LogGuard(const int target_fd): - buffer(target_fd, std::ios::out), - stream(&this->buffer) { } - - void append(const std::string& msg) { - this->stream << msg << std::endl; - } - - private: - __gnu_cxx::stdio_filebuf<char> buffer; - std::ostream stream; -}; -static std::unordered_set<std::string> tracked_files; +#include "io.h" +#include "utility.h" -static std::unique_ptr<FileDescriptorGuard> fd_guard; -static std::unique_ptr<LogGuard> log; +static std::unique_ptr<std::unordered_set<std::string>> tracked_files; +static std::unique_ptr<io::FileDescriptorGuard> fd_guard; +static std::unique_ptr<utility::Logger> log; template <class Result, typename... Arguments> std::function<Result(Arguments...)> get_real_function( @@ -66,11 +27,15 @@ std::function<Result(Arguments...)> get_real_function( void init() __attribute__ ((constructor)); void init() { + tracked_files = std::make_unique<std::unordered_set<std::string>>(); + if ( getenv("CHANGE_LOG_TARGET") != NULL ) { - fd_guard = std::make_unique<FileDescriptorGuard>(getenv("CHANGE_LOG_TARGET")); - log = std::make_unique<LogGuard>(fd_guard->fd); + fd_guard = std::make_unique<io::FileDescriptorGuard>( + getenv("CHANGE_LOG_TARGET") + ); + log = std::make_unique<utility::Logger>(fd_guard->fd); } else { - log = std::make_unique<LogGuard>(STDERR_FILENO); + log = std::make_unique<utility::Logger>(STDERR_FILENO); } } @@ -78,42 +43,19 @@ void exit(int status) { get_real_function<void, int>("exit")(status); } -std::string get_file_name(int fd) { - char proc_link[20]; - char file_name[256]; - - snprintf(proc_link, sizeof(proc_link), "/proc/self/fd/%d", fd); - const ssize_t name_size = readlink(proc_link, file_name, sizeof(file_name)); - - if ( name_size > 0 ) { - file_name[name_size] = '\0'; - - return std::string(file_name); - } else { - return std::string(); - } -} - -bool is_regular_file(int fd) { - struct stat fd_stat; - fstat(fd, &fd_stat); - - return S_ISREG(fd_stat.st_mode); -} - bool is_tracked_file(const std::string& file_name) { - return tracked_files.find(file_name) != tracked_files.end(); + return tracked_files->find(file_name) != tracked_files->end(); } bool track_file(const std::string& file_name) { - return tracked_files.emplace(file_name).second; + return tracked_files->emplace(file_name).second; } ssize_t write(int fd, const void* buffer, size_t count) { static auto real_write = get_real_function<ssize_t, int, const void*, size_t>("write"); - if ( is_regular_file(fd) ) { - const std::string file_name{ get_file_name(fd) }; + if ( io::is_regular_file(fd) ) { + const std::string file_name{ io::get_file_name(fd) }; if ( !is_tracked_file(file_name) ) { track_file(file_name); @@ -155,7 +97,7 @@ int unlinkat(int dirfd, const char* path, int flags) { if ( dirfd == AT_FDCWD ) { log->append("removed '" + std::string(path) + "'"); } else { - log->append("removed '" + get_file_name(dirfd) + path + "'"); + log->append("removed '" + io::get_file_name(dirfd) + path + "'"); } return real_unlinkat(dirfd, path, flags); @@ -0,0 +1,54 @@ +#ifndef CHANGE_IO_H_ +#define CHANGE_IO_H_ + +#include <unistd.h> +#include <dlfcn.h> +#include <fcntl.h> +#include <sys/stat.h> + +#include <cstring> + +namespace io { + +struct FileDescriptorGuard { + FileDescriptorGuard(const std::string& path) { + this->fd = open(path.c_str(), O_WRONLY | O_APPEND); + + if ( !this->fd ) { + this->fd = STDERR_FILENO; + } + } + + ~FileDescriptorGuard() { + close(this->fd); + } + + int fd; +}; + +std::string get_file_name(int fd) { + char proc_link[20]; + char file_name[256]; + + snprintf(proc_link, sizeof(proc_link), "/proc/self/fd/%d", fd); + const ssize_t name_size = readlink(proc_link, file_name, sizeof(file_name)); + + if ( name_size > 0 ) { + file_name[name_size] = '\0'; + + return std::string(file_name); + } else { + return std::string(); + } +} + +bool is_regular_file(int fd) { + struct stat fd_stat; + fstat(fd, &fd_stat); + + return S_ISREG(fd_stat.st_mode); +} + +} + +#endif // CHANGE_IO_H_ diff --git a/utility.h b/utility.h new file mode 100644 index 0000000..ec4529e --- /dev/null +++ b/utility.h @@ -0,0 +1,27 @@ +#ifndef CHANGE_UTILITY_H_ +#define CHANGE_UTILITY_H_ + +#include <ext/stdio_filebuf.h> + +#include <iostream> + +namespace utility { + +class Logger { + public: + Logger(const int target_fd): + buffer(target_fd, std::ios::out), + stream(&this->buffer) { } + + void append(const std::string& msg) { + this->stream << msg << std::endl; + } + + private: + __gnu_cxx::stdio_filebuf<char> buffer; + std::ostream stream; +}; + +} + +#endif // CHANGE_UTILITY_H_ |