sh.c (1587B)
1 #include <libc.h> 2 3 #define msg_clear "\033[2J\033[H" 4 5 #define max_line 256 6 #define max_args 16 7 #define max_cwd 256 8 9 static char prompt[] = "; "; 10 11 void exec_cd(const char *path) { 12 if (path != NULL) { 13 chdir(path); 14 } 15 } 16 17 int main(void) { 18 char line[max_line]; 19 char *argv[max_args]; 20 21 while (1) { 22 memset(line, 0, sizeof(line)); 23 memset(argv, 0, sizeof(argv)); 24 25 write(stdout, prompt, 2); 26 27 ssize_t n = read(stdin, line, max_line - 1); 28 if (n <= 0) break; 29 30 line[n] = '\0'; 31 32 while (n > 0 && (line[n - 1] == '\n' || line[n - 1] == '\r')) { 33 line[--n] = '\0'; 34 } 35 36 if (n == 0 || strlen(line) == 0) continue; 37 38 int argc = 0; 39 char *token = strtok(line, " "); 40 while (token != NULL && argc < max_args - 1) { 41 argv[argc++] = token; 42 token = strtok(NULL, " "); 43 } 44 argv[argc] = NULL; 45 46 if (argc == 0 || argv[0] == NULL) continue; 47 48 if (strcmp(argv[0], "clear") == 0) { 49 write(stdout, msg_clear, strlen(msg_clear)); 50 continue; 51 } 52 53 if (strcmp(argv[0], "exit") == 0) { 54 break; 55 } 56 57 if (strcmp(argv[0], "cd") == 0) { 58 exec_cd(argv[1]); 59 continue; 60 } 61 62 int pid = fork(); 63 if (pid < 0) { 64 write(stderr, "sh: fork failed\n", 16); 65 continue; 66 } 67 68 if (pid == 0) { 69 /* child */ 70 execvp(argv[0], argv); 71 72 write(stderr, "sh: command not found: ", 23); 73 write(stderr, argv[0], strlen(argv[0])); 74 write(stderr, "\n", 1); 75 exit(127); 76 } else { 77 /* parent */ 78 int status = 0; 79 waitpid(pid, &status, 0); 80 } 81 } 82 return 0; 83 }