Retrieve names of running processes
- by Dave DeLong
Hi everyone,
First off, I know that similar questions have been asked, but the answers provided haven't been very helpful so far (they all recommend one of the following options).
I have a user application that needs to determine if a particular process is running. Here's what I know about the process:
The name
The user (root)
It should already be running, since it's a LaunchDaemon, which means
Its parent process should be launchd (pid 1)
I've tried several ways to get this, but none have worked so far. Here's what I've tried:
Running ps and parsing the output. This works, but it's slow (fork/exec is expensive), and I'd like this to be as fast as possible.
Using the GetBSDProcessList function listed here. This also works, but the way in which they say to retrieve the process name (accessing kp_proc.p_comm from each kinfo_proc structure) is flawed. The resulting char* only contains the first 16 characters of the process name, which can be seen in the definition of the kp_proc structure:
#define MAXCOMLEN 16 //defined in param.h
struct extern_proc { //defined in proc.h
...snip...
char p_comm[MAXCOMLEN+1];
...snip...
};
Using libProc.h to retrieve process information:
pid_t pids[1024];
int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
for (int i = 0; i < numberOfProcesses; ++i) {
if (pids[i] == 0) { continue; }
char name[1024];
proc_name(pids[i], name, sizeof(name));
printf("Found process: %s\n", name);
}
This works, except it has the same flaw as GetBSDProcessList. Only the first portion of the process name is returned.
Using the ProcessManager function in Carbon:
ProcessSerialNumber psn;
psn.lowLongOfPSN = kNoProcess;
psn.highLongOfPSN = 0;
while (GetNextProcess(&psn) == noErr) {
CFStringRef procName = NULL;
if (CopyProcessName(&psn, &procName) == noErr) {
NSLog(@"Found process: %@", (NSString *)procName);
}
CFRelease(procName);
}
This does not work. It only returns process that are registered with the WindowServer (or something like that). In other words, it only returns apps with UIs, and only for the current user.
I can't use -[NSWorkspace launchedApplications], since this must be 10.5-compatible. In addition, this only returns information about applications that appear in the Dock for the current user.
I know that it's possible to retrieve the name of running processes (since ps can do it), but the question is "Can I do it without forking and exec'ing ps?".
Any suggestions?