BarryServer : Git

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

// Related

Nucleus

Barry Files namespace f0dcd54 (3 years, 3 months ago)
diff --git a/include/nucleus/task.h b/include/nucleus/task.h
index 397fae7..cfc0c99 100644
--- a/include/nucleus/task.h
+++ b/include/nucleus/task.h
@@ -30,7 +30,9 @@ enum State {
 /* Structure for a Task */
 struct Task {
 	Object obj;
-	pid_t tid;
+	pid_t tid, tgid;
+	uid_t uid, euid, suid;
+	gid_t gid, egid, sgid;
 	enum Priority priority;
 	enum State state;
 
@@ -39,6 +41,7 @@ struct Task {
 
 	/* Namespaces */
 	FileSystem *fs;
+	Files *files;
 };
 
 extern ObjectType taskType;
@@ -46,6 +49,13 @@ extern ObjectType taskType;
 extern Task *currentTask[];
 #define current currentTask[CPUID]
 
+/* Check if super-user */
+static inline int
+super_user(void)
+{
+	return (current->euid == 0);
+}
+
 void init_tasking(void);
 void schedule(void);
 pid_t clone(int flags);
diff --git a/include/nucleus/vfs.h b/include/nucleus/vfs.h
index ebd5396..59162c0 100644
--- a/include/nucleus/vfs.h
+++ b/include/nucleus/vfs.h
@@ -6,10 +6,13 @@
 #include <nucleus/object.h>
 #include <nucleus/memory.h>
 
+#define NFILES 32
 #define NAME_MAX 255
+#define PATH_MAX 1024
 
 typedef struct FSType FSType;
 typedef struct FileSystem FileSystem;
+typedef struct Files Files;
 typedef struct SuperBlock SuperBlock;
 typedef struct SuperOps SuperOps;
 typedef struct Inode Inode;
@@ -48,12 +51,16 @@ struct Inode {
 	InodeOps *ops;
 	FileOps *fileOps;
 	SuperBlock *super;
-	union {
-		ObjectList *dirEntries;
-		ObjectList *pages;
-	};
+	ObjectList *dirEntries;
+	ObjectList *pages;
 };
 struct InodeOps {
+	int (*create)(Inode *, DirEntry *, mode_t);
+	Inode *(*lookup)(Inode *, const char *);
+	int (*mkdir)(Inode *, DirEntry *, mode_t);
+	int (*rmdir)(Inode *, DirEntry *);
+	int (*mknod)(Inode *, DirEntry *, mode_t, dev_t);
+	int (*rename)(Inode *, DirEntry *, Inode *, DirEntry *);
 };
 
 /* Structure for a Directory Entry */
@@ -75,10 +82,15 @@ struct File {
 	ObjectList *path;
 };
 struct FileOps {
+	size_t (*read)(File *, char *, size_t, off_t);
+	size_t (*write)(File *, char *, size_t, off_t);
+	int (*open)(File *);
 };
 
 extern ObjectType fstypeType;
 extern ObjectType fsType;
+extern ObjectType filesType;
+extern ObjectType superBlockType;
 extern ObjectType inodeType;
 extern ObjectType dirEntryType;
 extern ObjectType fileType;
@@ -87,6 +99,23 @@ void init_vfs(void);
 void register_fstype(const char *name,	mount_callback_t mount);
 int mount(const char *src, const char *target, const char *type,
           unsigned long flags, void *data);
+
+/* Super Block functions */
+Inode *super_alloc_inode(SuperBlock *sb);
+Inode *super_find_inode(SuperBlock *sb, ino_t ino);
+/* Inode functions */
+int permission(Inode *inode, int mask);
+int inode_create(Inode *inode, DirEntry *entry, mode_t mode);
+DirEntry *inode_lookup(Inode *inode, const char *name);
+/* Directory Entry functions */
 DirEntry *find_direntry(ObjectList *list, const char *name);
+/* File functions */
+int file_open(File *file);
+size_t file_read(File *file, char *buf, size_t count);
+size_t file_write(File *file, char *buf, size_t count);
+/* Files namespace functions */
+File *get_file_by_fd(int fd);
+int allocate_fd(void);
+void install_fd(int fd, File *file);
 
 #endif
diff --git a/task/clone.c b/task/clone.c
index 86cf440..4dd15e7 100644
--- a/task/clone.c
+++ b/task/clone.c
@@ -25,6 +25,12 @@ clone(int flags)
 	else
 		child->fs = copy(parent->fs);
 
+	/* Clone parent's files namespace */
+	if (flags & CLONE_FILES)
+		child->files = get(parent->files);
+	else
+		child->files = copy(parent->files);
+
 	/* After this, anything on the stack is desynchronised */
 	child->pageDir = clone_dir();
 
diff --git a/task/task.c b/task/task.c
index 87c0c79..0e53b77 100644
--- a/task/task.c
+++ b/task/task.c
@@ -10,6 +10,7 @@
 #include <nucleus/task.h>
 #include <nucleus/memory.h>
 #include <nucleus/object.h>
+#include <nucleus/vfs.h>
 
 void init_scheduler(void);
 void timer_handler(struct InterruptFrame *frame);
@@ -18,12 +19,14 @@ static void task_new(Object *);
 
 /* Task object type */
 ObjectType taskType = {
+	.name = "TASK",
 	.size = sizeof(Task),
 	.new = task_new,
 };
 
 Task *currentTask[MAX_CPUS];
 pid_t nextTid = 1;
+extern char stackTop[];
 
 /* Create a new Task */
 static void
@@ -31,12 +34,11 @@ task_new(Object *obj)
 {
 	Task *task = (void *) obj;
 	task->tid = nextTid++;
+	task->tgid = task->tid;
 	task->priority = NORMAL;
 	task->state = READY;
 }
 
-extern char stackTop[];
-
 /* Move the stack */
 static void
 move_stack(uintptr_t top, size_t size)
@@ -80,6 +82,9 @@ init_tasking(void)
 	/* File System namespace */
 	current->fs = new(&fsType);
 
+	/* Files namespace */
+	current->files = new(&filesType);
+
 	init_scheduler();
 	register_interrupt(0, timer_handler);
 
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);
 }