3
3
#include < CoreServices/CoreServices.h>
4
4
5
5
#include < iostream>
6
- #include < thread>
7
6
8
7
std::string eventFlagsToString (FSEventStreamEventFlags eventFlags)
9
8
{
9
+ std::cout << " FSEventStreamEventFlags: " << std::to_string (eventFlags) << std::endl;
10
+
11
+ std::string text;
10
12
if ((eventFlags & kFSEventStreamEventFlagNone ) != 0U ) {
11
- return " None: " ;
13
+ text += " None" ;
12
14
}
13
15
if ((eventFlags & kFSEventStreamEventFlagMustScanSubDirs ) != 0U ) {
14
- return " MustScanSubDirs: " ;
16
+ text += " MustScanSubDirs " ;
15
17
}
16
18
if ((eventFlags & kFSEventStreamEventFlagUserDropped ) != 0U ) {
17
- return " UserDropped: " ;
19
+ text += " UserDropped " ;
18
20
}
19
21
if ((eventFlags & kFSEventStreamEventFlagKernelDropped ) != 0U ) {
20
- return " KernelDropped: " ;
22
+ text += " KernelDropped " ;
21
23
}
22
24
if ((eventFlags & kFSEventStreamEventFlagEventIdsWrapped ) != 0U ) {
23
- return " EventIdsWrapped: " ;
25
+ text += " EventIdsWrapped " ;
24
26
}
25
27
if ((eventFlags & kFSEventStreamEventFlagHistoryDone ) != 0U ) {
26
- return " HistoryDone: " ;
28
+ text += " HistoryDone " ;
27
29
}
28
30
if ((eventFlags & kFSEventStreamEventFlagRootChanged ) != 0U ) {
29
- return " RootChanged: " ;
31
+ text += " RootChanged " ;
30
32
}
31
33
if ((eventFlags & kFSEventStreamEventFlagMount ) != 0U ) {
32
- return " Mount: " ;
34
+ text += " Mount " ;
33
35
}
34
36
if ((eventFlags & kFSEventStreamEventFlagUnmount ) != 0U ) {
35
- return " Unmount: " ;
37
+ text += " Unmount " ;
36
38
}
37
39
if ((eventFlags & kFSEventStreamEventFlagItemCreated ) != 0U ) {
38
- return " Created: " ;
40
+ text += " Created " ;
39
41
}
40
42
if ((eventFlags & kFSEventStreamEventFlagItemRemoved ) != 0U ) {
41
- return " Removed: " ;
43
+ text += " Removed " ;
42
44
}
43
45
if ((eventFlags & kFSEventStreamEventFlagItemInodeMetaMod ) != 0U ) {
44
- return " InodeMetaMod: " ;
46
+ text += " InodeMetaMod " ;
45
47
}
46
48
if ((eventFlags & kFSEventStreamEventFlagItemRenamed ) != 0U ) {
47
- return " Renamed: " ;
49
+ text += " Renamed " ;
48
50
}
49
51
if ((eventFlags & kFSEventStreamEventFlagItemModified ) != 0U ) {
50
- return " Modified: " ;
52
+ text += " Modified " ;
51
53
}
52
54
if ((eventFlags & kFSEventStreamEventFlagItemFinderInfoMod ) != 0U ) {
53
- return " FinderInfoMod: " ;
55
+ text += " FinderInfoMod " ;
54
56
}
55
57
if ((eventFlags & kFSEventStreamEventFlagItemChangeOwner ) != 0U ) {
56
- return " ChangeOwner: " ;
58
+ text += " ChangeOwner " ;
57
59
}
58
60
if ((eventFlags & kFSEventStreamEventFlagItemXattrMod ) != 0U ) {
59
- return " XattrMod: " ;
61
+ text += " XattrMod " ;
60
62
}
61
63
if ((eventFlags & kFSEventStreamEventFlagItemIsFile ) != 0U ) {
62
- return " IsFile: " ;
64
+ text += " IsFile " ;
63
65
}
64
66
if ((eventFlags & kFSEventStreamEventFlagItemIsDir ) != 0U ) {
65
- return " IsDir: " ;
67
+ text += " IsDir " ;
66
68
}
67
69
if ((eventFlags & kFSEventStreamEventFlagItemIsSymlink ) != 0U ) {
68
- return " IsSymlink: " ;
70
+ text += " IsSymlink " ;
69
71
}
70
72
if ((eventFlags & kFSEventStreamEventFlagOwnEvent ) != 0U ) {
71
- return " OwnEvent: " ;
73
+ text += " OwnEvent " ;
72
74
}
73
75
if ((eventFlags & kFSEventStreamEventFlagItemIsHardlink ) != 0U ) {
74
- return " IsHardlink: " ;
76
+ text += " IsHardlink " ;
75
77
}
76
78
if ((eventFlags & kFSEventStreamEventFlagItemIsLastHardlink ) != 0U ) {
77
- return " IsLastHardlink: " ;
79
+ text += " IsLastHardlink " ;
78
80
}
79
81
if ((eventFlags & kFSEventStreamEventFlagItemCloned ) != 0U ) {
80
- return " Cloned: " ;
82
+ text += " Cloned " ;
83
+ }
84
+ if (text.empty ()) {
85
+ text = " Unknown " + std::to_string (eventFlags) + " " ;
86
+ } else {
87
+ text += " : " ;
81
88
}
82
- return " Unknown " + std::to_string (eventFlags) + " : " ;
89
+ return text ;
83
90
}
84
91
85
92
class MonitorDir ::MonitorDirPrivate
@@ -101,7 +108,7 @@ class MonitorDir::MonitorDirPrivate
101
108
// auto *monitorDir = static_cast<MonitorDirPrivate *>(clientCallBackInfo);
102
109
char **paths = static_cast <char **>(eventPaths);
103
110
if (paths == nullptr ) {
104
- std::cerr << " Error: paths is null." << std::endl;
111
+ std::cerr << " Errorpaths is null." << std::endl;
105
112
return ;
106
113
}
107
114
for (size_t i = 0 ; i < numEvents; ++i) {
@@ -113,54 +120,55 @@ class MonitorDir::MonitorDirPrivate
113
120
}
114
121
}
115
122
116
- void monitor ()
123
+ bool monitor ()
117
124
{
118
- std::cout << " addWatch: " << dir << std::endl;
119
- CFStringRef pathToWatch = CFStringCreateWithCString (kCFAllocatorDefault ,
120
- dir.c_str (),
121
- kCFStringEncodingUTF8 );
122
- CFArrayRef pathsToWatch = CFArrayCreate (kCFAllocatorDefault ,
123
- reinterpret_cast <const void **>(&pathToWatch),
124
- 1 ,
125
- nullptr );
125
+ std::cout << " addWatch" << dir << std::endl;
126
+ auto pathToWatch = CFStringCreateWithCString (kCFAllocatorDefault ,
127
+ dir.c_str (),
128
+ kCFStringEncodingUTF8 );
129
+ auto pathsToWatch = CFArrayCreate (kCFAllocatorDefault ,
130
+ reinterpret_cast <const void **>(&pathToWatch),
131
+ 1 ,
132
+ nullptr );
126
133
FSEventStreamContext context{0 , this , nullptr , nullptr , nullptr };
127
- FSEventStreamRef stream = FSEventStreamCreate (kCFAllocatorDefault ,
128
- monitorCallback,
129
- &context,
130
- pathsToWatch,
131
- kFSEventStreamEventIdSinceNow ,
132
- 3 ,
133
- kFSEventStreamCreateFlagFileEvents );
134
- runLoop = CFRunLoopGetCurrent ();
135
- FSEventStreamScheduleWithRunLoop (stream, runLoop, kCFRunLoopDefaultMode );
134
+ stream = FSEventStreamCreate (kCFAllocatorDefault ,
135
+ monitorCallback,
136
+ &context,
137
+ pathsToWatch,
138
+ kFSEventStreamEventIdSinceNow ,
139
+ 0 .,
140
+ kFSEventStreamCreateFlagFileEvents );
141
+ if (stream == nullptr ) {
142
+ std::cerr << " Failed to create FSEventStream" << std::endl;
143
+ CFRelease (pathsToWatch);
144
+ CFRelease (pathToWatch);
145
+ return false ;
146
+ }
147
+ auto queue = dispatch_queue_create (nullptr , nullptr );
148
+ FSEventStreamSetDispatchQueue (stream, queue);
136
149
FSEventStreamStart (stream);
137
- CFRunLoopRun (); // This will block until the stream is stopped.
138
- FSEventStreamStop (stream);
139
- FSEventStreamInvalidate (stream);
140
- FSEventStreamRelease (stream);
141
150
CFRelease (pathsToWatch);
142
151
CFRelease (pathToWatch);
152
+ return true ;
143
153
}
144
154
145
155
void stop ()
146
156
{
147
- if (nullptr == runLoop ) {
157
+ if (nullptr == stream ) {
148
158
return ;
149
159
}
150
- if (CFRunLoopIsWaiting (runLoop) == 0U ) {
151
- CFRunLoopWakeUp (runLoop);
152
- }
153
- CFRunLoopStop (runLoop);
160
+ FSEventStreamStop (stream);
161
+ FSEventStreamInvalidate (stream);
162
+ FSEventStreamRelease (stream);
154
163
}
155
164
156
- void run () { monitor (); }
165
+ bool run () { return monitor (); }
157
166
158
167
MonitorDir *q_ptr;
159
168
160
- CFRunLoopRef runLoop = nullptr ;
169
+ FSEventStreamRef stream = nullptr ;
161
170
162
171
std::filesystem::path dir;
163
- std::thread monitorThread;
164
172
};
165
173
166
174
MonitorDir::MonitorDir (const std::filesystem::path &dir)
@@ -179,29 +187,20 @@ MonitorDir::~MonitorDir()
179
187
180
188
bool MonitorDir::start ()
181
189
{
182
- if (m_isRunning) {
190
+ if (m_isRunning. load () ) {
183
191
std::cerr << " MonitorDir is already running" << std::endl;
184
192
return false ;
185
193
}
186
-
187
- m_isRunning.store (true );
188
- d_ptr->monitorThread = std::thread ([this ] {
189
- d_ptr->run ();
190
- m_isRunning.store (false );
191
- });
192
-
193
- return true ;
194
+ m_isRunning.store (d_ptr->run ());
195
+ return m_isRunning.load ();
194
196
}
195
197
196
198
void MonitorDir::stop ()
197
199
{
198
- if (!m_isRunning) {
200
+ if (!m_isRunning. load () ) {
199
201
std::cerr << " MonitorDir is not running" << std::endl;
200
202
return ;
201
203
}
202
204
203
205
d_ptr->stop ();
204
- if (d_ptr->monitorThread .joinable ()) {
205
- d_ptr->monitorThread .join ();
206
- }
207
206
}
0 commit comments