diff --git a/bin/shell/shell.c b/bin/shell/shell.c index eeb0219..4c4d9bc 100644 --- a/bin/shell/shell.c +++ b/bin/shell/shell.c @@ -5,6 +5,7 @@ // Castor Only #include +#include #define SHELL_MAX_ARGS 5 #define SHELL_MAX_LINE 256 @@ -16,9 +17,9 @@ main(int argc, const char *argv[]) { char buf[256]; - fputs("Shell\n", stdout); + fputs("System Shell\n", stdout); while (1) { - fputs("> ", stdout); + fputs("Shell> ", stdout); fgets(buf, sizeof(buf), stdin); DispatchCommand(buf); @@ -50,6 +51,36 @@ Cmd_Echo(int argc, const char *argv[]) void Cmd_List(int argc, const char *argv[]) { + int fd; + int status; + uintptr_t offset = 0; + + if (argc != 2) { + fputs("Requires an argument\n", stdout); + return; + } + + fd = SystemOpen(argv[1], 0); + if (fd < 0) { + fputs("Cannot open directory\n", stdout); + return; + } + + while (1) { + struct dirent de; + + status = SystemReadDir(fd, (char *)&de, sizeof(de), &offset); + if (status == 0) { + break; + } + if (status < 0) { + fputs("Error\n", stdout); + break; + } + + fputs(de.d_name, stdout); + fputs("\n", stdout); + } } void @@ -122,6 +153,8 @@ DispatchCommand(char *buf) Cmd_Echo(argc, (const char **)argv); } else if (strcmp(argv[0], "exit") == 0) { exit(0); + } else if (strcmp(argv[0], "ls") == 0) { + Cmd_List(argc, (const char **)argv); } else if (strcmp(argv[0], "#") == 0) { // Ignore comments } else if (buf[0] != '\0') { diff --git a/sys/fs/o2fs/o2fs.c b/sys/fs/o2fs/o2fs.c index 7f29d60..4786290 100644 --- a/sys/fs/o2fs/o2fs.c +++ b/sys/fs/o2fs/o2fs.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "o2fs.h" @@ -344,6 +346,41 @@ O2FS_Write(VNode *fn, void *buf, uint64_t off, uint64_t len) int O2FS_ReadDir(VNode *fn, void *buf, uint64_t len, uint64_t *off) { - return 0; + int count = 0; + int status; + DiskCacheEntry *fileEntry = (DiskCacheEntry *)fn->fsptr; + BNode *fileBN = fileEntry->buffer; + BDirEntry dirEntry; + struct dirent de; + + while (len >= sizeof(de)) { + if (*off == fileBN->size) + return count; + if (*off > fileBN->size) + return -EINVAL; + + // XXX: Check offset + + status = O2FS_Read(fn, &dirEntry, *off, sizeof(dirEntry)); + if (status != sizeof(dirEntry)) { + kprintf("Unexpected error reading directory."); + return status; + } + + // XXX: Validation and fill in all fields + strcpy(de.d_name, dirEntry.name); + + status = CopyOut(&de, (uintptr_t)buf, sizeof(de)); + if (status != 0) + return status; + + *off += sizeof(dirEntry); + buf += sizeof(de); + len -= sizeof(de); + + count++; + } + + return count; } diff --git a/sys/kern/syscall.c b/sys/kern/syscall.c index 3629247..6b875fe 100644 --- a/sys/kern/syscall.c +++ b/sys/kern/syscall.c @@ -254,7 +254,7 @@ Syscall_Stat(uint64_t user_path, uint64_t user_stat) uint64_t Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off) { - int status; + int status, rstatus; Thread *cur = Thread_Current(); Handle *handle = Handle_Lookup(cur, fd); uint64_t offset; @@ -268,15 +268,16 @@ Syscall_ReadDir(uint64_t fd, char *user_buf, size_t len, uintptr_t user_off) if (handle->type != HANDLE_TYPE_FILE) return -ENOTDIR; - status = VFS_ReadDir(handle->vnode, user_buf, len, &offset); - if (status != 0) - return status; + + rstatus = VFS_ReadDir(handle->vnode, user_buf, len, &offset); + if (rstatus < 0) + return rstatus; status = CopyOut(&offset, user_off, sizeof(offset)); if (status != 0) return status; - return 0; + return rstatus; } uint64_t diff --git a/sys/kern/vfs.c b/sys/kern/vfs.c index f04eee9..5347603 100644 --- a/sys/kern/vfs.c +++ b/sys/kern/vfs.c @@ -67,7 +67,11 @@ VFS_Lookup(const char *path) end++; len = (size_t)(end - start); - if (len == 0 || len > 256) { + if (len == 0) { + // Handle root and trailing slash + return curNode; + } + if (len > 256) { // Release return NULL; } diff --git a/sys/kern/vfsuio.c b/sys/kern/vfsuio.c index 23d75e3..c297b1d 100644 --- a/sys/kern/vfsuio.c +++ b/sys/kern/vfsuio.c @@ -63,6 +63,11 @@ VFSUIO_Open(const char *path, Handle **handle) } VNode *vn = VFS_Lookup(path); + if (!vn) { + Handle_Free(hdl); + return -ENOENT; + } + status = VFS_Open(vn); if (status != 0) { // XXX: Release VNode