⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 namei.cc

📁 南京航空航天大学开发的一个类Unix和Linux的操作系统,好不好看看就知道了,
💻 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 + -