ush

Tiny shell written in C
git clone git://git.finwo.net/app/ush
Log | Files | Refs | README

ush.c (1955B)


      1 #ifdef __cplusplus
      2 extern "C" {
      3 #endif
      4 
      5 #include <signal.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 #include <string.h>
      9 #include <sys/wait.h>
     10 #include <unistd.h>
     11 
     12 #include "linenoise.h"
     13 
     14 char **tokenize(char *input) {
     15   char **command = NULL;
     16   char *separator = " ";
     17   char *parsed;
     18   int index = 0;
     19 
     20   parsed = strtok(input, separator);
     21   while (parsed != NULL) {
     22     command = realloc(command, (index+2) * sizeof(char*));
     23     command[index] = parsed;
     24     index++;
     25     parsed = strtok(NULL, separator);
     26   }
     27 
     28   command[index] = NULL;
     29   return command;
     30 }
     31 
     32 int builtin_cd(char *path) {
     33   return chdir(path);
     34 }
     35 
     36 void sigint_handler(int signo) {
     37   printf("Caught SIGINT\n");
     38 }
     39 
     40 int main() {
     41   char *line;
     42   char *ps1 = "> ";
     43   char *histfile = "history.txt";
     44   char **command;
     45   pid_t child_pid;
     46   int stat_loc;
     47 
     48   linenoiseHistoryLoad(histfile); /* Load the history at startup */
     49 
     50   signal(SIGINT, sigint_handler);
     51   while((line = linenoise(ps1)) != NULL) {
     52 
     53     linenoiseHistoryLoad(histfile); /* Load the history at startup */
     54     linenoiseHistoryAdd(line); /* Add to the history. */
     55     linenoiseHistorySave(histfile); /* Save the history on disk. */
     56 
     57     command = tokenize(line);
     58 
     59     if (strcmp(command[0], "cd") == 0) {
     60       if (builtin_cd(command[1]) < 0) {
     61         perror(command[1]);
     62       }
     63       continue;
     64     }
     65 
     66     if (strcmp(command[0], "clear") == 0) {
     67       linenoiseClearScreen();
     68       continue;
     69     }
     70 
     71     if (strcmp(command[0], "exit") == 0) {
     72       if (command[1]) {
     73         exit(atoi(command[1]));
     74       } else {
     75         exit(0);
     76       }
     77     }
     78 
     79     child_pid = fork();
     80     if (child_pid < 0) {
     81       perror("Fork failed");
     82       exit(1);
     83     } else if (child_pid == 0) {
     84       if (execvp(command[0], command) < 0) {
     85         perror(command[0]);
     86         exit(1);
     87       }
     88     } else {
     89       waitpid(child_pid, &stat_loc, WUNTRACED);
     90     }
     91 
     92     free(line);
     93     free(command);
     94   }
     95 
     96   return 0;
     97 }
     98 
     99 #ifdef __cplusplus
    100 } // extern "C"
    101 #endif