From a3e64ef2bf31dda9a94db011a96651de918ea968 Mon Sep 17 00:00:00 2001 From: sotech117 Date: Thu, 25 Apr 2024 02:58:09 +0000 Subject: old vfs fixes --- kernel/fs/open.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 99 insertions(+), 2 deletions(-) (limited to 'kernel/fs/open.c') diff --git a/kernel/fs/open.c b/kernel/fs/open.c index 8c9fee6..811a9c4 100644 --- a/kernel/fs/open.c +++ b/kernel/fs/open.c @@ -62,6 +62,103 @@ long get_empty_fd(int *fd) */ long do_open(const char *filename, int oflags) { - NOT_YET_IMPLEMENTED("VFS: do_open"); - return -1; + // NOT_YET_IMPLEMENTED("VFS: do_open"); + + // Check if oflags is valid + if ((oflags & O_WRONLY) && (oflags & O_RDWR)) + { + return -EINVAL; + } + + // Get an empty file descriptor + int fd = -1; + long ret = get_empty_fd(&fd); + if (ret < 0) + { + return ret; + } + + // Check if the file is a directory + if (filename[strlen(filename) - 1] == '/' && (oflags & O_WRONLY)) + { + return -EISDIR; + } + + // Open the file + vnode_t *res_vnode = NULL; + vnode_t *base = curproc->p_cwd; + ret = namev_open(base, filename, oflags, S_IFREG, 0, &res_vnode); + if (ret < 0) + { + if (res_vnode != NULL) + { + vput(&res_vnode); + } + return ret; + } + + // Check if the vnode is a directory + if (S_ISDIR(res_vnode->vn_mode) && ((oflags & O_WRONLY) || (oflags & O_RDWR))) + { + return -EISDIR; + } + + // Check if the vnode is a blockdev or chardev + if (S_ISCHR(res_vnode->vn_mode) && res_vnode->vn_dev.chardev == NULL) + { + vput(&res_vnode); + return -ENXIO; + } + if (S_ISBLK(res_vnode->vn_mode) && res_vnode->vn_dev.blockdev == NULL) + { + vput(&res_vnode); + return -ENXIO; + } + + // Convert oflags to file access flags + int fmode = 0; + if (oflags & O_RDONLY) + { + fmode |= FMODE_READ; + } + + if (oflags & O_WRONLY) + { + fmode |= FMODE_WRITE; + } + else + { + fmode |= FMODE_READ; + } + + if (oflags & O_RDWR) + { + fmode |= FMODE_READ | FMODE_WRITE; + } + + if (oflags & O_APPEND) + { + fmode |= FMODE_APPEND; + } + // Truncate the file if O_TRUNC is specified + if (oflags & O_TRUNC && S_ISREG(res_vnode->vn_mode)) + { + vlock(res_vnode); + res_vnode->vn_ops->truncate_file(res_vnode); + vunlock(res_vnode); + } + + // Create the file descriptor + file_t *file = fcreate(fd, res_vnode, fmode); + if (file == NULL) + { + vput(&res_vnode); + return -ENOMEM; + } + + + // Set the file descriptor + // curproc->p_files[fd] = file; + vput(&res_vnode); + return fd; } -- cgit v1.2.3-70-g09d2