原理:
linux操作系统中有一个名为/proc的虚拟文件系统,其中记录着进程和用户的相关信息,其中/proc/N (注:N表示数字)目录表示进程ip号为N的进程信息,就是这里找到我们要找的进程信息,其中/proc/N/status记录了进程状态信息,包含进程名等,比如:
root@proc # cat /proc/3544/status
Name: lighttpd
State: S (sleeping)
Tgid: 3544
Pid: 3544
PPid: 1
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
Utrace: 0
FDSize: 32
Groups: 500
VmPeak: 2980 kB
VmSize: 2976 kB
。。。。。
注:对于存在多个同名的进程,只返回第一个进程ip,而不返回所有的进程ip
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
static void getProcessName(const int pid, char *pid_name, int pid_size);
/*return:
* -1 not found
* not-negative is pid number
* writed by zhj
* */
int getPidByName(const char *name)
{
DIR *dir_p = NULL;
struct dirent entry, *res = NULL;
int pid = -1, error_ret = 0;
if(name == NULL)
{
return -1;
}
dir_p = opendir("/proc");
if(NULL == dir_p)
{
printf("opendir error: %s\n", strerror(errno));
goto ERR;
}
for(;;)
{
error_ret = readdir_r(dir_p, &entry, &res);
if(error_ret != 0)
{
printf("readdir_r error: %s\n", strerror(error_ret));
goto ERR;
}
if(res == NULL)
{
break;
}
if(isdigit(res->d_name[0]))
{
char pid_name[56] = "";
pid = atoi(res->d_name);
getProcessName(pid, pid_name, sizeof(pid_name));
if(pid_name[0] != '\0' && strcmp(pid_name, name) == 0)
{
break;
}
}
pid = -1;
}
if(dir_p != NULL)
{
closedir(dir_p);
dir_p = NULL;
}
return pid;
ERR:
if(dir_p != NULL)
{
closedir(dir_p);
dir_p = NULL;
}
return -1;
}
static void getProcessName(const int pid, char *pid_name, int pid_size)
{
int fd = -1;
char name[56] = "", *p = NULL, str[56] = "", buf[1024] = "";
int size = 0;
struct stat file_stat;
pid_name[0] = '\0';
size = snprintf(name, sizeof(name) - 1, "/proc/%d/status", pid);
if(size <= 0 || size > sizeof(name) - 1)
{
printf("%s %d, snprintf error\n", __func__, __LINE__);
goto ERR;
}
fd = open(name, O_RDONLY);
if(fd < 0)
{
printf("%s %d, open error: %s\n", __func__, __LINE__, strerror(errno));
goto ERR;
}
if(fstat(fd, &file_stat) < 0)
{
printf("fstat error: %s\n", strerror(errno));
goto ERR;
}
size = read(fd, buf, sizeof(buf) - 1);
if(size <= 0)
{
printf("read error: %s\n", strerror(errno));
goto ERR;
}
buf[size] = '\0';
if(sscanf(buf, "%s %s", str, pid_name) != 2)
{
goto ERR;
}
if(fd != -1)
{
close(fd);
fd = -1;
}
return ;
ERR:
if(fd != -1)
{
close(fd);
fd = -1;
}
return ;
}