optimize the menuconfig redrawing
[lunaix-os.git] / lunaix-os / usr / sh / sh.c
index 2c9bb8d1ec7fa2f5bb93198ab37e4280ff98ba35..33f0b030b1372b860afff9b8cda068d8ef59b5fe 100644 (file)
@@ -46,8 +46,8 @@ strltrim_safe(char* str)
     return strcpy(str, str + l);
 }
 
-void
-parse_cmdline(char* line, char** cmd, char** arg_part)
+int
+parse_cmdline(char* line, char** args)
 {
     strrtrim(line);
     line = strltrim_safe(line);
@@ -60,12 +60,15 @@ parse_cmdline(char* line, char** cmd, char** arg_part)
         }
         l++;
     }
-    *cmd = line;
-    if (c) {
-        *arg_part = strltrim_safe(line + l);
+
+    args[0] = line;
+    if (c && l) {
+        args[1] = strltrim_safe(line + l);
     } else {
-        *arg_part = NULL;
+        args[1] = NULL;
     }
+
+    return !!l;
 }
 
 void
@@ -108,23 +111,59 @@ sigint_handle(int signum)
 }
 
 void
-sh_exec(const char* name, const char** argv)
+sh_exec(const char** argv)
 {
+    static int prev_exit;
+    const char* envp[] = { 0 };
+    char* name = argv[0];
     if (!strcmp(name, "cd")) {
-        chdir(argv[0] ? argv[0] : ".");
+        chdir(argv[1] ? argv[1] : ".");
         sh_printerr();
         return;
     }
 
+    if (!strcmp(name, "?")) {
+        printf("%d\n", prev_exit);
+        return;
+    }
+
+    char buffer[1024];
+    strcpy(buffer, "/usr/bin/");
+    strcpy(&buffer[9], name);
+
     pid_t p;
+    int res;
     if (!(p = fork())) {
-        if (execve(name, argv, NULL)) {
+        if (execve(buffer, argv, envp)) {
             sh_printerr();
         }
         _exit(1);
     }
     setpgid(p, getpgid());
-    waitpid(p, NULL, 0);
+    waitpid(p, &res, 0);
+
+    prev_exit = WEXITSTATUS(res);
+}
+
+static char*
+sanity_filter(char* buf)
+{
+    int off = 0, i = 0;
+    char c;
+    do {
+        c = buf[i];
+        
+        if ((32 <= c && c <= 126) || !c) {
+            buf[i - off] = c;
+        }
+        else {
+            off++;
+        }
+
+        i++;
+    } while(c);
+
+    return buf;
 }
 
 void
@@ -139,7 +178,7 @@ sh_loop()
     // stdout (by default, unless user did smth) is the tty we are currently at
     ioctl(stdout, TIOCSPGRP, getpgid());
 
-    char* argv[] = {0, 0};
+    char* argv[] = {0, 0, 0};
 
     while (1) {
         getcwd(pwd, 512);
@@ -152,21 +191,20 @@ sh_loop()
         }
 
         buf[sz] = '\0';
+        sanity_filter(buf);
 
         // currently, this shell only support single argument
-        parse_cmdline(buf, &cmd, &argv[0]);
-
-        if (cmd[0] == 0) {
+        if (!parse_cmdline(buf, argv)) {
             printf("\n");
             goto cont;
         }
 
         // cmd=="exit"
-        if (*(unsigned int*)cmd == 0x74697865U) {
+        if (*(unsigned int*)argv[0] == 0x74697865U) {
             break;
         }
 
-        sh_exec(cmd, (const char**)&argv);
+        sh_exec((const char**)argv);
     cont:
         printf("\n");
     }