/* * 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 #include #include #include #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->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; }