BarryServer : Git

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

// Related

Orion

Barry Keyboard/Mouse drivers + POSIX names for structs 1628fcf (2 years, 4 months ago)
/*
 * 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->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;
}

/* Open a file */
int
procfs_open(File *file)
{
	return 0;
}