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);
}