BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / commit / d41a53cbc7d055b1c00cf0a339dbed6925f4f02c / vfs / procfs / file.c

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
diff --git a/vfs/procfs/file.c b/vfs/procfs/file.c
new file mode 100644
index 0000000..b292cf4
--- /dev/null
+++ b/vfs/procfs/file.c
@@ -0,0 +1,126 @@
+/*
+ * This file controls access to ProcFS Files.  It contains the functions called
+ * by the VFS for any operation on a File struct belonging to ProcFS.
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include "fs.h"
+#include "../vfs.h"
+#include "../cache.h"
+#include "../../mem/paging.h"
+#include "../../mem/frame.h"
+
+size_t procfs_read(File *file, char *buf, size_t size, off_t offset);
+size_t procfs_write(File *file, char *buf, size_t size, off_t offset);
+int procfs_readdir(File *file, DirEnt *dent, off_t index);
+int procfs_open(File *file);
+
+FileOps procfsFileOps = {
+	.read = procfs_read,
+	.write = procfs_write,
+	.readdir = procfs_readdir,
+	.open = procfs_open,
+};
+
+/* Read a file */
+size_t
+procfs_read(File *file, char *buf, size_t size, off_t offset)
+{
+	if (offset > file->inode->size)
+		return 0;
+	if (size + offset > file->inode->size)
+		size = file->inode->size - offset;
+
+	uint16_t min;
+	size_t count = 0;
+	Page *page;
+	page_t oldPage;
+	while (size) {
+		min = (size > 0x1000) ? 0x1000 : size;
+		page = page_find(file->inode, offset);
+		if (!page)
+			break;
+		acquire(&quickPageLock);
+		oldPage = quick_page(page->frame);
+		memcpy(buf + count, QUICK_PAGE, min);
+		quick_page(oldPage);
+		release(&quickPageLock);
+		size -= min;
+		count += min;
+	}
+	return count;
+}
+
+/* Write a file */
+size_t
+procfs_write(File *file, char *buf, size_t size, off_t offset)
+{
+	if (size + offset > file->inode->size)
+		file->inode->size = size + offset;
+
+	uint16_t min;
+	size_t count = 0;
+	Page *page;
+	page_t oldPage;
+	while (size) {
+		min = (size > 0x1000) ? 0x1000 : size;
+		page = page_find(file->inode, offset);
+		if (!page)
+			page = page_create(file->inode, alloc_frames(1),
+		                           offset);
+		acquire(&quickPageLock);
+		oldPage = quick_page(page->frame);
+		memcpy(QUICK_PAGE, buf + count, min);
+		quick_page(oldPage);
+		release(&quickPageLock);
+		size -= min;
+		count += min;
+	}
+	return count;
+}
+
+/* Read a directory entry */
+int
+procfs_readdir(File *file, DirEnt *dent, off_t index)
+{
+	DirEntry *de;
+
+	if (!index--) {
+		dent->ino = file->inode->ino;
+		dent->type = DT_DIR;
+		dent->namelen = 2;
+		strncpy(dent->name, ".", dent->namelen);
+		return 0;
+	}
+
+	for (de = file->inode->dirEntries; de && index; de = de->next, index--);
+	if (!de)
+		return -ENOENT;
+	dent->ino = de->inode->ino;
+	if (S_ISBLK(de->inode->mode))
+		dent->type = DT_BLK;
+	if (S_ISCHR(de->inode->mode))
+		dent->type = DT_CHR;
+	if (S_ISDIR(de->inode->mode))
+		dent->type = DT_DIR;
+	if (S_ISFIFO(de->inode->mode))
+		dent->type = DT_FIFO;
+	if (S_ISLNK(de->inode->mode))
+		dent->type = DT_LNK;
+	if (S_ISREG(de->inode->mode))
+		dent->type = DT_REG;
+	if (S_ISSOCK(de->inode->mode))
+		dent->type = DT_SOCK;
+	dent->namelen = strnlen(de->name, NAME_MAX) + 1;
+	strncpy(dent->name, de->name, NAME_MAX);
+	return 0;
+}
+
+/* Open a file */
+int
+procfs_open(File *file)
+{
+	return 0;
+}