因为存在多进程和线程,Linux下同一个进程名有可能有多个进程号。下面的程序可以一次获得同一进程名的所有进程号。
process.h
#ifndef __PROCESS_H__
#define __PROCESS_H__
char *basename(const char *path);
int get_pid_by_name(const char* process_name, pid_t pid_list[], int list_size);
int is_process_exist(const char* process_name);
#endif /* __PROCESS_H__ */
process.c (使用/proc/pid/exe 查找进程名有时候会有问题,比如busybox中的命令,查到的是busybox)
修改为使用/proc/pid/cmdline来查找。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <ctype.h>
#include <errno.h>
char *basename(const char *path)
{
register const char *s;
register const char *p;
p = s = path;
while (*s) {
if (*s++ == '/') {
p = s;
}
}
return (char *) p;
}
/* find all pid of process by name, only compare base name of pid_name
* pid_list: caller malloc pid_t array
* list_size: the size of pid_list
* RETURN:
* < 0: error number
* >=0: how many pid found, pid_list will store the founded pid
*/
int get_pid_by_name(const char* process_name, pid_t pid_list[], int list_size)
{
#define MAX_BUF_SIZE 256
DIR *dir;
struct dirent *next;
int count=0;
pid_t pid;
FILE *fp;
char *base_pname = NULL;
char *base_fname = NULL;
char cmdline[MAX_BUF_SIZE];
char path[MAX_BUF_SIZE];
if(process_name == NULL || pid_list == NULL)
return -EINVAL;
base_pname = basename(process_name);
if(strlen(base_pname) <= 0)
return -EINVAL;
dir = opendir("/proc");
if (!dir)
{
return -EIO;
}
while ((next = readdir(dir)) != NULL) {
/* skip non-number */
if (!isdigit(*next->d_name))
continue;
pid = strtol(next->d_name, NULL, 0);
sprintf(path, "/proc/%u/cmdline", pid);
fp = fopen(path, "r");
if(fp == NULL)
continue;
memset(cmdline, 0, sizeof(cmdline));
if(fread(cmdline, MAX_BUF_SIZE - 1, 1, fp) < 0){
fclose(fp);
continue;
}
fclose(fp);
base_fname = basename(cmdline);
if (strcmp(base_fname, base_pname) == 0 )
{
if(count >= list_size){
break;
}else{
pid_list[count] = pid;
count++;
}
}
}
closedir(dir) ;
return count;
}
/* If process is existed, return true */
int is_process_exist(const char* process_name)
{
pid_t pid;
return (get_pid_by_name(process_name, &pid, 1) > 0);
}
main.c
#include <stdlib.h>
#include <stdio.h>
#include "process.h"
#define MAX_PID_NUM 32
int main(int argc, char* argv[])
{
char* process;
int ret = 0;
int n;
pid_t pid[MAX_PID_NUM];
if(argc < 2)
process = argv[0];
else
process = argv[1];
ret = get_pid_by_name(process, pid, MAX_PID_NUM);
printf("process '%s' is existed? (%d): %c\n", process, ret, (ret > 0)?'y':'n');
for(n=0;n<ret;n++){
printf("%u\n", pid[n]);
}
return ret;
}
Makefile:
PROG=check_process
OBJS=process.o main.o
#CFLAGS = -g -ggdb
all:$(PROG)
check_process:$(OBJS)
$(CC) -o $@ $^ $(LDFLAGS)
%.o:%.c
$(CC) -c -o $@ $(CFLAGS) $<
clean:
rm -rf $(PROG) *.o