diff options
Diffstat (limited to 'src/utility')
-rw-r--r-- | src/utility/io.h | 68 | ||||
-rw-r--r-- | src/utility/logger.h | 44 |
2 files changed, 112 insertions, 0 deletions
diff --git a/src/utility/io.h b/src/utility/io.h new file mode 100644 index 0000000..ed1f542 --- /dev/null +++ b/src/utility/io.h @@ -0,0 +1,68 @@ +#ifndef CHANGE_SRC_UTILITY_IO_H_ +#define CHANGE_SRC_UTILITY_IO_H_ + +#include <unistd.h> +#include <dlfcn.h> +#include <fcntl.h> +#include <sys/stat.h> + +#include <cstring> + +namespace utility { + +class FileDescriptorGuard { + public: + FileDescriptorGuard(const std::string& path) { + this->fd_ = open(path.c_str(), O_CREAT | O_WRONLY | O_APPEND); + + if ( !this->fd_ ) { + this->fd_ = STDERR_FILENO; + } + } + + ~FileDescriptorGuard() { + close(this->fd_); + } + + operator int() { + return this->fd_; + } + + private: + 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); +} + +bool is_regular_file(const char* path) { + struct stat fd_stat; + lstat(path, &fd_stat); + + return S_ISREG(fd_stat.st_mode); +} + +} + +#endif // CHANGE_SRC_UTILITY_IO_H_ diff --git a/src/utility/logger.h b/src/utility/logger.h new file mode 100644 index 0000000..475f33d --- /dev/null +++ b/src/utility/logger.h @@ -0,0 +1,44 @@ +#ifndef CHANGE_SRC_LOGGER_H_ +#define CHANGE_SRC_LOGGER_H_ + +#include <ext/stdio_filebuf.h> + +#include <boost/process.hpp> + +#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; + } + + // Forward the contents of a given standard output stream to the log target + // + // While `this->stream_ << stream.rdbuf()` would be more effective it sadly + // does not work with `boost::process::pistream` due to a broken pipe error + // in conjunction with the required `boost::process::capture_stream` context + // flag. + // + void forward(boost::process::pistream& stream) { + this->stream_ << std::string( + (std::istreambuf_iterator<char>(stream)), + (std::istreambuf_iterator<char>()) + ); + } + + private: + __gnu_cxx::stdio_filebuf<char> buffer_; + std::ostream stream_; + +}; + +} + +#endif // CHANGE_SRC_LOGGER_H_ |