Поскольку использование sysctl
уже давно не рекомендуется, рекомендуемый способ сделать это - изучить каждую из записей процесса в /proc
и прочитать файл comm
в каждой папке. , Если для вашего примера содержимое этого файла abc\n
, это процесс, который вы ищете.
Я действительно не говорю на C ++, но вот возможное решение в 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;
}
Предупреждение: если существует несколько запущенных процессов с именем, которое вы ищете, этот код будет возвращать только один. Если вы собираетесь это изменить, учтите, что с написанным наивным глобусом вы также изучите /proc/self/comm
, что потенциально может привести к дублированию записи.
Если существует несколько процессов с одним и тем же именем, на самом деле нет способа гарантировать, что вы получили правильный. По этой причине многие демоны могут сохранять свои pids в файл; проверьте свою документацию.