gerriet
(Gerriet M. Denkmann)
1
I tried:
let mib: [Int32] = [ CTL_KERN, KERN_PROCARGS, pid ]
let mibLen = UInt32(mib.count)
var length: size_t = 0
let si = sysctl( mib, mibLen, nil, &length, nil, 0)
this resulted in:
Error: Cannot convert value of type '[Int32]' to expected argument type 'UnsafeMutablePointer<Int32>?'
Then I tried:
let uMib: UnsafeMutablePointer<Int32> = UnsafeMutablePointer(mutating: mib)
let si = sysctl( uMib, mibLen, nil, &length, nil, 0)
This works, but produces:
Warning: Initialization of 'UnsafeMutablePointer<Int32>' results in a dangling pointer
What is the correct way to call sysctl() ?
Martin
(Martin R)
2
sysctl() takes a mutable pointer as the first argument, so you need to declare mib as a variable and pass the address of its element storage to the function with &mib:
var mib: [Int32] = [ CTL_KERN, KERN_PROCARGS, pid ]
// ...
let si = sysctl(&mib, mibLen, nil, &length, nil, 0)
If it is guaranteed that sysctl() does not write to the mib array (what I suspect, but do not know for sure) then you can also declare it as a constant and make the pointer mutable just for the system call:
let mib: [Int32] = [ CTL_KERN, KERN_PROCARGS, pid ]
// ...
let si = mib.withUnsafeBufferPointer { p in
sysctl(UnsafeMutablePointer(mutating: p.baseAddress), mibLen, nil, &length, nil, 0)
}
4 Likes