Orion
Barry Importing existing Orion kernel d41a53c (2 years, 4 months ago)diff --git a/vfs/devfs/file.c b/vfs/devfs/file.c new file mode 100644 index 0000000..d2da4e4 --- /dev/null +++ b/vfs/devfs/file.c @@ -0,0 +1,84 @@ +/* + * 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->ino = file->inode->ino; + dent->type = DT_DIR; + dent->namelen = 2; + strncpy(dent->name, ".", dent->namelen); + return 0; + } + + for (de = file->inode->dirEntries; de && index; de = de->next, index--); + if (!de) + return -ENOENT; + dent->ino = de->inode->ino; + if (S_ISBLK(de->inode->mode)) + dent->type = DT_BLK; + if (S_ISCHR(de->inode->mode)) + dent->type = DT_CHR; + if (S_ISDIR(de->inode->mode)) + dent->type = DT_DIR; + if (S_ISFIFO(de->inode->mode)) + dent->type = DT_FIFO; + if (S_ISLNK(de->inode->mode)) + dent->type = DT_LNK; + if (S_ISREG(de->inode->mode)) + dent->type = DT_REG; + if (S_ISSOCK(de->inode->mode)) + dent->type = DT_SOCK; + dent->namelen = strnlen(de->name, NAME_MAX) + 1; + strncpy(dent->name, de->name, NAME_MAX); + return 0; +}