Repo-Init
 
Loading...
Searching...
No Matches
FileMonitor Class Reference

#include <FileHelpers.hpp>

Public Member Functions

 FileMonitor (std::filesystem::path filePath, uint32_t notifyEvents=IN_MODIFY)
 
 FileMonitor (const FileMonitor &)=delete
 Copy constructor.
 
 FileMonitor (FileMonitor &&)=delete
 Move constructor.
 
FileMonitoroperator= (FileMonitor)=delete
 Copy assignment operator.
 
FileMonitoroperator= (FileMonitor &&)=delete
 Move assignment operator.
 
FNotifyCallback notifyCallback () const
 
void notifyCallback (FNotifyCallback func)
 
void userPtr (const void *ptr)
 
 ~FileMonitor ()
 

Private Member Functions

void threadFunc () const noexcept
 

Private Attributes

int _fDescriptor {-1}
 File descriptor.
 
int _wDescriptor {-1}
 Watch descriptor.
 
std::filesystem::path _filePath
 File path.
 
FNotifyCallback _notifyCallback
 Callback function.
 
uint32_t _notifyEvents
 Notify types.
 
const void * _userPtr = nullptr
 User pointer.
 
std::unique_ptr< std::thread > _thread
 Thread.
 
std::atomic_flag _shouldStop {false}
 Flag to stop monitoring.
 

Detailed Description

Invokes functions for a file for given notify events

Definition at line 65 of file FileHelpers.hpp.

Constructor & Destructor Documentation

◆ FileMonitor() [1/3]

FileMonitor::FileMonitor ( std::filesystem::path filePath,
uint32_t notifyEvents = IN_MODIFY )
explicit

Constructor

Parameters
[in]filePathPath to the file
[in]notifyEventsEvents to notify

Definition at line 57 of file FileHelpers.cpp.

58 : _fDescriptor(inotify_init()), _filePath(std::move(filePath)), _notifyEvents(notifyEvents)
59{
60 if (_fDescriptor < 0)
61 {
62 throw std::ios_base::failure("Failed to initialize inotify");
63 }
64
65 _wDescriptor = inotify_add_watch(_fDescriptor, _filePath.c_str(), notifyEvents);
66 if (_wDescriptor < 0)
67 {
68 close(_fDescriptor);
69 throw std::ios_base::failure("Failed to add watch descriptor");
70 }
71
72 if (fcntl(_fDescriptor, F_SETFL, fcntl(_fDescriptor, F_GETFL) | O_NONBLOCK) < 0)
73 {
74 close(_fDescriptor);
75 throw std::ios_base::failure("Failed to set file descriptor to non-blocking mode");
76 }
77
78 _thread = std::make_unique<std::thread>(&FileMonitor::threadFunc, this);
79}
int _fDescriptor
File descriptor.
void threadFunc() const noexcept
std::unique_ptr< std::thread > _thread
Thread.
int _wDescriptor
Watch descriptor.
uint32_t _notifyEvents
Notify types.
std::filesystem::path _filePath
File path.
Here is the call graph for this function:

◆ FileMonitor() [2/3]

FileMonitor::FileMonitor ( const FileMonitor & )
delete

Copy constructor.

◆ FileMonitor() [3/3]

FileMonitor::FileMonitor ( FileMonitor && )
delete

Move constructor.

◆ ~FileMonitor()

FileMonitor::~FileMonitor ( )

Destructor

Definition at line 81 of file FileHelpers.cpp.

82{
83 _shouldStop.test_and_set();
84 if (_thread && _thread->joinable())
85 {
86 _thread->join();
87 _thread.reset();
88 }
89
90 // Remove watch descriptor first
91 if (_wDescriptor >= 0)
92 {
93 if (inotify_rm_watch(_fDescriptor, _wDescriptor) < 0)
94 {
95 try
96 {
97 spdlog::error("Failed to remove watch descriptor: {}", getErrnoString(errno));
98 }
99 catch (const std::exception &e)
100 {
101 std::cerr << "Failed to remove watch descriptor and also logger thrown an exception: "
102 << getErrnoString(errno) << " " << e.what() << '\n';
103 }
104 }
105 _wDescriptor = -1;
106 }
107
108 // Then close the file descriptor
109 if (_fDescriptor >= 0)
110 {
111 if (close(_fDescriptor) < 0)
112 {
113 try
114 {
115 spdlog::error("Failed to close file descriptor: {}", getErrnoString(errno));
116 }
117 catch (const std::exception &e)
118 {
119 std::cerr << "Failed to close file descriptor and also logger thrown an exception: "
120 << getErrnoString(errno) << " " << e.what() << '\n';
121 }
122 }
123 _fDescriptor = -1;
124 }
125}
std::string getErrnoString(int errVal)
std::atomic_flag _shouldStop
Flag to stop monitoring.
Here is the call graph for this function:

