Browse Source

feat(usp): add lazybox and pwd

greatbridf 2 years ago
parent
commit
1e8ced7113
3 changed files with 129 additions and 0 deletions
  1. 2 0
      CMakeLists.txt
  2. 2 0
      user-space-program/CMakeLists.txt
  3. 125 0
      user-space-program/lazybox.c

+ 2 - 0
CMakeLists.txt

@@ -128,6 +128,8 @@ add_custom_target(boot.img
     COMMAND mcopy -i boot.img@@1M ${CMAKE_BINARY_DIR}/user-space-program/init.out ::init.elf
     COMMAND mcopy -i boot.img@@1M ${CMAKE_BINARY_DIR}/user-space-program/sh.out ::sh.elf
     COMMAND mcopy -i boot.img@@1M ${CMAKE_BINARY_DIR}/user-space-program/priv-test.out ::priv.elf
+    COMMAND mcopy -i boot.img@@1M ${CMAKE_BINARY_DIR}/user-space-program/lazybox.out ::lazybox
+    COMMAND mcopy -i boot.img@@1M ${CMAKE_BINARY_DIR}/user-space-program/lazybox.out ::pwd
 )
 
 add_custom_command(OUTPUT run

+ 2 - 0
user-space-program/CMakeLists.txt

@@ -17,7 +17,9 @@ add_executable(stack-test.out stack-test.s)
 add_executable(init.out init.c)
 add_executable(sh.out sh.c)
 add_executable(priv-test.out priv-test.c)
+add_executable(lazybox.out lazybox.c)
 
 add_custom_target(user_space_programs
     DEPENDS hello-world.out interrupt-test.out stack-test.out init.out sh.out priv-test.out
+    DEPENDS lazybox.out
 )

+ 125 - 0
user-space-program/lazybox.c

@@ -0,0 +1,125 @@
+#include "unistd.h"
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+struct applet {
+    const char* name;
+    int (*func)(const char** args);
+};
+
+int puts(const char* str)
+{
+    size_t ret = write(STDOUT_FILENO, str, strlen(str));
+    ret += write(STDOUT_FILENO, "\n", 1);
+    return ret;
+}
+
+int printf(const char* fmt, ...)
+{
+    va_list args;
+    va_start(args, fmt);
+
+    char buf[128];
+    int n = vsnprintf(buf, sizeof(buf), fmt, args);
+    n = write(STDOUT_FILENO, buf, n);
+
+    va_end(args);
+    return n;
+}
+
+int lazybox_version(const char** _)
+{
+    (void)_;
+    printf("lazybox by greatbridf\n");
+    return 0;
+}
+
+int pwd(const char** _)
+{
+    (void)_;
+    char buf[256];
+    if (getcwd(buf, sizeof(buf)) == 0) {
+        printf("cannot get cwd\n");
+        return -1;
+    }
+    puts(buf);
+    return 0;
+}
+
+struct applet applets[] = {
+    {
+        "lazybox",
+        lazybox_version,
+    },
+    {
+        "pwd",
+        pwd,
+    }
+};
+
+static inline int tolower(int c)
+{
+    if (c >= 'A' && c <= 'Z')
+        return c - 'A' + 'a';
+    return c;
+}
+
+int strcmpi(const char* a, const char* b)
+{
+    int ret = 0;
+    while (*a && *b) {
+        if (tolower(*a) != tolower(*b)) {
+            ret = 1;
+            break;
+        }
+        ++a, ++b;
+    }
+    if ((*a && !*b) || (*b && !*a)) {
+        ret = 1;
+    }
+    return ret;
+}
+
+const char* find_file_name(const char* path)
+{
+    const char* last = path + strlen(path);
+    for (; last != path; --last) {
+        if (*last == '/')
+            break;
+    }
+    return last + 1;
+}
+
+int parse_applet(const char* name)
+{
+    for (size_t i = 0; i < (sizeof(applets) / sizeof(struct applet)); ++i) {
+        if (strcmpi(applets[i].name, name) == 0) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+int main(int argc, const char** argv)
+{
+    int offset = 0;
+    const char* name = find_file_name(argv[offset++]);
+    int type = -1;
+
+run:
+    type = parse_applet(name);
+    if (type == -1) {
+        printf("applet not found: %s\n", name);
+        return -1;
+    }
+
+    if (type == 0 && argc != 1) {
+        name = argv[offset++];
+        goto run;
+    }
+
+    return applets[type].func(argv + offset);
+}