coreutils

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

sh.c (1323B)


      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 execcd(const char *path) {
     12   chdir(path);
     13 }
     14 
     15 int main(void) {
     16   char line[max_line];
     17   char *argv[max_args];
     18 
     19   while (1) {
     20     write(stdout, prompt, 2);
     21 
     22     ssize_t n = read(stdin, line, max_line - 1);
     23     if (n <= 0) continue;
     24 
     25     line[n] = '\0';
     26     if (line[n - 1] == '\n') line[n - 1] = '\0'; 
     27 
     28     if (strlen(line) == 0) continue;
     29 
     30     if (strcmp(line, "clear") == 0) {
     31       write(stdout, msg_clear, strlen(msg_clear));
     32       continue;
     33     }
     34 
     35     if (strcmp(line, "exit") == 0) {
     36       break;
     37     }
     38 
     39     int argc = 0;
     40     char *token = strtok(line, " ");
     41     while (token != NULL && argc < max_args - 1) {
     42       argv[argc++] = token;
     43       token = strtok(NULL, " ");
     44     }
     45     argv[argc] = NULL;
     46 
     47     if (argc == 0) continue;
     48 
     49     if (strcmp(line, "cd") == 0) {
     50       execcd(argv[1]);
     51       continue;
     52     }
     53 
     54     int pid = fork();
     55     if (pid == 0) {
     56       /* child */
     57       execvp(argv[0], argv);
     58 
     59       write(stderr, "sh: command not found: ", 23);
     60       write(stderr, argv[0], strlen(argv[0]));
     61       write(stderr, "\n", 1);
     62       exit(127);
     63     } else if (pid > 0) {
     64       /* parent */
     65       int status;
     66       waitpid(pid, &status, 0);
     67     }
     68   }
     69   return 0;
     70 }