Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Returns a list of running BSD processes efficiently using sysctl
/* This returns the full process name, rather than the 16 char limit
the p_comm field of the proc struct is limited to.
Note that this only works if the process is running under the same
user you are, or you are running this code as root. If not, then
the p_comm field is used (this function returns nil).
*/
NSString *GetNameForProcessWithPID(pid_t pidNum)
{
NSString *returnString = nil;
int mib[4], maxarg = 0, numArgs = 0;
size_t size = 0;
char *args = NULL, *namePtr = NULL, *stringPtr = NULL;
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
size = sizeof(maxarg);
if ( sysctl(mib, 2, &maxarg, &size, NULL, 0) == -1 ) {
return nil;
}
args = (char *)malloc( maxarg );
if ( args == NULL ) {
return nil;
}
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = pidNum;
size = (size_t)maxarg;
if ( sysctl(mib, 3, args, &size, NULL, 0) == -1 ) {
free( args );
return nil;
}
memcpy( &numArgs, args, sizeof(numArgs) );
stringPtr = args + sizeof(numArgs);
if ( (namePtr = strrchr(stringPtr, '/')) != NULL ) {
(void)*namePtr++;
returnString = [[NSString alloc] initWithUTF8String:namePtr];
} else {
returnString = [[NSString alloc] initWithUTF8String:stringPtr];
}
free( args );
return [returnString autorelease];
}
NSArray *
GetRunningBSDProcesses(void)
{
NSMutableArray *returnArray = [[NSMutableArray alloc] initWithCapacity:1];
struct kinfo_proc *kp;
int mib[4], nentries, i;
size_t bufSize = 0;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ALL;
mib[3] = 0;
if ( sysctl(mib, 4, NULL, &bufSize, NULL, 0) < 0 ) {
return [returnArray autorelease];
}
kp = (struct kinfo_proc *)malloc( bufSize );
if ( kp == NULL ) {
return [returnArray autorelease];
}
if ( sysctl(mib, 4, kp, &bufSize, NULL, 0) < 0 ) {
free( kp );
return [returnArray autorelease];
}
nentries = (SInt32)bufSize / sizeof(struct kinfo_proc);
if ( nentries == 0 ) {
free( kp );
return [returnArray autorelease];
}
for ( i = (nentries - 1); --i >= 0; ) {
NSAutoreleasePool *forPool = [[NSAutoreleasePool alloc] init];
NSString *realName = GetNameForProcessWithPID( ((&kp[i])->kp_proc.p_pid) );
if ( realName != nil ) {
[returnArray addObject:realName];
} else {
[returnArray addObject:[NSString stringWithUTF8String:((&kp[i])->kp_proc.p_comm)]];
}
[forPool release];
}
free( kp );
return [returnArray autorelease];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment