Implement auto subtree watching of a directory
Allow recursively watching a directory while adding newly created subdirectories to the inotify watch list.
This commit is contained in:
@@ -24,7 +24,7 @@ public actor Inotify {
|
||||
guard wd >= 0 else {
|
||||
throw InotifyError.addWatchFailed(path: path, errno: cinotify_get_errno())
|
||||
}
|
||||
watches.add(path, withId: wd)
|
||||
watches.add(path, withId: wd, mask: mask)
|
||||
return wd
|
||||
}
|
||||
|
||||
@@ -39,6 +39,13 @@ public actor Inotify {
|
||||
return result
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
public func addWatchWithAutomaticSubtreeWatching(forDirectory path: String, mask: InotifyEventMask) async throws -> [CInt] {
|
||||
let wds = try await self.addRecursiveWatch(forDirectory: path, mask: mask)
|
||||
watches.enableAutomaticSubtreeWatching(forIds: wds)
|
||||
return wds
|
||||
}
|
||||
|
||||
public func removeWatch(_ wd: CInt) throws {
|
||||
guard inotify_rm_watch(self.fd, wd) == 0 else {
|
||||
throw InotifyError.removeWatchFailed(watchDescriptor: wd, errno: cinotify_get_errno())
|
||||
@@ -50,11 +57,24 @@ public actor Inotify {
|
||||
cinotify_deinit(self.fd)
|
||||
}
|
||||
|
||||
private func transform(_ rawEvent: RawInotifyEvent) -> InotifyEvent? {
|
||||
private func transform(_ rawEvent: RawInotifyEvent) async -> InotifyEvent? {
|
||||
guard let path = self.watches.path(forId: rawEvent.watchDescriptor) else { return nil }
|
||||
let event = InotifyEvent.init(from: rawEvent, inDirectory: path)
|
||||
await self.addWatchInCaseOfAutomaticSubtreeWatching(event)
|
||||
return InotifyEvent.init(from: rawEvent, inDirectory: path)
|
||||
}
|
||||
|
||||
private func addWatchInCaseOfAutomaticSubtreeWatching(_ event: InotifyEvent) async {
|
||||
guard watches.isAutomaticSubtreeWatching(event.watchDescriptor),
|
||||
event.mask.contains(.create),
|
||||
event.mask.contains(.isDir) else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let mask = self.watches.mask(forId: event.watchDescriptor) else { return }
|
||||
let _ = try? await self.addWatchWithAutomaticSubtreeWatching(forDirectory: event.path.string, mask: mask)
|
||||
}
|
||||
|
||||
private static func createEventReader(forFileDescriptor fd: CInt) -> (any DispatchSourceRead, AsyncStream<RawInotifyEvent>) {
|
||||
let (stream, continuation) = AsyncStream<RawInotifyEvent>.makeStream(
|
||||
of: RawInotifyEvent.self,
|
||||
|
||||
Reference in New Issue
Block a user