BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / commit / f0dcd5469d9d1ca1dd816f97411f1209eb5a287a / vfs

// Related

Nucleus

Barry Files namespace f0dcd54 (3 years, 3 months ago)
diff --git a/vfs/files.c b/vfs/files.c
new file mode 100644
index 0000000..fffbc42
--- /dev/null
+++ b/vfs/files.c
@@ -0,0 +1,165 @@
+/*
+ * This file implements the Files object, which is the namespace for a task's
+ * files.  It stores all the opened files for a task.  It also implements many
+ * of the file-based system calls that need to use a file descriptor.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <nucleus/object.h>
+#include <nucleus/task.h>
+#include <nucleus/memory.h>
+#include <nucleus/vfs.h>
+
+/* Structure for a Files namespace */
+struct Files {
+	Object obj;
+	File *fd[NFILES];
+};
+
+static void files_delete(Object *);
+static void files_copy(Object *, Object *);
+
+/* Files object type */
+ObjectType filesType = {
+	.name = "FILES",
+	.size = sizeof(Files),
+	.delete = files_delete,
+	.copy = files_copy,
+};
+
+/* Destroy a Files object */
+static void
+files_delete(Object *obj)
+{
+	Files *files = (void *) obj;
+	int fd;
+	for (fd = 0; fd < NFILES; fd++)
+		if (files->fd[fd])
+			put(files->fd[fd]);
+}
+
+/* Copy a Files object */
+static void
+files_copy(Object *a, Object *b)
+{
+	Files *parent = (void *) a, *child = (void *) b;
+	File *file;
+	int fd;
+	for (fd = 0; fd < NFILES; fd++) {
+		file = parent->fd[fd];
+		if (!file)
+			continue;
+		child->fd[fd] = get(file);
+	}
+}
+
+/* Get the file described by fd */
+File *
+get_file_by_fd(int fd)
+{
+	if (fd < 0 || fd >= NFILES)
+		return NULL;
+	return current->files->fd[fd];
+}
+
+/* Allocate file descriptor */
+int
+allocate_fd(void)
+{
+	int fd;
+	for (fd = 0; fd < NFILES; fd++)
+		if (!current->files->fd[fd])
+			break;
+	if (fd == NFILES)
+		fd = -1;
+	return fd;
+}
+
+/* Install a file in a file descriptor */
+void
+install_fd(int fd, File *file)
+{
+	current->files->fd[fd] = file;
+}
+
+/* Close a file */
+int
+close(int fd)
+{
+	if (!get_file_by_fd(fd))
+		return -EBADF;
+	put(current->files->fd[fd]);
+	current->files->fd[fd] = NULL;
+	return 0;
+}
+
+/* Read a file */
+int
+read(int fd, void *buf, size_t count)
+{
+	if (!verify_access(buf, count, PROT_WRITE))
+		return -EFAULT;
+
+	File *file = get_file_by_fd(fd);
+	if (!file)
+		return -EBADF;
+
+	if (file->inode && S_ISDIR(file->inode->mode))
+		return -EISDIR;
+
+	lock(file);
+	int sz = file_read(file, buf, count);
+	unlock(file);
+	return sz;
+}
+
+/* Write a file */
+int
+write(int fd, void *buf, size_t count)
+{
+	if (!verify_access(buf, count, PROT_READ))
+		return -EFAULT;
+
+	File *file = get_file_by_fd(fd);
+	if (!file)
+		return -EBADF;
+
+	if (file->inode && S_ISDIR(file->inode->mode))
+		return -EISDIR;
+
+	lock(file);
+	int sz = file_write(file, buf, count);
+	unlock(file);
+	return sz;
+}
+
+/* Move a file's position */
+off_t
+lseek(int fd, off_t offset, int whence)
+{
+	File *file = get_file_by_fd(fd);
+	if (!file)
+		return -EBADF;
+
+	lock(file);
+	switch (whence) {
+	case SEEK_SET:
+		file->pos = offset;
+		break;
+	case SEEK_CUR:
+		file->pos += offset;
+		break;
+	case SEEK_END:
+		file->pos = file->inode->size + offset;
+		break;
+	default:
+		unlock(file);
+		return -EINVAL;
+	}
+	unlock(file);
+	return file->pos;
+}
diff --git a/vfs/namespace.c b/vfs/namespace.c
index 1cf7515..638453f 100644
--- a/vfs/namespace.c
+++ b/vfs/namespace.c
@@ -1,6 +1,6 @@
 /*
  * This file implements the File System object, which is the namespace for a
- * task's files.  It tracks a task's root and current working directory.
+ * task's file system.  It tracks a task's root and current working directory.
  */
 
 #include <nucleus/object.h>
@@ -8,12 +8,15 @@
 #include "namespace.h"
 
 static void file_system_new(Object *);
+static void file_system_delete(Object *);
 static void file_system_copy(Object *, Object *);
 
 /* File System object type */
 ObjectType fsType = {
+	.name = "FILE SYSTEM",
 	.size = sizeof(FileSystem),
 	.new = file_system_new,
+	.delete = file_system_delete,
 	.copy = file_system_copy,
 };
 
@@ -25,14 +28,22 @@ file_system_new(Object *obj)
 	fs->cwdPath = create_list(&dirEntryType);
 }
 
+/* Destory a File System object */
+static void
+file_system_delete(Object *obj)
+{
+	FileSystem *fs = (void *) obj;
+	put(fs->cwd);
+	destroy_list(fs->cwdPath);
+	put(fs->root);
+}
+
 /* Copy a File System object */
 static void
 file_system_copy(Object *a, Object *b)
 {
 	FileSystem *parent = (void *) a, *child = (void *) b;
 	child->cwd = get(parent->cwd);
-	/* init cwd custody chain */
 	child->cwdPath = copy_list(parent->cwdPath);
-	/* copy cwd custody chain */
 	child->root = get(parent->root);
 }