mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
pstree.c
C Source File · 165 lines
pstree.c
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <getopt.h>
static int read_comm(pid_t pid, char *buf, size_t n) {
char path[64];
snprintf(path, sizeof(path), "/proc/%d/comm", pid);
FILE *f = fopen(path, "r");
if (!f) return -1;
if (!fgets(buf, (int)n, f)) { fclose(f); return -1; }
buf[strcspn(buf, "\n")] = 0;
fclose(f);
return 0;
}
static int get_ppid_from_stat(pid_t pid, pid_t *ppid_out) {
char path[64], line[4096];
snprintf(path, sizeof(path), "/proc/%d/stat", pid);
FILE *f = fopen(path, "r");
if (!f) return -1;
if (!fgets(line, sizeof(line), f)) { fclose(f); return -1; }
fclose(f);
int id, ppid;
char comm[256], state;
if (sscanf(line, "%d (%255[^)]) %c %d", &id, comm, &state, &ppid) != 4) return -1;
*ppid_out = (pid_t)ppid;
return 0;
}
void Version() {
printf("------my_pstree------\n");
printf("Version 1.0 generated by Katyusha & Codex\n");
}
#define MAXN 300005
struct process {
pid_t pid, ppid;
char *s;
};
typedef struct process process;
process p[MAXN];
int head[MAXN], ecnt;
struct edge {
int to, nxt;
};
typedef struct edge edge;
edge E[MAXN];
void add(int u, int v) {
E[++ecnt].to = v;
E[ecnt].nxt = head[u];
head[u] = ecnt;
}
int print_pid = 0, version = 0, print_sort = 0;
int cmp(process *x, process *y) {
if (print_sort) {
return (*x).pid < (*y).pid;
}
else {
int c = strcmp((*x).s, (*y).s);
if (c < 0) return 1;
if (c > 0) return 0;
return (*x).pid < (*y).pid;
}
}
void swap(int *x, int *y) {
int t = *x;
*x = *y;
*y = t;
}
void dfs(int u, int gap) {
for (int i = 1; i <= gap; i++) putchar(' ');
char buf[256], _buf[256];
if (u != 0) {
snprintf(_buf, sizeof(_buf), "(%d)", u);
snprintf(buf, sizeof(buf), "%s%s", p[u].s, (print_pid)? _buf : "");
printf("%s\n", buf);
}
int _gap = (u != 0) ? (gap + 3 + strlen(buf)) : 0;
int cid[1024], cnt = 0;
for (int i = head[u]; i ; i = E[i].nxt) {
int v = E[i].to;
cid[cnt++] = v;
}
while (1){
int flag = 0;
for (int i = 1; i < cnt; i++) {
if (cmp(&p[cid[i]], &p[cid[i - 1]])) {
swap(&cid[i - 1], &cid[i]);
flag = 1;
}
}
if (!flag) break;
}
for (int i = 0; i < cnt; i++) {
dfs(cid[i], _gap);
}
}
int main(int argc, char *argv[]) {
int opt;
static struct option option_long[] = {
{"show-pids", no_argument, 0, 'p'},
{"numeric-sort", no_argument, 0, 'n'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0}
};
while ((opt = getopt_long(argc, argv, "pnV", option_long, NULL)) != -1) {
switch (opt) {
case 'p':
print_pid = 1;
break;
case 'V':
version = 1;
break;
case 'n':
print_sort = 1;
break;
default:
return 1;
}
}
if (version) {
Version();
return 0;
}
DIR *d = opendir("/proc");
if (!d) {
perror("opendir /proc");
return 1;
}
struct dirent *de;
while ((de = readdir(d)) != NULL) {
if (!isdigit((unsigned char)de->d_name[0])) continue;
pid_t pid = (pid_t)atoi(de->d_name);
p[pid].s = (char *)malloc(256 * sizeof(char));
p[pid].pid = pid;
int ret1 = read_comm(pid, p[pid].s, 256);
int ret2 = get_ppid_from_stat(pid, &p[pid].ppid);
if (ret1 == -1 || ret2 == -1) continue;
add(p[pid].ppid, pid);
}
dfs(0, 0);
for (int i = 0; i < MAXN; i++) free(p[i].s);
closedir(d);
}

目录