原理:
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

1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <errno.h>
5 #include <sys/types.h>
6 #include <dirent.h>
7 #include <sys/stat.h>
8 #include <sys/mman.h>
9 #include <fcntl.h>
10 #include <ctype.h>
11 #include <unistd.h>
12
13 static void getProcessName(const int pid, char *pid_name, int pid_size);
14 /*return:
15 * -1 not found
16 * not-negative is pid number
17 * writed by zhj
18 * */
19 int getPidByName(const char *name)
20 {
21 DIR *dir_p = NULL;
22 struct dirent entry, *res = NULL;
23 int pid = -1, error_ret = 0;
24 if(name == NULL)
25 {
26 return -1;
27 }
28
29 dir_p = opendir("/proc");
30 if(NULL == dir_p)
31 {
32 printf("opendir error: %s\n", strerror(errno));
33 goto ERR;
34 }
35 for(;;)
36 {
37 error_ret = readdir_r(dir_p, &entry, &res);
38 if(error_ret != 0)
39 {
40 printf("readdir_r error: %s\n", strerror(error_ret));
41 goto ERR;
42 }
43 if(res == NULL)
44 {
45 break;
46 }
47 if(isdigit(res->d_name[0]))
48 {
49 char pid_name[56] = "";
50
51 pid = atoi(res->d_name);
52
53 getProcessName(pid, pid_name, sizeof(pid_name));
54 if(pid_name[0] != '\0' && strcmp(pid_name, name) == 0)
55 {
56 break;
57 }
58 }
59 pid = -1;
60 }
61
62
63 if(dir_p != NULL)
64 {
65 closedir(dir_p);
66 dir_p = NULL;
67 }
68 return pid;
69 ERR:
70 if(dir_p != NULL)
71 {
72 closedir(dir_p);
73 dir_p = NULL;
74 }
75 return -1;
76 }
77
78
79 static void getProcessName(const int pid, char *pid_name, int pid_size)
80 {
81 int fd = -1;
82 char name[56] = "", *p = NULL, str[56] = "", buf[1024] = "";
83 int size = 0;
84 struct stat file_stat;
85
86 pid_name[0] = '\0';
87 size = snprintf(name, sizeof(name) - 1, "/proc/%d/status", pid);
88 if(size <= 0 || size > sizeof(name) - 1)
89 {
90 printf("%s %d, snprintf error\n", __func__, __LINE__);
91 goto ERR;
92 }
93
94 fd = open(name, O_RDONLY);
95 if(fd < 0)
96 {
97 printf("%s %d, open error: %s\n", __func__, __LINE__, strerror(errno));
98 goto ERR;
99 }
100 if(fstat(fd, &file_stat) < 0)
101 {
102 printf("fstat error: %s\n", strerror(errno));
103 goto ERR;
104 }
105 size = read(fd, buf, sizeof(buf) - 1);
106 if(size <= 0)
107 {
108 printf("read error: %s\n", strerror(errno));
109 goto ERR;
110 }
111 buf[size] = '\0';
112
113 if(sscanf(buf, "%s %s", str, pid_name) != 2)
114 {
115 goto ERR;
116 }
117
118 if(fd != -1)
119 {
120 close(fd);
121 fd = -1;
122 }
123
124 return ;
125 ERR:
126 if(fd != -1)
127 {
128 close(fd);
129 fd = -1;
130 }
131
132 return ;
133 }