Skip to content

Instantly share code, notes, and snippets.

@CocoaBeans
Created September 8, 2013 18:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CocoaBeans/6487285 to your computer and use it in GitHub Desktop.
Save CocoaBeans/6487285 to your computer and use it in GitHub Desktop.
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