List all processes with arguments in Swift

290 Views Asked by At

I'm trying to convert some piece of code to Swift that will list all running processes. But since it requires calling some C specific APIs I'm a bit struggling. Can someone tell me here what am I doing here incorrectly? print statement at the end is outputting incorrect values. I assume it should be process name. Also line info = malloc(length) gives me the creeps. How should I properly allocate it?

var maxArgumentsSize: Int = 0
if maxArgumentsSize == 0 {
    var size: size_t = MemoryLayout<Int>.size
    var mib: [Int32] = [CTL_KERN, KERN_ARGMAX]
    let a = sysctl(&mib, 2, &maxArgumentsSize, &size, nil, 0)
    if a == -1 {
        maxArgumentsSize = 4096;
    }
}

var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_ALL]
var info: UnsafeMutableRawPointer? = nil
var length: size_t = 0
var count: Int = 0

if sysctl(&mib, 3, nil, &length, nil, 0) < 0 {
    exit(EXIT_FAILURE)
}

info = malloc(length)

if sysctl(&mib, 3, info, &length, nil, 0) < 0 {
    free(info)
    exit(EXIT_FAILURE)
}

count = length / MemoryLayout<kinfo_proc>.size
for index in 0...count {
    let info = info?.assumingMemoryBound(to: kinfo_proc.self)
    let pid: pid_t = info![index].kp_proc.p_pid
    let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: maxArgumentsSize)
    var mib: [Int32] = [CTL_KERN, KERN_PROCARGS2, pid]
    if sysctl(&mib, 3, buffer, &maxArgumentsSize, nil, 0) == 0 {
        let str = String(cString: buffer, encoding: .utf8)
        print(str)
    }
    free(buffer);
}
1

There are 1 best solutions below

1
Thunder On BEST ANSWER

Basically I've changed my initial code to this and calling @MartinR solution (https://stackoverflow.com/a/72445381/1187415) at the end. Of course it's not complete and pasted from my code directly but it's working.

// Get all processess information:
var name: [CInt] = [CTL_KERN, KERN_PROC, KERN_PROC_ALL]
var length: size_t = 0
if sysctl(&name, CUnsignedInt(name.count), nil, &length, nil, 0) < 0 {
    return
}
var infoPtr = UnsafeMutableRawPointer.allocate(
    byteCount: length,
    alignment: MemoryLayout<kinfo_proc>.alignment
)
if sysctl(&name, CUnsignedInt(name.count), infoPtr, &length, nil, 0) < 0 {
    infoPtr.deallocate()
    return
}
let count = length / MemoryLayout<kinfo_proc>.size
for index in 0...count {
    let info = infoPtr.assumingMemoryBound(to: kinfo_proc.self)
    let pid: pid_t = info[index].kp_proc.p_pid
    let arguments = self.processArguments(pid: pid)
}
infoPtr.deallocate()