📄 namei.cc
字号:
#include <lib/root.h>#include <lib/gcc.h>#include <lib/limits.h>#include <lib/string.h>#include <kern/sched.h>#include "inode.h"static int advancei(inode_t ** cwd, char * name){ inode_t * sub; int e; if (e = (*cwd)->lookup(name, &sub)) return e; (*cwd)->lose(); (*cwd) = sub; return 0;}int namei(int flags, const char * pathname, inode_t ** inode, char * basename){ int e; scanstr_t scan(pathname, "/"); inode_t * cwd; if (flags & I2SPLIT) { assert(basename); basename[0] = 0; } *inode = NULL; if ((scan.nlefttok() == 0) && (flags & I2SPLIT)) return ENOENT; cwd = (*pathname == '/') ? curr->fs->root : curr->fs->cwd; allege(cwd); cwd->hold(); for (; scan.more(); scan.next()) { if (!cwd->isdir()) { cwd->lose(); return ENOTDIR; } if ((scan.nlefttok() == 1) && (flags & I2SPLIT)) { *inode = cwd; strncpy(basename, scan.curtok(), NAMEMAX+1); return 0; } if (e = advancei(&cwd, scan.curtok())) { cwd->lose(); return e; } } *inode = cwd; return 0;}asmlinkage int syslink(const char * oldname, const char * newname){ int e; inode_t * oldi, * newdir; char newbasename[NAMEMAX+1]; if (lowfreepage()) return ENOMEM; if ((e = verrpath(oldname)) || (e = verrpath(newname))) return e; if (e = namei(ISTAT, oldname, &oldi)) return e; if (e = namei(ILINK, newname, &newdir, newbasename)) { oldi->lose(); return e; } e = newdir->hardlink(newbasename, oldi); oldi->lose(); newdir->lose(); return e;}asmlinkage int sysunlink(const char * pathname){ int e; inode_t * dir; char basename[NAMEMAX+1]; if (lowfreepage()) return ENOMEM; if (e = verrpath(pathname)) return e; if (e = namei(IUNLINK, pathname, &dir, basename)) return e; e = dir->unlink(basename); dir->lose(); return e;}int domkfifo(const char * pathname, mode_t mode){ int e; inode_t * dir; char basename[NAMEMAX+1]; if (e = namei(IMKNOD, pathname, &dir, basename)) return e; e = dir->mkfifo(basename, mode); dir->lose(); return e;}asmlinkage int sysmknod(const char * pathname, int mode, int dev){ int e; inode_t * dir; char basename[NAMEMAX+1]; if (lowfreepage()) return ENOMEM; if (e = verrpath(pathname)) return e; if (e = namei(IMKNOD, pathname, &dir, basename)) return e; e = dir->mknod(basename, mode, dev); dir->lose(); return e;}asmlinkage int sysmkdir(const char * pathname, int mode){ int e; inode_t * dir; char basename[NAMEMAX+1]; if (e = verrpath(pathname)) return e; if (e = namei(IMKDIR, pathname, &dir, basename)) return e; e = dir->mkdir(basename, mode); dir->lose(); return e;}asmlinkage int sysrmdir(const char * pathname){ int e; inode_t * dir; char basename[NAMEMAX+1]; if (lowfreepage()) return ENOMEM; if (e = verrpath(pathname)) return e; if (e = namei(IRMDIR, pathname, &dir, basename)) return e; e = dir->rmdir(basename); dir->lose(); return e;}asmlinkage int sysrename(const char * oldname, const char * newname){ int e; inode_t * olddir, * newdir; char oldbasename[NAMEMAX+1], newbasename[NAMEMAX+1]; if ((e = verrpath(oldname)) || (e = verrpath(newname))) return e; if (e = namei(IUNLINK, oldname, &olddir, oldbasename)) return e; if (e = namei(IMKNOD, newname, &newdir, newbasename)) { olddir->lose(); return e; } /* olddir may equal newdir */ e = olddir->rename(oldbasename, newdir, newbasename); olddir->lose(); newdir->lose(); return e;}static void getstat(inode_t * i, stat_t * s) { s->dev = i->dev; s->ino = i->ino; s->mode = i->mode; s->nlink = i->nlink; s->uid = i->uid; s->gid = i->gid; s->rdev = i->getrdev(); s->size = i->size; s->blksize = MINIXBSIZE; s->blocks = i->bnodiv(i->size); s->atime = i->atime; s->mtime = i->mtime; s->ctime = i->ctime;}asmlinkage int sysstat(const char * pathname, stat_t * stat){ int e; inode_t * leaf; if (e = verrpath(pathname)) return e; if (e = verw(stat, sizeof(stat_t))) return e; if (e = namei(ISTAT, pathname, &leaf)) return e; getstat(leaf, stat); leaf->lose(); return 0;}asmlinkage int syslstat(const char * pathname, stat_t * stat){ return sysstat(pathname, stat);}#include "regfd.h"asmlinkage int sysfstat(int fd, stat_t * stat){ int e; fdes_t * fdes; if (e = verw(stat, sizeof(stat_t))) return e; if (e = fdtofdes(fd, &fdes)) return e;#warning "to be continue..." /* some hack for gawk */ if (fdes->type != REGFD) { stat->blksize = 1024; return 0; } getstat(((regfd_t*)fdes)->inode, stat); return 0;}asmlinkage int syschdir(const char * pathname){ int e; inode_t * inode; if (e = verrpath(pathname)) return e; if (e = namei(ISTAT, pathname, &inode)) return e; if (!inode->isdir()) { inode->lose(); return ENOTDIR; } if (inode->deny(IX)) { inode->lose(); return EACCES; } curr->fs->cwd->lose(); curr->fs->cwd = inode; return 0;}asmlinkage int sysfchdir(int fd){ fdes_t *fdes; int e = fdtofdes(fd, &fdes); if (e < 0) return e; if (fdes->type != REGFD) return ENOTDIR; regfd_t *regfd = (regfd_t*)fdes; if (!regfd->inode->isdir()) return ENOTDIR; inode_t * inode = regfd->inode; if (inode->deny(IX)) return EACCES; inode->hold(); curr->fs->cwd->lose(); curr->fs->cwd = inode; return 0;}asmlinkage int syschmod(const char * pathname, mode_t mode){ int e; inode_t * inode; if (e = verrpath(pathname)) return e; if (e = namei(ISTAT, pathname, &inode)) return e; if ((curr->euid != inode->uid) && !suser()) { inode->lose(); return EPERM; } inode->mode = (mode & 07777) | (inode->mode & ~07777); inode->lose2(); return 0;}asmlinkage int syschown(const char * pathname, uid_t uid, gid_t gid){ int e; inode_t * inode; if (e = verrpath(pathname)) return e; if (e = namei(ISTAT, pathname, &inode)) return e; if (!suser()) { inode->lose(); return EPERM; } inode->uid = uid; inode->gid = gid; inode->lose2(); return 0;}asmlinkage int syschroot(const char * pathname){ int e; inode_t * inode; if (e = verrpath(pathname)) return e; if (e = namei(ISTAT, pathname, &inode)) return e; if (!inode->isdir()) { inode->lose(); return ENOTDIR; } if (!suser()) { inode->lose(); return EPERM; } curr->fs->root->lose(); curr->fs->root = inode; return (0);}struct utimbuf_t { time_t atime; time_t mtime;};/* If times==NULL, set access and modification to current time, * must be owner or have write permission. * Else, update from *times, must be owner or super user. */asmlinkage int sysutime(char * pathname, utimbuf_t * t){ int e; inode_t * inode; if (e = verrpath(pathname)) return e; if (e = namei(ISTAT, pathname, &inode)) return e; if (e = inode->deny(IW)) { inode->lose(); return EPERM; } if (t) { if (e = verr(t, sizeof(*t))) { inode->lose(); return e; } inode->atime = t->atime; inode->mtime = t->mtime; } else { inode->atime = inode->mtime = now(); } inode->lose2(); return 0;}/* * XXX we should use the real ids for checking _all_ components of the * path. Now we only use them for the final component of the path. */asmlinkage int sysaccess(const char * pathname,int mode){ int e; inode_t * inode; if (e = verrpath(pathname)) return e; if (mode != (mode & 7)) return EINVAL; if (e = namei(ISTAT, pathname, &inode)) return e; e = inode->deny(mode); inode->lose(); return e;}asmlinkage int sysumask(int mask){ int old = curr->fs->umask; curr->fs->umask = mask & 0777; return old;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -