Orion
Barry Keyboard/Mouse drivers + POSIX names for structs 1628fcf (3 years, 1 month 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;
}