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

📄 nami.c

📁 unix v7是最后一个广泛发布的研究型UNIX版本
💻 C
字号:
#include "../h/param.h"#include "../h/systm.h"#include "../h/inode.h"#include "../h/mount.h"#include "../h/dir.h"#include "../h/user.h"#include "../h/buf.h"/* * Convert a pathname into a pointer to * an inode. Note that the inode is locked. * * func = function called to get next char of name *	&uchar if name is in user space *	&schar if name is in system space * flag = 0 if name is sought *	1 if name is to be created *	2 if name is to be deleted */struct inode *namei(func, flag)int (*func)();{	register struct inode *dp;	register c;	register char *cp;	struct buf *bp;	int i;	dev_t d;	off_t eo;	/*	 * If name starts with '/' start from	 * root; otherwise start from current dir.	 */	dp = u.u_cdir;	if((c=(*func)()) == '/')		if ((dp = u.u_rdir) == NULL)			dp = rootdir;	iget(dp->i_dev, dp->i_number);	while(c == '/')		c = (*func)();	if(c == '\0' && flag != 0)		u.u_error = ENOENT;cloop:	/*	 * Here dp contains pointer	 * to last component matched.	 */	if(u.u_error)		goto out;	if(c == '\0')		return(dp);	/*	 * If there is another component,	 * Gather up name into	 * users' dir buffer.	 */	cp = &u.u_dbuf[0];	while (c != '/' && c != '\0' && u.u_error == 0 ) {		if (mpxip!=NULL && c=='!')			break;		if(cp < &u.u_dbuf[DIRSIZ])			*cp++ = c;		c = (*func)();	}	while(cp < &u.u_dbuf[DIRSIZ])		*cp++ = '\0';	while(c == '/')		c = (*func)();	if (c == '!' && mpxip != NULL) {		iput(dp);		plock(mpxip);		mpxip->i_count++;		return(mpxip);	}seloop:	/*	 * dp must be a directory and	 * must have X permission.	 */	if((dp->i_mode&IFMT) != IFDIR)		u.u_error = ENOTDIR;	access(dp, IEXEC);	if(u.u_error)		goto out;	/*	 * set up to search a directory	 */	u.u_offset = 0;	u.u_segflg = 1;	eo = 0;	bp = NULL;eloop:	/*	 * If at the end of the directory,	 * the search failed. Report what	 * is appropriate as per flag.	 */	if(u.u_offset >= dp->i_size) {		if(bp != NULL)			brelse(bp);		if(flag==1 && c=='\0') {			if(access(dp, IWRITE))				goto out;			u.u_pdir = dp;			if(eo)				u.u_offset = eo-sizeof(struct direct);			else				dp->i_flag |= IUPD|ICHG;			return(NULL);		}		u.u_error = ENOENT;		goto out;	}	/*	 * If offset is on a block boundary,	 * read the next directory block.	 * Release previous if it exists.	 */	if((u.u_offset&BMASK) == 0) {		if(bp != NULL)			brelse(bp);		bp = bread(dp->i_dev,			bmap(dp, (daddr_t)(u.u_offset>>BSHIFT), B_READ));		if (bp->b_flags & B_ERROR) {			brelse(bp);			goto out;		}	}	/*	 * Note first empty directory slot	 * in eo for possible creat.	 * String compare the directory entry	 * and the current component.	 * If they do not match, go back to eloop.	 */	bcopy(bp->b_un.b_addr+(u.u_offset&BMASK), (caddr_t)&u.u_dent,		sizeof(struct direct));	u.u_offset += sizeof(struct direct);	if(u.u_dent.d_ino == 0) {		if(eo == 0)			eo = u.u_offset;		goto eloop;	}	for(i=0; i<DIRSIZ; i++)		if(u.u_dbuf[i] != u.u_dent.d_name[i])			goto eloop;	/*	 * Here a component matched in a directory.	 * If there is more pathname, go back to	 * cloop, otherwise return.	 */	if(bp != NULL)		brelse(bp);	if(flag==2 && c=='\0') {		if(access(dp, IWRITE))			goto out;		return(dp);	}	d = dp->i_dev;	if(u.u_dent.d_ino == ROOTINO)	if(dp->i_number == ROOTINO)	if(u.u_dent.d_name[1] == '.')		for(i=1; i<NMOUNT; i++)			if(mount[i].m_bufp != NULL)			if(mount[i].m_dev == d) {				iput(dp);				dp = mount[i].m_inodp;				dp->i_count++;				plock(dp);				goto seloop;			}	iput(dp);	dp = iget(d, u.u_dent.d_ino);	if(dp == NULL)		return(NULL);	goto cloop;out:	iput(dp);	return(NULL);}/* * Return the next character from the * kernel string pointed at by dirp. */schar(){	return(*u.u_dirp++ & 0377);}/* * Return the next character from the * user string pointed at by dirp. */uchar(){	register c;	c = fubyte(u.u_dirp++);	if(c == -1)		u.u_error = EFAULT;	return(c);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -