Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linux - get pid of process

Tags:

c++

linux

pid

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.

like image 844
gln Avatar asked Mar 08 '11 12:03

gln


People also ask

How do I find the PID of a process?

Task Manager can be opened in a number of ways, but the simplest is to select Ctrl+Alt+Delete, and then select Task Manager. In Windows, first click More details to expand the information displayed. From the Processes tab, select Details to see the process ID listed in the PID column.


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.

like image 186
Cairnarvon Avatar answered Sep 30 '22 17:09

Cairnarvon


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++

like image 39
the JinX Avatar answered Sep 30 '22 18:09

the JinX