根据进程名获取进程pid
摘自:https://blog.csdn.net/shanguangy111/article/details/77136187
原理:
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 }