Reputation: 103
I'm using C's inotify
library, through a wrapper in Swift. The idea is to provide a Swift Package Manager library that gives basic File System events support in Linux.
Almost everything works. Except that here, I can't seem to be able to copy the inotify_event
member name
:
let bufferLength = Int(MemoryLayout<inotify_event>.size + NAME_MAX + 1)
let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: bufferLength)
var fileSystemEvent : FileSystemEvent?
var currentIndex: Int = 0
let readLength = read(Int32(self.fileDescriptor), buffer, bufferLength)
while currentIndex < readLength {
var event = withUnsafePointer(to: &buffer[currentIndex]) {
return $0.withMemoryRebound(to: inotify_event.self, capacity: 1) {
return $0.pointee
}
}
if event.len > 0 {
fileSystemEvent = FileSystemEvent(
watchDescriptor: WatchDescriptor(event.wd),
name: "", //String(cString: event.name),
mask: event.mask,
cookie: event.cookie,
length: event.len
)
}
currentIndex += MemoryLayout<inotify_event>.stride + Int(event.len)
}
I would want to do:
name: String(cString: event.name)
, but then the compiler throws an error:
`value of type 'inotify_event' has no member 'name'`
I can't find any clues as to why this happens, or as to how I can access the name
member. Here is the struct's declaration in inotify.h
:
/*
* struct inotify_event - structure read from the inotify device for each event
*
* When you are watching a directory, you will receive the filename for events
* such as IN_CREATE, IN_DELETE, IN_OPEN, IN_CLOSE, ..., relative to the wd.
*/
struct inotify_event {
__s32 wd; /* watch descriptor */
__u32 mask; /* watch mask */
__u32 cookie; /* cookie to synchronize two events */
__u32 len; /* length (including nulls) of name */
char name[0]; /* stub for possible name */
};
What's going on here?
Thanks in advance :)
PS: here's my full project, if you need more information.
Upvotes: 1
Views: 128
Reputation: 539685
The name
field is defined as a zero-length array:
char name[0]; /* stub for possible name */
and those are not imported into Swift. A possible solution is to compute the offset to the start of the name string within the received buffer:
fileSystemEvent = FileSystemEvent(
watchDescriptor: WatchDescriptor(event.wd),
name: String(cString: buffer + currentIndex + MemoryLayout<inotify_event>.size),
mask: event.mask,
cookie: event.cookie,
length: event.len)
Upvotes: 1