因为存在多进程和线程,Linux下同一个进程名有可能有多个进程号。下面的程序可以一次获得同一进程名的所有进程号。
注意下面代码的局限性:如果允许程序带参数的话,使用该代码恐怕就起作用了,例如./myprocess -o filename -p port , 不信的可以自己写个代码试试。
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