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);
}