From b3b42765712afed5a35c9be5c832f4a06bd85e7a Mon Sep 17 00:00:00 2001 From: Minep Date: Tue, 23 Aug 2022 12:55:38 +0100 Subject: [PATCH] feat: a pseudo shell environment for basic interacting and testing purpose chore: fixes and clean up --- lunaix-os/includes/klibc/string.h | 2 +- lunaix-os/includes/lunaix/device.h | 1 + lunaix-os/kernel/demos/simple_sh.c | 105 +++++++++++++++++++++++++++++ lunaix-os/kernel/device/devfs.c | 4 +- lunaix-os/kernel/device/device.c | 5 +- lunaix-os/kernel/fs/path_walk.c | 5 +- lunaix-os/kernel/fs/ramfs/ramfs.c | 11 ++- lunaix-os/kernel/fs/vfs.c | 2 + lunaix-os/kernel/proc0.c | 8 ++- lunaix-os/libs/klibc/string/trim.c | 10 ++- 10 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 lunaix-os/kernel/demos/simple_sh.c diff --git a/lunaix-os/includes/klibc/string.h b/lunaix-os/includes/klibc/string.h index fcb0df5..dc4e6e1 100644 --- a/lunaix-os/includes/klibc/string.h +++ b/lunaix-os/includes/klibc/string.h @@ -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 */ diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index beb8066..8171600 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -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 index 0000000..036550a --- /dev/null +++ b/lunaix-os/kernel/demos/simple_sh.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include + +#include +#include + +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 diff --git a/lunaix-os/kernel/device/devfs.c b/lunaix-os/kernel/device/devfs.c index 0448924..ac674b4 100644 --- a/lunaix-os/kernel/device/devfs.c +++ b/lunaix-os/kernel/device/devfs.c @@ -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; } diff --git a/lunaix-os/kernel/device/device.c b/lunaix-os/kernel/device/device.c index 1512e6f..282f44d 100644 --- a/lunaix-os/kernel/device/device.c +++ b/lunaix-os/kernel/device/device.c @@ -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; } diff --git a/lunaix-os/kernel/fs/path_walk.c b/lunaix-os/kernel/fs/path_walk.c index ea5b1c5..c7d4ecb 100644 --- a/lunaix-os/kernel/fs/path_walk.c +++ b/lunaix-os/kernel/fs/path_walk.c @@ -33,7 +33,10 @@ __vfs_walk(struct v_dnode* start, panick("vfs: no root"); } } - i++; + + if (path[0] == VFS_PATH_DELIM) { + i++; + } } assert(start); diff --git a/lunaix-os/kernel/fs/ramfs/ramfs.c b/lunaix-os/kernel/fs/ramfs/ramfs.c index 3dcbd59..11ec846 100644 --- a/lunaix-os/kernel/fs/ramfs/ramfs.c +++ b/lunaix-os/kernel/fs/ramfs/ramfs.c @@ -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 diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index 7fbc226..0c2f42d 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -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; } diff --git a/lunaix-os/kernel/proc0.c b/lunaix-os/kernel/proc0.c index f926ffd..cd76818 100644 --- a/lunaix-os/kernel/proc0.c +++ b/lunaix-os/kernel/proc0.c @@ -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 diff --git a/lunaix-os/libs/klibc/string/trim.c b/lunaix-os/libs/klibc/string/trim.c index 82f29bd..fb907fa 100644 --- a/lunaix-os/libs/klibc/string/trim.c +++ b/lunaix-os/libs/klibc/string/trim.c @@ -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 -- 2.27.0