polybar/include/utils/file.hpp

109 lines
2.3 KiB
C++

#pragma once
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <fstream>
#include "common.hpp"
#include "utils/scope.hpp"
LEMONBUDDY_NS
namespace file_util {
/**
* RAII file wrapper
*/
class file_ptr {
public:
/**
* Constructor: open file handler
*/
explicit file_ptr(const string& path, const string& mode = "a+")
: m_path(string(path)), m_mode(string(mode)) {
m_ptr = fopen(m_path.c_str(), m_mode.c_str());
}
/**
* Destructor: close file handler
*/
~file_ptr() {
if (m_ptr != nullptr)
fclose(m_ptr);
}
/**
* Logical operator testing if the file handler was created
*/
operator bool() {
return m_ptr != nullptr;
}
/**
* Call operator returning a pointer to the file handler
*/
FILE* operator()() {
return m_ptr;
}
protected:
FILE* m_ptr = nullptr;
string m_path;
string m_mode;
};
/**
* Checks if the given file exist
*/
inline auto exists(string filename) {
struct stat buffer;
return stat(filename.c_str(), &buffer) == 0;
}
/**
* Gets the contents of the given file
*/
inline auto get_contents(string filename) {
try {
std::ifstream ifs(filename);
string contents((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
return contents;
} catch (std::ios_base::failure& e) {
return string{""};
}
}
/**
* Puts the given file descriptor into blocking mode
*/
inline auto set_block(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1)
throw system_error("Failed to unset O_NONBLOCK");
}
/**
* Puts the given file descriptor into non-blocking mode
*/
inline auto set_nonblock(int fd) {
int flags = fcntl(fd, F_GETFL, 0);
flags |= O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) == -1)
throw system_error("Failed to set O_NONBLOCK");
}
/**
* Checks if the given file is a named pipe
*/
inline auto is_fifo(string filename) {
auto fileptr = make_unique<file_ptr>(filename);
int fd = fileno((*fileptr)());
struct stat statbuf;
fstat(fd, &statbuf);
return S_ISFIFO(statbuf.st_mode);
}
}
LEMONBUDDY_NS_END