The statfs struct in C has these char array members:
char f_mntonname[MNAMELEN]; /* directory on which mounted */
char f_mntfromname[MNAMELEN]; /* mounted file system */
The Swift type for these arrays in the Darwin.sys.mount module is a tuple with 90 elements:
public var f_mntonname: (Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8,
...
Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8, Int8)
Another question about Converting a C char array to a String has an answer with code that I use twice in this example:
import Darwin.sys.mount
var vols: UnsafeMutablePointer<statfs>?
let count = getmntinfo(&vols, 0)
if let volsarray = vols, count > 0 {
for i in 0 ..< count {
var vol = volsarray[Int(i)]
let mntOnName = withUnsafePointer(to: &vol.f_mntonname) {
$0.withMemoryRebound(to: UInt8.self,
capacity: MemoryLayout.size(ofValue: vol.f_mntonname)) {
String(cString: $0)
}
}
let mntFromName = withUnsafePointer(to: &vol.f_mntfromname) {
$0.withMemoryRebound(to: UInt8.self,
capacity: MemoryLayout.size(ofValue: vol.f_mntfromname)) {
String(cString: $0)
}
}
print("on \(mntOnName) from \(mntFromName)")
}
}
To avoid repeating the code twice, I refactored the conversion code into the function below, but passing &vol.f_mntonname to it won't compile, and I can't see a way to fix the problem by using a different type for the first argument.
func charArrayToString(_ array: UnsafePointer<Int8>, capacity: Int) -> String {
return array.withMemoryRebound(to: UInt8.self, capacity: capacity) {
String(cString: $0)
}
}
var a = (Int8(65), Int8(66), Int8(67))
print(charArrayToString(&a, capacity: 3)) // doesn't compile
The compiler complains about call to charArrayToString:
Cannot convert value of type '(Int8, Int8, Int8)' to expected argument type 'Int8'
It also complains when I pass a instead of &a:
Cannot convert value of type '(Int8, Int8, Int8)' to expected argument type 'UnsafePointer<Int8>'