polybar/src/utils/inotify.cpp

131 lines
2.5 KiB
C++
Raw Normal View History

#include "utils/inotify.hpp"
2016-11-20 22:04:31 +00:00
#include <unistd.h>
2016-11-25 12:55:15 +00:00
#include "errors.hpp"
2016-11-02 19:22:45 +00:00
#include "utils/memory.hpp"
2016-11-19 05:22:44 +00:00
POLYBAR_NS
2016-11-02 19:22:45 +00:00
/**
* Construct inotify watch
*/
inotify_watch::inotify_watch(string path) : m_path(move(path)) {}
/**
* Deconstruct inotify watch
*/
inotify_watch::~inotify_watch() {
if (m_wd != -1) {
inotify_rm_watch(m_fd, m_wd);
2016-11-02 19:22:45 +00:00
}
if (m_fd != -1) {
close(m_fd);
2016-11-02 19:22:45 +00:00
}
}
2016-11-02 19:22:45 +00:00
inotify_watch::inotify_watch(inotify_watch&& other) noexcept {
std::swap(m_path, other.m_path);
std::swap(m_wd, other.m_wd);
std::swap(m_fd, other.m_fd);
std::swap(m_mask, other.m_mask);
}
inotify_watch& inotify_watch::operator=(inotify_watch&& other) noexcept {
std::swap(m_path, other.m_path);
std::swap(m_wd, other.m_wd);
std::swap(m_fd, other.m_fd);
std::swap(m_mask, other.m_mask);
return *this;
}
/**
* Attach inotify watch
*/
void inotify_watch::attach(int mask) {
if (m_fd == -1 && (m_fd = inotify_init()) == -1) {
throw system_error("Failed to allocate inotify fd");
}
if ((m_wd = inotify_add_watch(m_fd, m_path.c_str(), mask)) == -1) {
throw system_error("Failed to attach inotify watch");
2016-11-02 19:22:45 +00:00
}
m_mask |= mask;
}
2016-11-02 19:22:45 +00:00
/**
* Remove inotify watch
*/
void inotify_watch::remove(bool force) {
if (inotify_rm_watch(m_fd, m_wd) == -1 && !force) {
throw system_error("Failed to remove inotify watch");
}
m_wd = -1;
m_mask = 0;
}
2016-11-02 19:22:45 +00:00
/**
* Poll the inotify fd for events
*
2022-02-20 20:40:48 +00:00
* @brief A wait_ms of -1 blocks until an event is fired
*/
2016-12-26 09:37:14 +00:00
bool inotify_watch::poll(int wait_ms) const {
if (m_fd == -1) {
return false;
}
2016-11-02 19:22:45 +00:00
struct pollfd fds[1];
fds[0].fd = m_fd;
fds[0].events = POLLIN;
2016-11-02 19:22:45 +00:00
::poll(fds, 1, wait_ms);
2016-11-02 19:22:45 +00:00
return fds[0].revents & POLLIN;
}
2016-11-02 19:22:45 +00:00
/**
* Get the latest inotify event
*/
2022-03-06 16:44:48 +00:00
inotify_event inotify_watch::get_event() const {
inotify_event event;
2016-11-02 19:22:45 +00:00
if (m_fd == -1 || m_wd == -1) {
return event;
}
2016-11-02 19:22:45 +00:00
2022-03-06 16:44:48 +00:00
event.is_valid = true;
char buffer[1024];
2016-12-26 09:37:14 +00:00
auto bytes = read(m_fd, buffer, 1024);
auto len = 0;
2016-11-02 19:22:45 +00:00
while (len < bytes) {
auto* e = reinterpret_cast<::inotify_event*>(&buffer[len]);
2016-11-02 19:22:45 +00:00
2022-03-06 16:44:48 +00:00
event.filename = e->len ? e->name : m_path;
event.wd = e->wd;
event.cookie = e->cookie;
event.is_dir = e->mask & IN_ISDIR;
event.mask |= e->mask;
2016-11-02 19:22:45 +00:00
len += sizeof(*e) + e->len;
2016-11-02 19:22:45 +00:00
}
return event;
}
/**
* Get watch file path
*/
string inotify_watch::path() const {
return m_path;
}
/**
* Get the file descriptor associated with the watch
*/
int inotify_watch::get_file_descriptor() const {
return m_fd;
}
2016-11-19 05:22:44 +00:00
POLYBAR_NS_END