aboutsummaryrefslogtreecommitdiff
path: root/kernel/fs/open.c
diff options
context:
space:
mode:
authorsotech117 <michael_foiani@brown.edu>2024-04-25 02:58:09 +0000
committersotech117 <michael_foiani@brown.edu>2024-04-25 02:58:09 +0000
commita3e64ef2bf31dda9a94db011a96651de918ea968 (patch)
tree67c1d65ccc219c223d261dfd4cb024201220dcff /kernel/fs/open.c
parentd970aa2698d831645986effded059eb344a77486 (diff)
old vfs fixes
Diffstat (limited to 'kernel/fs/open.c')
-rw-r--r--kernel/fs/open.c101
1 files changed, 99 insertions, 2 deletions
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;
}