From e2970d37bba1545f808a9eeb8c1ca5c3e3b5e256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=B5=A9=E7=84=B6?= <10195501441@stu.ecnu.edu.cn> Date: Thu, 18 Mar 2021 18:35:16 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4=20'ref.c'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ref.c | 924 ------------------------------------------------------------------ 1 file changed, 924 deletions(-) delete mode 100644 ref.c diff --git a/ref.c b/ref.c deleted file mode 100644 index 552c8dc..0000000 --- a/ref.c +++ /dev/null @@ -1,924 +0,0 @@ -#include //标准I/O库 -#include //实用程序库函数 -#include //字符串操作 -#include // 信号 -#include -#include //实现常量 -#include -#include -#include //时间和日期 -#include //出错码 -#include //验证程序断言 - -#include //目录项 -#include //文件控制 -#include //口令文件 -#include //符号常量 - -#include -#include -#include -#include -#include -#include -#include -#include - -#include //文件状态 -#include //基本系统数据类型 -#include //进程控制 -#include //进程时间 -#include -#include //select函数 - -//一般的命令0 -//输出重定向1 -//输入重定向2 -//命令中有管道3 -//#define SELF ((endpoint_t) 0x8ace) /* used to indicate 'own process' */ -//#define _MAX_MAGIC_PROC (SELF) /* used by */ -//#define MAX_NR_TASKS 1023 -//#define _ENDPOINT_GENERATION_SIZE (MAX_NR_TASKS+_MAX_MAGIC_PROC+1) -//#define _ENDPOINT_P(e) -//((((e)+1023) % (1023+((endpoint_t) 0x8ace)+1)) - 1023) -//#define SLOT_NR(e) (_ENDPOINT_P(e) + nr_tasks) - -#define _PATH_PROC "/proc/" -#define PSINFO_VERSION 0 -#define TYPE_TASK 'T' -#define TYPE_SYSTEM 'S' -#define TYPE_USER 'U' -#define STATE_RUN 'R' -#define TIMECYCLEKEY 't' -#define ORDERKEY 'o' - -#define USED 0x1 -#define IS_TASK 0x2 -#define IS_SYSTEM 0x4 -#define BLOCKED 0x8 - -#define ORDER_CPU 0 -#define ORDER_MEMORY 1 -#define ORDER_HIGHEST ORDER_MEMORY - -#define TC_BUFFER 1024 /* Size of termcap(3) buffer */ -#define TC_STRINGS 200 /* Enough room for cm,cl,so,se */ - -/* name of cpu cycle types, in the order they appear in /psinfo. */ -const char *cputimenames[] = {"user", "ipc", "kernelcall"}; -#define CPUTIMENAMES (sizeof(cputimenames) / sizeof(cputimenames[0])) - -#define CPUTIME(m, i) (m & (1L << (i))) - -struct proc -{ - int p_flags; // - endpoint_t p_endpoint; //端点 - pid_t p_pid; //进程号 - u64_t p_cpucycles[CPUTIMENAMES]; //cpu周期 - int p_priority; //动态优先级 - endpoint_t p_blocked; //阻塞状态 - time_t p_user_time; //用户时间 - vir_bytes p_memory; //内存 - uid_t p_effuid; //有效用户ID - int p_nice; //静态优先级 - char p_name[PROC_NAME_LEN + 1]; //名字 -}; - -struct proc *proc = NULL, *prev_proc = NULL; - -struct tp -{ - struct proc *p; - u64_t ticks; -}; - -void getOrder(char *); //得到输入的命令 -void anaOrder(char *, int *, char (*)[256]); //对输入的命令进行解析 -void exeCommand(int, char (*)[256]); //执行命令 -int checkCommand(char *command); //查找命令中的可执行程序 -void getkinfo(); //读取/proc/kinfo得到总的进程和任务数nr_total -int print_memory(); //输出内存信息 -void get_procs(); //记录当前进程,赋值给prev_proc -void parse_dir(); //获取到/proc/下的所有进程pid -void parse_file(pid_t pid); //获取每一个进程信息 -u64_t cputicks(struct proc *p1, struct proc *p2, int timemode); //计算每个进程的滴答 -void print_procs(struct proc *proc1, struct proc *proc2, int cputimemode); //输出CPU使用时间 - -char *message; //用于myshell提示信息的输出 -int whilecnt = 0; -char msg[40][256]; -unsigned int nr_procs, nr_tasks; //进程数和任务数 -int nr_total; //进程和任务总数 -int order = ORDER_CPU; -int blockedverbose = 0; -char *Tclr_all; -int slot = 1; - -/*static inline u64_t make64(unsigned long lo, unsigned long hi) -{ - return ((u64_t)hi << 32) | (u64_t)lo; -} -*/ - -/* -函数名: memset -功 能: 设置s中的所有字节为ch, s数组的大小由n给定 -用 法: void *memset(void *s, char ch, unsigned n); -程序例: - -#include -#include -#include - -int main(void) -{ - char buffer[] = "Hello world\n"; - - printf("Buffer before memset: %s\n", buffer); - memset(buffer, '*', strlen(buffer) - 1); - printf("Buffer after memset: %s\n", buffer); - return 0; -} -*/ -/* -函数名: getcwd -功 能: 取当前工作目录 -用 法: char *getcwd(char *buf, int n); -程序例: -#include -#include -int main(void) -{ - char buffer[MAXPATH]; - - getcwd(buffer, MAXPATH); - printf("The current directory is: %s\n", buffer); - return 0; -} -*/ - -int main(int argc, char **argv) -{ - int i; - int wordcount = 0; - char wordmatrix[100][256]; - char **arg = NULL; - char *buf = NULL; //用户输入 - - if ((buf = (char *)malloc(256)) == NULL) - { - perror("malloc failed"); - exit(-1); - } - - while (1) - { - memset(buf, 0, 256); //将buf所指的空间清零 - message = (char *)malloc(100); - getcwd(message, 100); - printf("myshell:%s# ", message); - free(message); - getOrder(buf); - strcpy(msg[whilecnt], buf); - whilecnt++; - if (strcmp(buf, "exit\n") == 0) - { - break; - } - for (i = 0; i < 100; i++) - { - wordmatrix[i][0] = '\0'; - } - wordcount = 0; - anaOrder(buf, &wordcount, wordmatrix); - exeCommand(wordcount, wordmatrix); - } - - if (buf != NULL) - { - free(buf); - buf = NULL; - } - return 0; -} - -//获取用户输入 -void getOrder(char *buf) -{ - int cnt = 0; - - int c = getchar(); - while (cnt < 256 && c != '\n') - { - buf[cnt++] = c; - c = getchar(); - } - buf[cnt++] = '\n'; - buf[cnt] = '\0'; - if (cnt == 256) - { - exit(-1); - } -} - -//解析buf中的命令,将结果存入wordmatrix中,命令以回车符号\n结束 -void anaOrder(char *buf, int *wordcount, char (*wordmatrix)[256]) -{ - char *p = buf; - char *q = buf; - int number = 0; - int i; - while (1) - { - if (p[0] == '\n') - { - break; - } - if (p[0] == ' ') - { - p++; - } - else - { - q = p; - number = 0; - while ((q[0] != ' ') && (q[0] != '\n')) - { - if (q[0] == 92) - { - q[0] = ' '; - q[1] = q[2]; - for (i = 2;; i++) - { - q[i] = q[i + 1]; - if ((q[i] == ' ') || (q[i] == '\n')) - break; - } - } - number++; - q++; - } - strncpy(wordmatrix[*wordcount], p, number + 1); - wordmatrix[*wordcount][number] = '\0'; - *wordcount = *wordcount + 1; - p = q; - } - } -} -/* -函数名: dup2 -功 能: 复制文件句柄 -用 法: int dup2(int oldhandle, int newhandle); -程序例: - -#include -#include -#include -#include - -int main(void) -{ - #define STDOUT 1 - - int nul, oldstdout; - char msg[] = "This is a test"; - - //create a file - nul = open("DUMMY.FIL", O_CREAT | O_RDWR, - S_IREAD | S_IWRITE); - - //create a duplicate handle for standard output - oldstdout = dup(STDOUT); - redirect standard output to DUMMY.FIL - by duplicating the file handle onto the - file handle for standard output. - dup2(nul, STDOUT); - - close the handle for DUMMY.FIL - close(nul); - - will be redirected into DUMMY.FIL - write(STDOUT, msg, strlen(msg)); - - restore original standard output handle - dup2(oldstdout, STDOUT); - - //close duplicate handle for STDOUT - close(oldstdout); - - return 0; -} -*/ - -void exeCommand(int wordcount, char (*wordmatrix)[256]) -{ - pid_t pid; - char *file; - int correct = 1; - int way = 0; - int status; - int i; - int fd; - char *word[wordcount + 1]; - char *wordnext[wordcount + 1]; - - //将命令取出 - for (i = 0; i < wordcount; i++) - { - word[i] = (char *)wordmatrix[i]; - } - word[wordcount] = NULL; - - //查看命令行是否有后台运行符 - for (i = 0; i < wordcount; i++) - { - if (strncmp(word[i], "&", 1) == 0) - { - way = 4; - word[wordcount - 1] = NULL; - } - } - - for (i = 0; word[i] != NULL; i++) - { - if (strcmp(word[i], ">") == 0) - { - way = 1; - if (word[i + 1] == NULL) - { - correct = 0; - } - } - if (strcmp(word[i], "<") == 0) - { - way = 2; - if (i == 0) - { - correct = 0; - } - } - if (strcmp(word[i], "|") == 0) - { - way = 3; - if (word[i + 1] == NULL) - { - correct = 0; - } - if (i == 0) - { - correct = 0; - } - } - } - //correct=0,说明命令格式不对 - if (correct == 0) - { - printf("wrong format\n"); - return; - } - - if (way == 1) - { - //输出重定向 - for (i = 0; word[i] != NULL; i++) - { - if (strcmp(word[i], ">") == 0) - { - file = word[i + 1]; - word[i] = NULL; - } - } - } - - if (way == 2) - { - //输入重定向 - for (i = 0; word[i] != NULL; i++) - { - if (strcmp(word[i], "<") == 0) - { - file = word[i + 1]; - word[i] = NULL; - } - } - } - - if (way == 3) - { - //把管道符后面的部分存入wordnext中,管道后面的部分是一个可执行的shell命令 - for (i = 0; word[i] != NULL; i++) - { - if (strcmp(word[i], "|") == 0) - { - word[i] = NULL; - int j; - for (j = i + 1; word[j] != NULL; j++) - { - wordnext[j - i - 1] = word[j]; - } - wordnext[j - i - 1] = NULL; - } - } - } - - if (strcmp(word[0], "cd") == 0) - { - if (word[1] == NULL) - { - return; - } - if (chdir(word[1]) == -1) - { - perror("cd"); - } - return; - } - - if ((pid = fork()) < 0) - { //创建子进程 - printf("fork error\n"); - return; - } - - if (strcmp(word[0], "history") == 0) - { //实现history n - if (pid == 0) - { - char cnum = word[1][0]; - int num = cnum - 48; - for (int i = whilecnt - 1; i > whilecnt - num - 1; i--) - { - printf("command %d:", i); - printf("%s", msg[i]); - } - exit(0); - } - } - - if (strcmp(word[0], "mytop") == 0) - { - if (pid == 0) - { - int cputimemode = 1; - getkinfo(); - print_memory(); - get_procs(); - if (prev_proc == NULL) - get_procs(); - print_procs(prev_proc, proc, cputimemode); - exit(0); - } - } - - switch (way) - { - case 0: - //pid为0说明是子进程,在子进程中执行输入的命令 - //输入的命令中不含> < | & - if (pid == 0) - { - if (!(checkCommand(word[0]))) - { - printf("%s : command not found\n", word[0]); - exit(0); - } - execvp(word[0], word); - exit(0); - } - break; - - case 1: - //输入的命令中含有输出重定向符 - if (pid == 0) - { - if (!(checkCommand(word[0]))) - { - printf("%s : command not found\n", word[0]); - exit(0); - } - fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644); - dup2(fd, 1); - execvp(word[0], word); - exit(0); - } - break; - - case 2: - //输入的命令中含有输入重定向< - if (pid == 0) - { - if (!(checkCommand(word[0]))) - { - printf("%s : command not found\n", word[0]); - exit(0); - } - fd = open(file, O_RDONLY); - dup2(fd, 0); - execvp(word[0], word); - exit(0); - } - break; - - case 3: - //输入的命令中含有管道符| - if (pid == 0) - { - int pid2; - int status2; - int fd[2]; - - if (pipe(fd) < 0) - { - printf("pipe error\n"); - exit(0); - } - - if ((pid2 = fork()) < 0) - { - printf("fork2 error\n"); - return; - } - else if (pid2 == 0) - { - if (!(checkCommand(word[0]))) - { - printf("%s : command not found\n", word[0]); - exit(0); - } - dup2(fd[1], 1); - execvp(word[0], word); - exit(0); - } - if (waitpid(pid2, &status2, 0) == -1) - { - printf("wait for child process error\n"); - } - if (!(checkCommand(wordnext[0]))) - { - printf("%s : command not found\n", wordnext[0]); - exit(0); - } - dup2(fd[0], 0); - execvp(wordnext[0], wordnext); - exit(0); - } - break; - case 4: //若命令中有&,表示后台执行,父进程直接返回,不等待子进程结束 - signal(SIGCHLD, SIG_IGN); - if (pid == 0) - { - //int pidbg; - //pidbg=fork(); - //if(pidbg==0){ - printf("[process id: %d]\n", pid); - int a = open("/dev/null", O_RDONLY); - dup2(a, 0); - dup2(a, 1); - if (!(checkCommand(word[0]))) - { - printf("%s : command not found\n", word[0]); - exit(0); - } - execvp(word[0], word); - exit(0); - //} - } - break; - - default: - break; - } - - //父进程等待子进程结束 - if (waitpid(pid, &status, 0) == -1) - { - printf("wait for child process error\n"); - } -} - -//查找命令中的可执行程序 -int checkCommand(char *command) -{ - DIR *dp; - struct dirent *dirp; - char *path[] = {"./", "/bin", "/usr/bin", NULL}; - - if (strncmp(command, "./", 2) == 0) - { - command = command + 2; - } - - //分别在当前目录,/bin和/usr/bin目录查找要执行的程序 - int i = 0; - while (path[i] != NULL) - { - if ((dp = opendir(path[i])) == NULL) - { - printf("can not open /bin \n"); - } - while ((dirp = readdir(dp)) != NULL) - { - if (strcmp(dirp->d_name, command) == 0) - { - closedir(dp); - return 1; - } - } - closedir(dp); - i++; - } - return 0; -} - -void getkinfo() -{ - FILE *fp; - - if ((fp = fopen("/proc/kinfo", "r")) == NULL) - { - fprintf(stderr, "opening " _PATH_PROC "kinfo failed\n"); - exit(1); - } - - if (fscanf(fp, "%u %u", &nr_procs, &nr_tasks) != 2) - { - fprintf(stderr, "reading from " _PATH_PROC "kinfo failed\n"); - exit(1); - } - - fclose(fp); - - nr_total = (int)(nr_procs + nr_tasks); -} - -int print_memory() -{ - FILE *fp; - unsigned int pagesize; - unsigned long total, free, largest, cached; - - if ((fp = fopen("/proc/meminfo", "r")) == NULL) - return 0; - - if (fscanf(fp, "%u %lu %lu %lu %lu", &pagesize, &total, &free, - &largest, &cached) != 5) - { - fclose(fp); - return 0; - } - - fclose(fp); - - printf("main memory: %ldK total, %ldK free, %ldK contig free, " - "%ldK cached\n", - (pagesize * total) / 1024, (pagesize * free) / 1024, - (pagesize * largest) / 1024, (pagesize * cached) / 1024); - - return 1; -} - -void get_procs() -{ - struct proc *p; - int i; - - p = prev_proc; - prev_proc = proc; - proc = p; - - if (proc == NULL) - { - proc = malloc(nr_total * sizeof(proc[0])); - - if (proc == NULL) - { - fprintf(stderr, "Out of memory!\n"); - exit(1); - } - } - - for (i = 0; i < nr_total; i++) - proc[i].p_flags = 0; - - parse_dir(); -} - -void parse_dir() -{ - DIR *p_dir; - struct dirent *p_ent; - pid_t pid; - char *end; //end是指向第一个不可转换的字符位置的指针 - - if ((p_dir = opendir("/proc")) == NULL) - { - perror("opendir on " _PATH_PROC); - exit(1); - } - - for (p_ent = readdir(p_dir); p_ent != NULL; p_ent = readdir(p_dir)) - { - pid = strtol(p_ent->d_name, &end, 10); //long strtol(char *str, char **endptr, int base)将串转换为长整数,base是基数,表示要转换的是几进制的数 - - if (!end[0] && pid != 0) - parse_file(pid); - } - - closedir(p_dir); -} - -void parse_file(pid_t pid) -{ - char path[PATH_MAX], name[256], type, state; - int version, endpt, effuid; //版本,端点,有效用户ID - unsigned long cycles_hi, cycles_lo; //高周期,低周期 - FILE *fp; - struct proc *p; - //int slot; //插槽? - int i; - //printf("parse_file\n"); - - sprintf(path, "/proc/%d/psinfo", pid); - - if ((fp = fopen(path, "r")) == NULL) - return; - - if (fscanf(fp, "%d", &version) != 1) - { - fclose(fp); - return; - } - - if (version != PSINFO_VERSION) - { //0 - fputs("procfs version mismatch!\n", stderr); - exit(1); - } - - if (fscanf(fp, " %c %d", &type, &endpt) != 2) - { - fclose(fp); - return; - } - - slot++; - //slot = SLOT_NR(endpt); - - if (slot < 0 || slot >= nr_total) - { - fprintf(stderr, "top: unreasonable endpoint number %d\n", endpt); - fclose(fp); - return; - } - - p = &proc[slot]; - - if (type == TYPE_TASK) - p->p_flags |= IS_TASK; - else if (type == TYPE_SYSTEM) - p->p_flags |= IS_SYSTEM; - - p->p_endpoint = endpt; - p->p_pid = pid; - - if (fscanf(fp, " %255s %c %d %d %lu %*u %lu %lu", - name, &state, &p->p_blocked, &p->p_priority, - &p->p_user_time, &cycles_hi, &cycles_lo) != 7) - { - - fclose(fp); - return; - } - - strncpy(p->p_name, name, sizeof(p->p_name) - 1); - p->p_name[sizeof(p->p_name) - 1] = 0; - - if (state != STATE_RUN) - p->p_flags |= BLOCKED; - p->p_cpucycles[0] = make64(cycles_lo, cycles_hi); - p->p_memory = 0L; - - if (!(p->p_flags & IS_TASK)) - { - int j; - if ((j = fscanf(fp, " %lu %*u %*u %*c %*d %*u %u %*u %d %*c %*d %*u", - &p->p_memory, &effuid, &p->p_nice)) != 3) - { - - fclose(fp); - return; - } - - p->p_effuid = effuid; - } - else - p->p_effuid = 0; - - for (i = 1; i < CPUTIMENAMES; i++) - { - if (fscanf(fp, " %lu %lu", - &cycles_hi, &cycles_lo) == 2) - { - p->p_cpucycles[i] = make64(cycles_lo, cycles_hi); - } - else - { - p->p_cpucycles[i] = 0; - } - } - - if ((p->p_flags & IS_TASK)) - { - if (fscanf(fp, " %lu", &p->p_memory) != 1) - { - p->p_memory = 0; - } - } - - p->p_flags |= USED; - - fclose(fp); -} - -u64_t cputicks(struct proc *p1, struct proc *p2, int timemode) -{ - int i; - u64_t t = 0; - for (i = 0; i < CPUTIMENAMES; i++) - { - if (!CPUTIME(timemode, i)) - continue; - if (p1->p_endpoint == p2->p_endpoint) - { - t = t + p2->p_cpucycles[i] - p1->p_cpucycles[i]; - } - else - { - t = t + p2->p_cpucycles[i]; - } - } - - return t; -} - -void print_procs(struct proc *proc1, struct proc *proc2, int cputimemode) -{ - int p, nprocs; - //u64_t idleticks = 0; - //u64_t kernelticks = 0; - u64_t systemticks = 0; - u64_t userticks = 0; - u64_t total_ticks = 0; - int blockedseen = 0; - static struct tp *tick_procs = NULL; //tp结构体的数组tick_procs,对所有的进程和任务(即上面读出来的nr_total)计算ticks - - if (tick_procs == NULL) - { - tick_procs = malloc(nr_total * sizeof(tick_procs[0])); - - if (tick_procs == NULL) - { - fprintf(stderr, "Out of memory!\n"); - exit(1); - } - } - - for (p = nprocs = 0; p < nr_total; p++) - { - u64_t uticks; - if (!(proc2[p].p_flags & USED)) - continue; - tick_procs[nprocs].p = proc2 + p; - tick_procs[nprocs].ticks = cputicks(&proc1[p], &proc2[p], cputimemode); - uticks = cputicks(&proc1[p], &proc2[p], 1); - total_ticks = total_ticks + uticks; - //printf("total_ticks:%llu\n",total_ticks); - /*if(p-NR_TASKS == IDLE) { - idleticks = uticks; - continue; - } - if(p-NR_TASKS == KERNEL) { - kernelticks = uticks; - } - */ - if (!(proc2[p].p_flags & IS_TASK)) - { - if (proc2[p].p_flags & IS_SYSTEM) - systemticks = systemticks + tick_procs[nprocs].ticks; - else - userticks = userticks + tick_procs[nprocs].ticks; - } - - nprocs++; - } - - if (total_ticks == 0) - return; - - printf("CPU states: %6.2f%% user, ", 100.0 * userticks / total_ticks); - printf("%6.2f%% system", 100.0 * systemticks / total_ticks); - printf("%6.2f%% in total\n", 100.0 * (systemticks + userticks) / total_ticks); - //printf("%6.2f%% kernel, ", 100.0 * kernelticks/ total_ticks); - //printf("%6.2f%% idle", 100.0 * idleticks / total_ticks); -}