BarryServer : Git

All the code for all my projects
// BarryServer : Git / Nucleus / blob / master / vfs / devfs / file.c

// Related

Nucleus

Barry System headers (remove libc dependency) 18495cf (3 years, 2 months ago)
#include <stddef.h>
#include <stdint.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <nucleus/driver.h>
#include <nucleus/lib.h>
#include <nucleus/memory.h>
#include <nucleus/vfs.h>

size_t devfs_read(File *file, char *buf, size_t size, off_t offset);
size_t devfs_write(File *file, char *buf, size_t size, off_t offset);
int devfs_open(File *file);

FileOps devfsFileOps = {
	.read = devfs_read,
	.write = devfs_write,
	.open = devfs_open,
};

/* Read a file */
size_t
devfs_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;

	Page *page;
	char *data;
	size_t count = 0;
	uint16_t min, indent = offset % PAGE_SIZE;
	while (size) {
		min = (size > PAGE_SIZE) ? PAGE_SIZE : size;
		page = find_page(file->inode->pages, offset);
		if (!page)
			break;
		data = map_page(page);
		memcpy(buf + count, data + indent, min);
		size -= min;
		count += min;
		indent = 0;
	}
	return count;
}

/* Write a file */
size_t
devfs_write(File *file, char *buf, size_t size, off_t offset)
{
	if (size + offset > file->inode->size)
		file->inode->size = size + offset;

	Page *page;
	char *data;
	size_t count = 0;
	uint16_t min, indent = offset % PAGE_SIZE;
	while (size) {
		min = (size > PAGE_SIZE) ? PAGE_SIZE : size;
		page = find_page(file->inode->pages, offset);
		if (!page)
			page = create_page(file->inode->pages, alloc_frame(),
			                   offset);
		data = map_page(page);
		memcpy(data + indent, buf + count, min);
		size -= min;
		count += min;
		indent = 0;
	}
	return count;
}

/* Open a file */
int
devfs_open(File *file)
{
	if (S_ISREG(file->inode->mode) || S_ISDIR(file->inode->mode))
		return 0;

	/* Assign correct File Operations */
	file->ops = find_driver(MAJOR(file->inode->dev));
	if (!file->ops)
		return -ENXIO;
	if (!file->ops->open)
		return 0;
	return file->ops->open(file);
}