福州正规网站建设公司推荐搜索指数分析
自主实现shell
done,故意写成=,表示先赋值,再判断,分割之后,strtok会返回NULL,刚好让gArgv最后一个元素是NULL,并且while判断结束
Makefile
1 myshell:myshell.c 2 gcc -o $@ $^3 .PHONY:clean4 clean:5 rm -f myshell
myshell.c
1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/wait.h>5 #include<stdlib.h>6 #include<string.h>7 #include<errno.h>8 9 #define SIZE 51210 #define ZERO '\0'11 #define SEP " "12 #define NUM 3213 #define SkipPath(p) do{p += (strlen(p) - 1);while(*p != '/') p--;}while(0)14 15 char cwd[SIZE*2];16 char *gArgv[NUM];17 int lastcode = 0;18 void Die()19 {20 exit(1);21 }22 23 const char *GetHome()24 {25 const char *home = getenv("HOME"); 26 if(home == NULL) return "/";27 return home;28 }29 const char *Getusername()30 {31 const char *name = getenv("USER");32 if(name == NULL) return "None";33 return name;34 }35 const char *Gethostname()36 { 37 const char *hostname = getenv("HOSTNAME");38 if(hostname == NULL) return "None";39 return hostname;40 }41 const char *Getcwd()42 {43 const char *cwd = getenv("PWD");44 if(cwd == NULL) return "None";45 return cwd;46 }47 48 void makecommandline()49 {50 char line[SIZE];51 const char *username = Getusername();52 const char *hostname = Gethostname();53 const char *cwd = Getcwd();54 55 SkipPath(cwd);56 snprintf(line, sizeof(line), "[%s@%s %s] love:", username, hostname, strlen(cwd) == 1 ? "/" : cwd + 1);57 printf("%s", line);58 fflush(stdout);59 }60 61 int Getusercommand(char command[], size_t n)62 {63 char *s = fgets(command, n, stdin);64 if(s == NULL) return -1;65 66 command[strlen(command) - 1] = ZERO;67 return strlen(command);68 }69 70 void SplitCommand(char command[], size_t n)71 {72 (void)n;73 gArgv[0] = strtok(command, SEP);74 int index = 1;75 while((gArgv[index++] = strtok(NULL, SEP))); 76 }77 void ExecuteCommand()78 {79 pid_t id = fork();80 if(id < 0) Die();81 else if(id == 0)82 {83 //child84 execvp(gArgv[0], gArgv);85 exit(errno);86 }87 else 88 {89 //father90 int status = 0;91 pid_t rid = waitpid(id, &status, 0);92 if(rid > 0)93 {94 lastcode = WEXITSTATUS(status);95 if(lastcode != 0) printf("%s:%s:%d\n", gArgv[0], strerror(lastcode), lastcode);96 }97 }98 }99
100 void Cd()
101 {
102 const char *path = gArgv[1];
103 if(path == NULL) path =GetHome();
104
105 chdir(path);
106 //刷新环境变量
107 char temp[SIZE*2];
108 getcwd(temp, sizeof(temp));
109 snprintf(cwd, sizeof(cwd), "PWD=%s", temp);
110 putenv(cwd);
111 }
112 int CheckBuildin()
113 {
114 int yes = 0;
115 const char *enter_cmd = gArgv[0];
116 if(strcmp(enter_cmd, "cd") == 0)
117 {
118 yes = 1;
119 Cd();
120 }
121 else if(strcmp(enter_cmd, "echo") == 0 && strcmp(gArgv[1], "$?") == 0)
122 {
123 yes = 1;
124 printf("%d\n", lastcode);
125 lastcode = 0;
126 }
127
128 return yes;
129 }
130 int main()
131 {
132 int quit = 0;
133 while(!quit)
134 {
135 makecommandline();
136
137 char usercommand[SIZE];
138 int n = Getusercommand(usercommand, sizeof(usercommand));
139 if(n <= 0) return 1;
140
141 SplitCommand(usercommand, sizeof(usercommand));
142
143 n = CheckBuildin();
144 if(n) continue;
145 ExecuteCommand();
146 }
147
148 return 0;
149 }