Linux下通过进程名获得进程号

因为存在多进程和线程,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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值