coreutils

custom mini coreutils
git clone git://git.evenfri.xyz/coreutils.git
Log | Files | Refs | README

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 }