BarryServer : Git

All the code for all my projects
// BarryServer : Git / Orion / blob / 1628fcfdfdf2978ed9ccac96ee7d13bb3dc43a01 / vfs / devfs / file.c

// Related

Orion

Barry Keyboard/Mouse drivers + POSIX names for structs 1628fcf (2 years, 4 months ago)
/*
 * 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->d_ino = file->inode->ino;
		dent->d_type = DT_DIR;
		dent->d_namelen = 2;
		strncpy(dent->d_name, ".", dent->d_namelen);
		return 0;
	}

	for (de = file->inode->dirEntries; de && index; de = de->next, index--);
	if (!de)
		return -ENOENT;
	dent->d_ino = de->inode->ino;
	if (S_ISBLK(de->inode->mode))
		dent->d_type = DT_BLK;
	if (S_ISCHR(de->inode->mode))
		dent->d_type = DT_CHR;
	if (S_ISDIR(de->inode->mode))
		dent->d_type = DT_DIR;
	if (S_ISFIFO(de->inode->mode))
		dent->d_type = DT_FIFO;
	if (S_ISLNK(de->inode->mode))
		dent->d_type = DT_LNK;
	if (S_ISREG(de->inode->mode))
		dent->d_type = DT_REG;
	if (S_ISSOCK(de->inode->mode))
		dent->d_type = DT_SOCK;
	dent->d_namelen = strnlen(de->name, NAME_MAX) + 1;
	strncpy(dent->d_name, de->name, NAME_MAX);
	return 0;
}