How can I get the PID of a service called abc
using C++ on Linux without using a system call? I would appreciate any examples that you care to offer.
-
@Lazarus - I tried using sysctl but my linux doesn't recognize kinfo_proc (SUSE) – gln Mar 08 '11 at 13:00
-
@Tim Post - what do you mean - can you explain in an answer? – gln Mar 08 '11 at 13:04
-
1The only way you can learn information about the world outside your process's address space is by making a system call. What are you _really_ trying to achieve? – sarnold Mar 08 '11 at 13:08
-
... Do you mean, "Without using `system(3)`?" – sarnold Mar 08 '11 at 13:13
-
See also http://stackoverflow.com/questions/939778/linux-api-to-list-running-processes/941304#941304 – Craig McQueen Aug 27 '13 at 01:14
2 Answers
Since use of sysctl
has been discouraged for ages now, the recommended way of doing this is by examining each of the process entries in /proc
and reading the comm
file in each folder. If, for your example, the contents of that file are abc\n
, that's the process you're looking for.
I don't really speak C++, but here's a possible solution in POSIX C89:
#include <glob.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
pid_t find_pid(const char *process_name)
{
pid_t pid = -1;
glob_t pglob;
char *procname, *readbuf;
int buflen = strlen(process_name) + 2;
unsigned i;
/* Get a list of all comm files. man 5 proc */
if (glob("/proc/*/comm", 0, NULL, &pglob) != 0)
return pid;
/* The comm files include trailing newlines, so... */
procname = malloc(buflen);
strcpy(procname, process_name);
procname[buflen - 2] = '\n';
procname[buflen - 1] = 0;
/* readbuff will hold the contents of the comm files. */
readbuf = malloc(buflen);
for (i = 0; i < pglob.gl_pathc; ++i) {
FILE *comm;
char *ret;
/* Read the contents of the file. */
if ((comm = fopen(pglob.gl_pathv[i], "r")) == NULL)
continue;
ret = fgets(readbuf, buflen, comm);
fclose(comm);
if (ret == NULL)
continue;
/*
If comm matches our process name, extract the process ID from the
path, convert it to a pid_t, and return it.
*/
if (strcmp(readbuf, procname) == 0) {
pid = (pid_t)atoi(pglob.gl_pathv[i] + strlen("/proc/"));
break;
}
}
/* Clean up. */
free(procname);
free(readbuf);
globfree(&pglob);
return pid;
}
Caveat: if there are multiple running processes with the name you're looking for, this code will only return one. If you're going to change that, be aware that with the naive glob written, you'll also examine /proc/self/comm
, which could potentially lead to a duplicate entry.
If there are multiple processes with the same name, there isn't really a way to ensure you got the right one. Many daemons have the ability to save their pids to a file for this reason; check your documentation.

- 25,981
- 9
- 51
- 65
Google has this covered :)
http://programming-in-linux.blogspot.com/2008/03/get-process-id-by-name-in-c.html
Although it does use sysctl, which is a system call!
It's C but should work just as well in C++

- 1,950
- 1
- 18
- 23
-
I have an error on kinfo_proc: forward declaration of struct kinfo_proc - any help? – gln Mar 08 '11 at 13:02
-
-
Perhaps some of the -dev packages are not installed. Can you compile other applications? – the JinX Mar 08 '11 at 13:12
-
6
-
1[Web archive link here.](http://web.archive.org/web/20111003002604/http://programming-in-linux.blogspot.com/2008/03/get-process-id-by-name-in-c.html) That article was for FreeBSD, not for Linux. – Craig McQueen Aug 26 '13 at 04:14