#include <stdio.h> #include <stdlib.h> #include <dirent.h> #include <getopt.h> #include <sys/types.h> #include <string.h> #include <unistd.h> #include <stdbool.h> typedef struct pipinfo { char pidname[36]; pid_t pid; pid_t ppid; } Pipinfo; typedef struct processtree { pid_t pid; char pidname[36]; } Processtree;
Pipinfo allpid[666] = { 0 }; int pidcount = 0;
void setProcessInfo(); pid_t getPpid(char*, char*); void creatTree(bool pid, Processtree* root, int paddinglen); void findAllchild(pid_t pid, int* childrenar);
int main(int argc, char* argv[]) { setProcessInfo(); Processtree* root = (Processtree*)malloc(sizeof(Processtree)); root->pid = allpid[0].pid; strcpy(root->pidname, allpid[0].pidname);
int opt; struct option longopt[] = { {"show-pids",0,NULL,'p'}, {"numeric-sort",0,NULL,'n'}, {"version",0,NULL,'V'} }; switch (opt = getopt_long(argc, argv, "Vpnh", longopt, NULL)) { case 'V': printf("Grxer 2023 3 25\n"); break; case 'p': creatTree(true, root, 0); break; case 'n': creatTree(false, root, 0); break; } if (optind == argc) { creatTree(false, root, 0); } else printf("pstree -h for help");
}
void setProcessInfo() { DIR* proc = opendir("/proc"); if (!proc) { fprintf(stderr, "%s", "Can 't open /proc/"); exit(1); } else { int pid = 0; struct dirent* entry; while (NULL != (entry = readdir(proc))) { if (0 == (pid = atoi(entry->d_name))) continue; allpid[pidcount].pid = pid; allpid[pidcount].ppid = getPpid(entry->d_name, allpid[pidcount].pidname); pidcount++; }
} closedir(proc); }
pid_t getPpid(char* pid, char* name) { char processpath[30] = "/proc/"; strcat(processpath, pid); strcat(processpath, "/stat"); FILE* fp = fopen(processpath, "r"); if (fp) { char i; pid_t _pid, ppid; fscanf(fp, "%d (%s %c %d", &_pid, name, &i, &ppid); name[strlen(name) - 1] = 0; fclose(fp); return ppid; } fprintf(stderr, "%s %s %s", "open", processpath, "fail"); exit(1); }
void creatTree(bool pidflag, Processtree* root, int paddinglen) { int childrens[666] = { 0 }; findAllchild(root->pid, childrens); char str[60] = { 0 }; if (childrens[0] == 0) { if (pidflag) printf("%s(%d)", root->pidname, root->pid); else printf("%s", root->pidname); return; } if (pidflag) sprintf(str, "%s(%d)-+-", root->pidname, root->pid); else sprintf(str, "%s-+-", root->pidname); printf("%s", str); for (size_t i = 0; i < 666 && 0 != childrens[i]; i++) { Processtree* temp = (Processtree*)malloc(sizeof(Processtree)); if (temp == NULL) { printf("malloc failed"); exit(1); } temp->pid = allpid[childrens[i]].pid; strcpy(temp->pidname, allpid[childrens[i]].pidname); creatTree(pidflag, temp, strlen(str) + paddinglen); if (i + 1 < 500 && childrens[i + 1] != 0) { printf("\n"); for (size_t i = 0; i < strlen(str) + paddinglen; i++) { printf(" "); } printf("|-"); } } free(root);
}
void findAllchild(pid_t pid, int* childrenar) { size_t index = 0; size_t i = 0; for (;i < pidcount - 1; i += 2) { if (allpid[i].ppid == pid) childrenar[index++] = i; if (allpid[i + 1].ppid == pid) childrenar[index++] = i + 1; } for (; i < pidcount; i++) { if (allpid[i].ppid == pid) childrenar[index++] = i; }
}
|