操作系统"UNIX外壳项目":简易命令行实现(执行命令+历史功能)
运行环境Ubuntu-Linux
代码如下 1 #include <unistd.h> 2 #include <string.h>
1 #include <unistd.h> 2 #include <string.h> 3 #include <stdio.h> 4 #include <wait.h> 5 #include <stdlib.h> 6 #define MAX_LINE 80 7 typedef struct hst{ 8 int number; 9 char *hst_cmd[MAX_LINE/2 + 1]; 10 int len; 11 struct hst *next; 12 13 }HstList; 14 void outHst(HstList *p); 15 void reLoad(int n, char *a[], HstList *p, int *num); 16 int main(void){ 17 char *args[MAX_LINE/2 + 1]; 18 int should_run = 1; 19 int waitFlag = 1;//flag of wait, 1 represent the father need to wait 20 int retype = 0;//flag of retype command 21 int hst_num = 1;//init the HstList 22 HstList *head, *node, *end, *latest; 23 head = (HstList*)malloc(sizeof(HstList)); 24 head->number = 0; 25 end = head; 26 latest = head; 27 end->next = NULL; 28 29 while(should_run){ 30 usleep(100000); 31 printf("myCommand(input 'exit' to exit)>>"); 32 fflush(stdout); 33 34 //read every input 35 int num = 0; 36 while(1){ 37 char *tmp = (char*)malloc(50*sizeof(char)); 38 if((scanf("%s", tmp)) == EOF || getchar() == '\n'){ 39 args[num] = tmp; 40 if(strcmp(args[num], "!!") == 0){ 41 if(latest->number == 0) printf("***you have not input any command recently!***:(\n"); 42 else{ 43 reLoad(end->number, args, head, &num); 44 break; 45 } 46 retype = 1; 47 break; 48 } 49 if(args[num][0] == '!' && args[num][1] != '!'){ 50 char *n = &args[num][1]; 51 int index = atoi(n); 52 if( index < head->number || index > end->number) printf("***the command not found!***:(\n"); 53 else{ 54 reLoad(index, args, head, &num); 55 break; 56 } 57 retype = 1; 58 break; 59 } 60 61 if(strcmp(args[num], "history") == 0){ 62 if(latest->number == 0) printf("***you have not input any command!***:(\n"); 63 else{ 64 while(latest != NULL){ 65 outHst(latest); 66 latest = latest->next; 67 } 68 latest = head->next;//when it print out the history, it should be reset 69 } 70 retype = 1; 71 break; 72 } 73 if(strcmp(args[num], "&") == 0){ 74 args[num] = NULL; 75 waitFlag = 0; 76 break; 77 } 78 if(strcmp(args[num], "exit") == 0){//set the flag of end 79 should_run = 0; 80 break; 81 } 82 args[++num] = NULL;//the end of args should be NULL 83 break; 84 }//for delay to close input 85 args[num] = tmp; 86 num++; 87 } 88 if(retype == 1){ 89 retype = 0; 90 continue; 91 } 92 if(should_run == 0) break;//stop run 93 94 //put the command into history 95 node = (HstList*)malloc(sizeof(HstList)); 96 end->next = node; 97 end = node; 98 end->next = NULL; 99 node->number = hst_num; 100 node->len = num; 101 hst_num++; 102 for(int i = 0;i <= node->number;i++) node->hst_cmd[i] = args[i]; 103 int i; 104 latest = head; 105 for(i = 0;i < 10;i++){ 106 if((end->number - i) > 1) continue; 107 else{ 108 latest = head->next; 109 break; 110 } 111 } 112 if(i == 10)//latest point to the latest 10 history command 113 while(latest->number != (end->number - 9)) 114 latest = latest->next; 115 116 //fork a process and insert a program into it 117 int pid; 118 pid = fork(); 119 if(pid < 0){ 120 printf("***process creation failed!***:(\n"); 121 } 122 else if(pid == 0){ 123 execvp(args[0], args); 124 printf("***command execution failed!***:(\n");//if the command execute successfully,there will not be returned value, or error occurred 125 exit(1); 126 } 127 else{ 128 if(waitFlag == 1){ 129 while(wait(NULL) != pid);//not continue untill recycle the latest child 130 } 131 waitFlag = 1; 132 printf("***parent program finished!***:)\n"); 133 } 134 135 } 136 return 0; 137 } 138 139 void outHst(HstList *p){ 140 printf("%d ", p->number); 141 for(int i = 0;i < p->len;i++) 142 printf("%s ", p->hst_cmd[i]); 143 printf("\n"); 144 } 145 void reLoad(int n, char *a[], HstList *p, int *num){ 146 while(p->number != n) p = p->next; 147 for(int i = 0;i <= p->len;i++){ 148 a[i] = p->hst_cmd[i]; 149 } 150 *num = p->len; 151 }