feat: a pseudo shell environment for basic interacting and testing purpose
authorMinep <zelong56@gmail.com>
Tue, 23 Aug 2022 11:55:38 +0000 (12:55 +0100)
committerMinep <zelong56@gmail.com>
Tue, 23 Aug 2022 11:55:38 +0000 (12:55 +0100)
chore: fixes and clean up

lunaix-os/includes/klibc/string.h
lunaix-os/includes/lunaix/device.h
lunaix-os/kernel/demos/simple_sh.c [new file with mode: 0644]
lunaix-os/kernel/device/devfs.c
lunaix-os/kernel/device/device.c
lunaix-os/kernel/fs/path_walk.c
lunaix-os/kernel/fs/ramfs/ramfs.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/proc0.c
lunaix-os/libs/klibc/string/trim.c

index fcb0df5286167ebf9a43586efe30da7fa13f6b43..dc4e6e1f1bcb605a81adba289dc33b7ebe15e34c 100644 (file)
@@ -36,7 +36,7 @@ streq(const char* a, const char* b);
 void
 strrtrim(char* str);
 
-void*
+char*
 strltrim_safe(char* str);
 
 #endif /* __LUNAIX_STRING_H */
index beb8066739d5b8c046da927c0299c1f6831633a6..81716002bbc166be8881a590f7078f3bf1c9bbb3 100644 (file)
@@ -18,6 +18,7 @@ typedef unsigned int dev_t;
 struct device
 {
     struct llist_header siblings;
+    struct llist_header children;
     struct device* parent;
     struct hstr name;
     dev_t dev_id;
diff --git a/lunaix-os/kernel/demos/simple_sh.c b/lunaix-os/kernel/demos/simple_sh.c
new file mode 100644 (file)
index 0000000..036550a
--- /dev/null
@@ -0,0 +1,105 @@
+#include <lunaix/fctrl.h>
+#include <lunaix/foptions.h>
+#include <lunaix/lunistd.h>
+#include <lunaix/proc.h>
+#include <lunaix/status.h>
+
+#include <klibc/string.h>
+#include <ulibc/stdio.h>
+
+char pwd[512];
+
+/*
+    Simple shell - (actually this is not even a shell)
+    It just to make the testing more easy.
+*/
+
+void
+parse_cmdline(char* line, char** cmd, char** arg_part)
+{
+    strrtrim(line);
+    line = strltrim_safe(line);
+    int l = 0;
+    char c = 0;
+    while ((c = line[l])) {
+        if (c == ' ') {
+            line[l++] = 0;
+            break;
+        }
+        l++;
+    }
+    *cmd = line;
+    *arg_part = strltrim_safe(line + l);
+}
+
+void
+sh_printerr()
+{
+    int errno = geterrno();
+    switch (errno) {
+        case ENOTDIR:
+            printf("Error: Not a directory\n");
+            break;
+        case ENOENT:
+            printf("Error: No such file or directory\n");
+            break;
+        case EINVAL:
+            printf("Error: Invalid parameter or operation\n");
+            break;
+        case ENOTSUP:
+            printf("Error: Not supported\n");
+            break;
+        case EROFS:
+            printf("Error: File system is read only\n");
+            break;
+        case ENOMEM:
+            printf("Error: Out of memory\n");
+            break;
+        default:
+            printf("Error: Fail to open (%d)\n", errno);
+            break;
+    }
+}
+
+void
+sh_main()
+{
+    char buf[512];
+    char *cmd, *argpart;
+
+    while (1) {
+        getcwd(pwd, 512);
+        printf("%s> ", pwd);
+        size_t sz = read(stdin, buf, 512);
+        if (sz < 0) {
+            printf("fail to read user input (%d)\n", geterrno());
+            return;
+        }
+        buf[sz - 1] = '\0';
+        parse_cmdline(buf, &cmd, &argpart);
+        if (streq(cmd, "cd")) {
+            if (chdir(argpart) < 0) {
+                sh_printerr();
+            }
+        } else if (streq(cmd, "ls")) {
+            int fd = open(argpart, 0);
+            if (fd < 0) {
+                sh_printerr();
+            } else {
+                struct dirent ent = { .d_offset = 0 };
+                int status;
+                while ((status = readdir(fd, &ent)) == 1) {
+                    printf(" %s\n", ent.d_name);
+                }
+
+                if (status < 0)
+                    sh_printerr();
+
+                close(fd);
+            }
+        } else {
+            printf("unknow command");
+        }
+        printf("\n");
+    }
+}
\ No newline at end of file
index 0448924083fa603413b73a415b3fa669b2aca610..ac674b4ac77ebb4e5f4b5cee6f1b4794c2c92ad0 100644 (file)
@@ -84,7 +84,9 @@ devfs_dirlookup(struct v_inode* this, struct v_dnode* dnode)
 int
 devfs_readdir(struct v_file* file, struct dir_context* dctx)
 {
-    struct device* dev = device_getbyoffset(file->inode->data, dctx->index);
+    struct device* holder = (struct device*)(file->inode->data);
+    struct device* dev =
+      device_getbyoffset(holder ? &holder->children : NULL, dctx->index);
     if (!dev) {
         return 0;
     }
index 1512e6f1cb56bf2fc8f402a6243413524140a60d..282f44d27603a49670e7de65a4633440bdd0939e 100644 (file)
@@ -19,6 +19,9 @@ device_add(struct device* parent,
 
     if (parent) {
         assert((parent->dev_type & DEV_MSKIF) == DEV_IFCAT);
+        llist_append(&parent->children, &dev->siblings);
+    } else {
+        llist_append(&root_list, &dev->siblings);
     }
 
     size_t strlen =
@@ -31,7 +34,7 @@ device_add(struct device* parent,
     dev->dev_type = type;
 
     hstr_rehash(&dev->name, HSTR_FULL_HASH);
-    llist_append(&root_list, &dev->siblings);
+    llist_init_head(&dev->children);
 
     return dev;
 }
index ea5b1c59b4aa5da7e54d59d467d8875025ac632c..c7d4ecb1e23f4a0914332928941515f8db8242b5 100644 (file)
@@ -33,7 +33,10 @@ __vfs_walk(struct v_dnode* start,
                 panick("vfs: no root");
             }
         }
-        i++;
+
+        if (path[0] == VFS_PATH_DELIM) {
+            i++;
+        }
     }
 
     assert(start);
index 3dcbd5908882243fcdd49ee19afa3a1c9d585d1c..11ec8463aa4f8db47097bc8eb3e936e6d45aa7c4 100644 (file)
@@ -42,6 +42,7 @@
 volatile static inode_t ino = 0;
 
 extern const struct v_inode_ops ramfs_inode_ops;
+extern const struct v_file_ops ramfs_file_ops;
 
 int
 ramfs_readdir(struct v_file* file, struct dir_context* dctx)
@@ -88,7 +89,7 @@ ramfs_inode_init(struct v_superblock* vsb, struct v_inode* inode)
 {
     inode->id = ino++;
     inode->ops = &ramfs_inode_ops;
-    inode->default_fops = &default_file_ops;
+    inode->default_fops = &ramfs_file_ops;
 }
 
 int
@@ -127,4 +128,10 @@ const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir,
                                                default_inode_dirlookup,
                                              .create = ramfs_create,
                                              .open = default_inode_open,
-                                             .rename = default_inode_rename };
\ No newline at end of file
+                                             .rename = default_inode_rename };
+
+const struct v_file_ops ramfs_file_ops = { .readdir = ramfs_readdir,
+                                           .close = default_file_close,
+                                           .read = default_file_read,
+                                           .write = default_file_write,
+                                           .seek = default_file_seek };
\ No newline at end of file
index 7fbc2268008b61a4777b3420cb817f777e37fbec..0c2f42d8459a0f440f488dfb1dd8dc14c63294b3 100644 (file)
@@ -487,6 +487,8 @@ __vfs_try_locate_file(const char* path,
     char name_str[VFS_NAME_MAXLEN];
     struct hstr name = HSTR(name_str, 0);
     int errno;
+
+    name_str[0] = 0;
     if ((errno = vfs_walk_proc(path, fdir, &name, VFS_WALK_PARENT))) {
         return errno;
     }
index f926ffda7df7926c6a063aabdaab1f0fa7b36898..cd7681854e86dfefca8455928256a7aefd9c5614 100644 (file)
@@ -50,7 +50,8 @@ __do_reserved_memory(int unlock);
 // #define DEMO_SIGNAL
 // #define DEMO_READDIR
 // #define DEMO_IOTEST
-#define DEMO_INPUT_TEST
+// #define DEMO_INPUT_TEST
+#define DEMO_SIMPLE_SH
 
 extern void
 _pconsole_main();
@@ -70,6 +71,9 @@ _iotest_main();
 extern void
 input_test();
 
+extern void
+sh_main();
+
 void __USER__
 __proc0_usr()
 {
@@ -95,6 +99,8 @@ __proc0_usr()
         _iotest_main();
 #elif defined DEMO_INPUT_TEST
         input_test();
+#elif defined DEMO_SIMPLE_SH
+        sh_main();
 #else
         _lxinit_main();
 #endif
index 82f29bd717ead44bcaddd5dd4c9fc6927a211a4c..fb907fa5673585413ac99c421b971d336414e585 100644 (file)
@@ -18,12 +18,16 @@ strrtrim(char* str)
     str[l + 1] = '\0';
 }
 
-void*
+char*
 strltrim_safe(char* str)
 {
     size_t l = 0;
     char c = 0;
-    while ((c = str[l++]) && WS_CHAR(c))
-        ;
+    while ((c = str[l]) && WS_CHAR(c)) {
+        l++;
+    }
+
+    if (!l)
+        return str;
     return strcpy(str, str + l);
 }
\ No newline at end of file