BarryServer : Git

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

// Related

Orion

Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)
diff --git a/vfs/devfs/file.c b/vfs/devfs/file.c
new file mode 100644
index 0000000..d2da4e4
--- /dev/null
+++ b/vfs/devfs/file.c
@@ -0,0 +1,84 @@
+/*
+ * This file controls access to DevFS Files.  It contains the functions called
+ * by the VFS for any operation on a File struct belonging to DevFS.
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include "fs.h"
+#include "../vfs.h"
+#include "../cache.h"
+#include "../../mem/paging.h"
+#include "../../mem/frame.h"
+#include "../../drivers/drivers.h"
+
+int devfs_open(File *file);
+int devfs_readdir(File *file, DirEnt *dent, off_t index);
+
+FileOps devfsFileOps = {
+	.open = devfs_open,
+	.readdir = devfs_readdir,
+};
+
+/* Open a device node */
+int
+devfs_open(File *file)
+{
+	if (S_ISREG(file->inode->mode) || S_ISDIR(file->inode->mode))
+		return 0;
+
+	/* Use major number to find relevant driver */
+	Driver *driver;
+	for (driver = drivers; driver; driver = driver->next)
+		if (driver->major == MAJOR(file->inode->dev))
+			break;
+	if (!driver)
+		return -ENXIO;
+
+	file->ops = driver->ops;
+	if (!file->ops)
+		return 0;
+	if (!file->ops->open)
+		return 0;
+	return file->ops->open(file);
+	/* For checking the minor internally */
+}
+
+/* Read a directory entry */
+int
+devfs_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;
+}