Thunder
Thunder

Reputation: 631

List all processes with arguments in Swift

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);
}

Upvotes: 0

Views: 452

Answers (1)

Thunder
Thunder

Reputation: 631

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()

Upvotes: 1

Related Questions