Member Function Documentation

◆ notifyCallback() [1/2]

FNotifyCallback FileMonitor::notifyCallback ( ) const
inlinenodiscard

Definition at line 107 of file FileHelpers.hpp.

107{ return _notifyCallback; }
FNotifyCallback _notifyCallback
Callback function.

◆ notifyCallback() [2/2]

void FileMonitor::notifyCallback ( FNotifyCallback func)
inline

Definition at line 108 of file FileHelpers.hpp.

108{ _notifyCallback = std::move(func); }

◆ operator=() [1/2]

FileMonitor & FileMonitor::operator= ( FileMonitor && )
delete

Move assignment operator.

◆ operator=() [2/2]

FileMonitor & FileMonitor::operator= ( FileMonitor )
delete

Copy assignment operator.

◆ threadFunc()

void FileMonitor::threadFunc ( ) const
privatenoexcept

Definition at line 16 of file FileHelpers.cpp.

17{
18 while (!_shouldStop._M_i)
19 {
20 // Buffer for reading events
21 unsigned int nBytes = 0;
22 if (ioctl(_fDescriptor, FIONREAD, &nBytes) < 0)
23 {
24 spdlog::error("Failed to get available events for file monitoring: {}", getErrnoString(errno));
25 }
26
27 auto buffer = std::vector<char>(nBytes + 1, '\0');
28 auto nRead = read(_fDescriptor, buffer.data(), nBytes);
29 if (nRead < 0)
30 {
31 spdlog::error("Failed to read events for file monitoring: {}", getErrnoString(errno));
32 }
33 else if (nRead == 0)
34 {
35 spdlog::debug("No events read for file monitoring");
36 }
37
38 ssize_t idx = 0;
39 while (_notifyCallback && idx < nRead)
40 {
41 const auto *event = reinterpret_cast<inotify_event *>(&buffer[static_cast<size_t>(idx)]);
42
43 // Check if file notify type matches
44 if ((event->mask & _notifyEvents) != 0)
45 {
47 break;
48 }
49
50 idx += static_cast<ssize_t>(sizeof(inotify_event) + event->len);
51 }
52
53 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_INTERVAL_MS));
54 }
55}
constexpr int SLEEP_INTERVAL_MS
const void * _userPtr
User pointer.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ userPtr()

void FileMonitor::userPtr ( const void * ptr)
inline

Sets user pointer

Parameters
[in]ptrUser pointer

Definition at line 114 of file FileHelpers.hpp.

114{ _userPtr = ptr; }

Member Data Documentation

◆ _fDescriptor

int FileMonitor::_fDescriptor {-1}
private

File descriptor.

Definition at line 68 of file FileHelpers.hpp.

68{-1};

◆ _filePath

std::filesystem::path FileMonitor::_filePath
private

File path.

Definition at line 72 of file FileHelpers.hpp.

◆ _notifyCallback

FNotifyCallback FileMonitor::_notifyCallback
private

Callback function.

Definition at line 74 of file FileHelpers.hpp.

◆ _notifyEvents

uint32_t FileMonitor::_notifyEvents
private

Notify types.

Definition at line 76 of file FileHelpers.hpp.

◆ _shouldStop

std::atomic_flag FileMonitor::_shouldStop {false}
private

Flag to stop monitoring.

Definition at line 83 of file FileHelpers.hpp.

83{false};

◆ _thread

std::unique_ptr<std::thread> FileMonitor::_thread
private

Thread.

Definition at line 81 of file FileHelpers.hpp.

◆ _userPtr

const void* FileMonitor::_userPtr = nullptr
private

User pointer.

Definition at line 78 of file FileHelpers.hpp.

◆ _wDescriptor

int FileMonitor::_wDescriptor {-1}
private

Watch descriptor.

Definition at line 70 of file FileHelpers.hpp.

70{-1};

The documentation for this class was generated from the following files: