-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy path12_2.c
158 lines (139 loc) · 3.94 KB
/
12_2.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
154
155
156
157
158
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <ctype.h>
#include <pwd.h>
#include <stdlib.h>
#include <limits.h>
#include <stdlib.h>
#define MAXNAME 256
#define MAXLINE 4096
typedef struct procnode procnode;
struct procnode
{
char name[MAXNAME];
int pid;
int ppid;
};
int procsz = 0;
int pid_max = 32;
procnode *proc;
/**
* 原本的想法是直接读 /proc/sys/kernel/pid_max 然后分配这个数,
* 算了算大约要1GB多点,就很离谱因为实际上才一百多个进程却分配了
* 多几个数量级,所以用realloc思路,最后只分配了128个数量。
* 一个GB和几个37KB的差距。。。我一开始脑子有毛病。。。
*
* 后面make_tree的算法就是无脑暴力,因为一共没多少数(逃。
*/
int handle_proc(const char *dir);
void make_tree(uid_t ppid, int layer);
int main(int argc, char *argv[])
{
char dirname[MAXNAME];
DIR *dirp;
struct dirent *dir_entry;
if (argc != 1)
{
printf("run it without any arguments.\n");
exit(0);
}
proc = (procnode *)malloc(sizeof(procnode) * pid_max);
dirp = opendir("/proc");
if (dirp == NULL)
{
printf("opendir failed\n");
exit(1);
}
while ((dir_entry = readdir(dirp)) != NULL)
{
if (dir_entry->d_type != DT_DIR)
continue;
strcpy(dirname, "/proc/");
strcat(dirname, dir_entry->d_name);
handle_proc(dirname);
}
// for (int i = 0; i < procsz; ++i)
// printf("name:%s|pid:%d|ppid:%d\n", proc[i].name, proc[i].pid, proc[i].ppid);
for (int i = 0; i < procsz; ++i)
if (proc[i].pid == 1)
printf("%s(pid%d|ppid%d)\n", proc[i].name, proc[i].pid, proc[i].ppid);
make_tree(1, 1);
return 0;
}
int handle_proc(const char *dir)
{
char filename[MAXNAME];
char proc_name[MAXLINE];
char str[MAXLINE];
char pid[MAXLINE];
char ppid[MAXLINE];
char *key;
char *value;
FILE *fp;
strcpy(filename, dir);
strcat(filename, "/status");
fp = fopen(filename, "r");
if (fp == NULL)
return 0; /* do nothing and normal return */
while ((fgets(str, MAXLINE, fp)) != NULL)
{
key = strtok(str, ":");
value = strtok(NULL, ":"); // 继续使用静态分配的,所以NULL
// 自动除了给定的符号,\n也会停止,符号可以多个",: ;",空格也可
if (key != NULL && value != NULL)
{
while (*value == ' ' || *value == '\t')
value++;
// printf("----%s-----%s", key, value);
if (strcmp(key, "Name") == 0)
strcpy(proc_name, value);
if (strcmp(key, "Pid") == 0)
strcpy(pid, value);
if (strcmp(key, "PPid") == 0)
strcpy(ppid, value);
}
}
pid[strlen(pid) - 1] = '\0';
ppid[strlen(ppid) - 1] = '\0';
proc_name[strlen(proc_name) - 1] = '\0';
strcpy(proc[procsz].name, proc_name);
proc[procsz].pid = atoi(pid);
proc[procsz].ppid = atoi(ppid);
++procsz;
if (procsz == pid_max)
{
proc = realloc(proc, 2 * procsz * sizeof(procnode));
pid_max = 2 * procsz;
// printf("---%d\n", procsz);
}
fclose(fp);
return 0;
}
void make_tree(uid_t ppid, int layer)
{
char empty[MAXLINE] = " ";
char end_empty[MAXLINE] = "";
for (int i = 0; i < layer; ++i)
strcat(end_empty, empty);
int pos = strlen(end_empty);
end_empty[pos - 1] = '|';
end_empty[pos] = '-';
end_empty[pos + 1] = '>';
end_empty[pos + 2] = '\0';
// int done = 1;
for (int i = 0; i < procsz; ++i)
{
if (proc[i].ppid == ppid)
{
// done = 0;
printf("%s%s(%d|%d)\n", end_empty, proc[i].name, proc[i].pid, proc[i].ppid);
make_tree(proc[i].pid, layer + 1);
}
}
// if (done)
// printf("\n");
}