Creare un file watcher in Swift

Mattepuffo's logo
Creare un file watcher in Swift

Creare un file watcher in Swift

Premetto subito che ho testato questo codice sono su Linux, e funziona.

Non essendoci librerie particolari, dovrebbe funzionare anche su macOS.

In pratica si tratta di creare un filesystem watcher usando Swift.

Abbiamo usato inotify:

import Glibc

let path = "/home/fermat/TEST/"

let fd = inotify_init1(Int32(IN_NONBLOCK))
guard fd >= 0 else {
    perror("inotify_init1")
    exit(1)
}

let wd = inotify_add_watch(fd, path, UInt32(IN_CREATE | IN_DELETE | IN_MODIFY))
guard wd >= 0 else {
    perror("inotify_add_watch")
    exit(1)
}

print("Watching directory: \(path)")

let bufferSize = 1024
var buffer = [UInt8](repeating: 0, count: bufferSize)

while true {
    let length = read(fd, &buffer, bufferSize)
    if length < 0 {
        if errno == EAGAIN {
            usleep(500_000)
            continue
        } else {
            perror("read")
            break
        }
    }

    var i = 0
    while i < length {
        let event = buffer.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> inotify_event in
            return ptr.baseAddress!.advanced(by: i).assumingMemoryBound(to: inotify_event.self)
                .pointee
        }

        if event.len > 0 {
            let namePtr = buffer.withUnsafeBytes {
                (ptr: UnsafeRawBufferPointer) -> UnsafePointer<CChar> in
                return ptr.baseAddress!.advanced(by: i + MemoryLayout<inotify_event>.size)
                    .assumingMemoryBound(to: CChar.self)
            }
            let name = String(cString: namePtr)
            if (event.mask & UInt32(IN_CREATE)) != 0 {
                print("File created: \(name)")
            }
            if (event.mask & UInt32(IN_DELETE)) != 0 {
                print("File deleted: \(name)")
            }
            if (event.mask & UInt32(IN_MODIFY)) != 0 {
                print("File modified: \(name)")
            }
        }

        i += MemoryLayout<inotify_event>.size + Int(event.len)
    }
}

Enjoy!


Condividi

Commentami!