forked from WuBingzheng/memleax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proc_info.c
153 lines (134 loc) · 3.02 KB
/
proc_info.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
* read process information, on GNU/Linux and FreeBSD
*
* Author: Wu Bingzheng
* Date: 2016-5
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "proc_info.h"
#ifdef MLX_LINUX
#include <dirent.h>
#include <unistd.h>
const char *proc_maps(pid_t pid, size_t *start, size_t *end, int *exe_self)
{
static FILE *filp = NULL;
static char exe_name[1024];
static char ret_path[1024];
/* first, init */
if (filp == NULL) {
char pname[100];
sprintf(pname, "/proc/%d/maps", pid);
filp = fopen(pname, "r");
if (filp == NULL) {
perror("Error in open /proc/pid/maps");
exit(3);
}
sprintf(pname, "/proc/%d/exe", pid);
int exe_len = readlink(pname, exe_name, sizeof(exe_name));
if (exe_len < 0) {
perror("error in open /proc/pid/exe");
exit(3);
}
exe_name[exe_len] = '\0';
}
/* walk through */
char line[1024];
char perms[5];
char deleted[100];
int ia, ib, ic, id;
while (fgets(line, sizeof(line), filp) != NULL) {
int ret = sscanf(line, "%zx-%zx %s %x %x:%x %d %s %s",
start, end, perms, &ia, &ib, &ic, &id, ret_path, deleted);
if (ret == 8 && perms[2] == 'x' && ret_path[0] == '/') {
if (exe_self != NULL) {
*exe_self = (strcmp(ret_path, exe_name) == 0);
}
return ret_path;
}
}
fclose(filp);
filp = NULL;
return NULL;
}
pid_t proc_tasks(pid_t pid)
{
static DIR *dirp = NULL;
if (dirp == NULL) {
char tname[100];
sprintf(tname, "/proc/%d/task", pid);
dirp = opendir(tname);
if (dirp == NULL) {
perror("Error in open /proc/pid/tasks");
exit(3);
}
}
struct dirent *e;
while((e = readdir(dirp)) != NULL) {
pid_t task_id = atoi(e->d_name);
if (task_id != 0) {
return task_id;
}
}
closedir(dirp);
dirp = NULL;
return 0;
}
int proc_task_check(pid_t pid, pid_t child)
{
char tname[100];
sprintf(tname, "/proc/%d/task", pid);
DIR *dirp = opendir(tname);
if (dirp == NULL) {
perror("Error in open /proc/pid/tasks");
exit(3);
}
struct dirent *e;
while((e = readdir(dirp)) != NULL) {
if (atoi(e->d_name) == child) {
closedir(dirp);
return 1;
}
}
closedir(dirp);
return 0;
}
#endif /* MLX_LINUX */
#ifdef MLX_FREEBSD
#include <sys/user.h>
#include <libutil.h>
#include <libprocstat.h>
const char *proc_maps(pid_t pid, size_t *start, size_t *end, int *exe_self)
{
static struct kinfo_vmentry *freep = NULL;
static unsigned int i, cnt;
static char *exe_name;
/* first, init */
if (freep == NULL) {
struct kinfo_proc *ki = kinfo_getproc(pid);
if (ki == NULL) {
perror("Error in get process info");
exit(6);
}
freep = procstat_getvmmap(procstat_open_sysctl(), ki, &cnt);
exe_name = ki->ki_comm;
}
while (i < cnt) {
struct kinfo_vmentry *kve = &freep[i++];
if ((kve->kve_protection & KVME_PROT_EXEC) && kve->kve_path[0] == '/') {
*start = kve->kve_start;
*end = kve->kve_end;
if (exe_self != NULL) {
*exe_self = (strcmp(exe_name, strrchr(kve->kve_path, '/') + 1) == 0);
}
return kve->kve_path;
}
}
i = 0;
free(freep);
freep = NULL;
return NULL;
}
#endif /* MLX_FREEBSD */