11#include < iostream>
22#include < string>
3+ #include < thread>
4+ #include < mutex>
5+ #include < vector>
6+ #include < fstream>
7+
38#include < unistd.h>
49#include < sys/inotify.h>
510#include < limits.h>
611#include < dirent.h>
712
13+ // Mutex for thread safety
14+ std::mutex mtx;
15+
16+ // Buffer to store events temporarily
17+ std::vector<std::string> eventBuffer;
18+
819// Function to add a watch recursively
920void add_watch (int fd, const std::string& path) {
1021 // Add a watch for the current directory
@@ -13,7 +24,6 @@ void add_watch(int fd, const std::string& path) {
1324 perror (" inotify_add_watch" );
1425 return ;
1526 }
16-
1727
1828 // Open the directory and iterate through its entries
1929 DIR* dir = opendir (path.c_str ());
@@ -40,12 +50,45 @@ void add_watch(int fd, const std::string& path) {
4050 closedir (dir);
4151}
4252
53+ // Function to write buffered events to CSV file
54+ void write_to_csv (const std::string& csv_file) {
55+ std::lock_guard<std::mutex> lock (mtx);
56+
57+ if (eventBuffer.empty ()) {
58+ return ;
59+ }
60+
61+
62+
63+ std::ofstream ofs (csv_file, std::ios_base::app); // Append mode
64+ if (!ofs.is_open ()) {
65+ std::cerr << " Failed to open CSV file: " << csv_file << std::endl;
66+ return ;
67+ }
68+
69+ for (const auto & event : eventBuffer) {
70+ ofs << event << std::endl;
71+ }
72+
73+ ofs.close ();
74+ eventBuffer.clear (); // Clear the buffer after writing
75+ }
76+
77+ // Function to periodically flush the buffer to CSV
78+ void periodic_flush (const std::string& csv_file) {
79+ while (true ) {
80+ std::this_thread::sleep_for (std::chrono::minutes (1 )); // Wait for one minute
81+ write_to_csv (csv_file);
82+ }
83+ }
84+
4385int main (int argc, char * argv[]) {
4486 if (argc < 2 ) {
4587 std::cerr << " Usage: " << argv[0 ] << " <directory_to_watch>" << std::endl;
4688 return EXIT_FAILURE;
4789 }
4890 const std::string directory_to_watch = argv[1 ]; // Get the directory to watch from command-line argument
91+ const std::string csv_file = " file_operations.csv" ;
4992
5093 // Create an inotify instance
5194 int fd = inotify_init ();
@@ -57,6 +100,9 @@ int main(int argc, char* argv[]) {
57100 // Add watches recursively
58101 add_watch (fd, directory_to_watch);
59102
103+ // Start the periodic flush thread
104+ std::thread flush_thread (periodic_flush, csv_file);
105+
60106 // Buffer to store inotify events
61107 char buffer[4096 ] __attribute__ ((aligned (__alignof__ (struct inotify_event ))));
62108 while (true ) {
@@ -70,25 +116,42 @@ int main(int argc, char* argv[]) {
70116 struct inotify_event * event = reinterpret_cast <struct inotify_event *>(ptr);
71117
72118 std::string event_name = (event->len > 0 ) ? event->name : " unknown" ;
73- std::cout << " Event: " ;
119+ std::string event_desc;
120+
121+ // Get the current timestamp
122+ time_t now = time (nullptr );
123+ char timestamp[20 ];
124+ strftime (timestamp, sizeof (timestamp), " %Y-%m-%d %H:%M:%S" , localtime (&now));
125+
126+ event_desc = timestamp;
127+ event_desc += " , " ;
128+
74129 if (event->mask & IN_CREATE) {
75- std::cout << " CREATE" ;
130+ event_desc += " CREATE" ;
76131 } else if (event->mask & IN_DELETE) {
77- std::cout << " DELETE" ;
132+ event_desc += " DELETE" ;
78133 } else if (event->mask & IN_MODIFY) {
79- std::cout << " MODIFY" ;
134+ event_desc += " MODIFY" ;
80135 } else if (event->mask & IN_MOVED_FROM || event->mask & IN_MOVED_TO) {
81- std::cout << " MOVE" ;
136+ event_desc += " MOVE" ;
82137 } else {
83- std::cout << " UNKNOWN" ;
138+ event_desc += " UNKNOWN" ;
84139 }
85- std::cout << " on " << event_name << std::endl;
140+
141+ event_desc += " , " ;
142+ event_desc += event_name;
143+
144+ // Lock the mutex and add the event to the buffer
145+ std::lock_guard<std::mutex> lock (mtx);
146+ eventBuffer.push_back (event_desc);
86147
87148 ptr += sizeof (struct inotify_event ) + event->len ;
88149 }
89150 }
90151
91152 // Clean up
92153 close (fd);
154+ flush_thread.join (); // Ensure the flush thread is finished before exiting
155+
93156 return EXIT_SUCCESS;
94- }
157+ }
0 commit comments