#include #include #include #include #include #include "dat.h" #include "fns.h" #include "linux.h" enum { Mnull, Mzero, Mfull, Mrandom, Murandom, Mmax, }; typedef struct Miscfile Miscfile; struct Miscfile { Ufile; int m; }; static int path2m(char *path) { int m; m = -1; if(strcmp(path, "/dev/null")==0){ m = Mnull; } else if(strcmp(path, "/dev/zero")==0){ m = Mzero; } else if(strcmp(path, "/dev/full")==0){ m = Mfull; } else if(strcmp(path, "/dev/random")==0){ m = Mrandom; } else if(strcmp(path, "/dev/urandom")==0){ m = Murandom; } return m; } static int openmisc(char *path, int mode, int, Ufile **pf) { Miscfile *f; int m; if((m = path2m(path)) < 0) return -ENOENT; f = kmallocz(sizeof(*f), 1); f->ref = 1; f->mode = mode; f->path = kstrdup(path); f->fd = -1; f->dev = MISCDEV; f->m = m; *pf = f; return 0; } static int closemisc(Ufile *) { return 0; } static int readmisc(Ufile *f, void *buf, int len, vlong) { switch(((Miscfile*)f)->m){ case Mnull: return 0; case Mzero: memset(buf, 0, len); return len; case Mfull: return -EIO; case Mrandom: genrandom(buf, len); return len; case Murandom: prng(buf, len); return len; default: return -EIO; } } static int writemisc(Ufile *f, void *, int len, vlong) { switch(((Miscfile*)f)->m){ case Mnull: case Mzero: case Mrandom: case Murandom: return len; case Mfull: return -ENOSPC; default: return -EIO; } } static int statmisc(char *path, int, Ustat *s) { if(path2m(path) < 0) return -ENOENT; s->mode = 0666 | S_IFCHR; s->uid = current->uid; s->gid = current->gid; s->size = 0; s->ino = hashpath(path); s->dev = 0; s->rdev = 0; s->atime = s->mtime = s->ctime = boottime/1000000000LL; return 0; } static int fstatmisc(Ufile *f, Ustat *s) { return fsstat(f->path, 0, s); }; static Udev miscdev = { .open = openmisc, .read = readmisc, .write = writemisc, .close = closemisc, .stat = statmisc, .fstat = fstatmisc, }; void miscdevinit(void) { devtab[MISCDEV] = &miscdev; fsmount(&miscdev, "/dev/null"); fsmount(&miscdev, "/dev/zero"); fsmount(&miscdev, "/dev/full"); fsmount(&miscdev, "/dev/random"); fsmount(&miscdev, "/dev/urandom"); srand(truerand()); }