Skip to content

Instantly share code, notes, and snippets.

@macshome
Last active April 29, 2024 05:33
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save macshome/c18bd88a6b8973bd1e5bfaea738f739e to your computer and use it in GitHub Desktop.
Save macshome/c18bd88a6b8973bd1e5bfaea738f739e to your computer and use it in GitHub Desktop.
Swift Playground to get all running processes on macOS
import Darwin
func getProcessList() {
// Requesting the pid of 0 from systcl will return all pids
var mib = [CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0]
var bufferSize = 0
// To find the needed buffer size you call sysctl with a nil results pointer.
// This sets the size of the buffer needed in the bufferSize pointer.
if sysctl(&mib, UInt32(mib.count), nil, &bufferSize, nil, 0) < 0 {
perror(&errno)
return
}
// Determine how many kinfo_proc struts will be returned.
// Using stride rather than size will take alligment into account.
let entryCount = bufferSize / MemoryLayout<kinfo_proc>.stride
// Create our buffer to be filled with the list of processes and allocate it.
// Use defer to make sure it's deallocated when the scope ends.
var procList: UnsafeMutablePointer<kinfo_proc>?
procList = UnsafeMutablePointer.allocate(capacity: bufferSize)
defer { procList?.deallocate() }
// Now we actually perform our query to get all the processes.
if sysctl(&mib, UInt32(mib.count), procList, &bufferSize, nil, 0) < 0 {
perror(&errno)
return
}
// Simply step through the returned bytes and lookup the data you want.
// If the pid is 0 that means it's invalid and should be ignored.
for index in 0...entryCount {
guard let pid = procList?[index].kp_proc.p_pid,
pid != 0,
let comm = procList?[index].kp_proc.p_comm else {
continue
}
// p_comm returns the first 16 characters of the process name as a tuple of CChars.
// An easy way to convert it to to an array of CChars is with a Mirror.
//
// If you want the full names you can make another sysctl request for the KERN_PROCARGS2
// mib for each pid.
let name = String(cString: Mirror(reflecting: comm).children.map(\.value) as! [CChar])
print("PID: \(pid), Name: \(name)")
}
}
getProcessList()
@macshome
Copy link
Author

Swift playground code to get all the active processes using sysctl. Mostly for learning how to use some POSIX stuff in Swift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment