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

📄 xfile.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <auth.h>#include <fcall.h>#include "dat.h"#include "fns.h"static Xfile*	clean(Xfile*);#define	FIDMOD	127	/* prime */static Xdata*	xhead;static Xfile*	xfiles[FIDMOD];static Xfile*	freelist;Xdata*getxdata(char *name){	int fd;	Dir *dir;	Xdata *xf, *fxf;	int flag;	if(name[0] == 0)		name = deffile;	if(name == 0)		error(Enofile);	flag = (access(name, 6) == 0) ? ORDWR : OREAD;	fd = open(name, flag);	if(fd < 0)		error(Enonexist);	dir = nil;	if(waserror()){		close(fd);		free(dir);		nexterror();	}	if((dir = dirfstat(fd)) == nil)		error("I/O error");	if((dir->qid.type & ~QTTMP) != QTFILE)		error("attach name not a plain file");	for(fxf=0,xf=xhead; xf; xf=xf->next){		if(xf->name == 0){			if(fxf == 0)				fxf = xf;			continue;		}		if(xf->qid.path != dir->qid.path || xf->qid.vers != dir->qid.vers)			continue;		if(xf->type != dir->type || xf->fdev != dir->dev)			continue;		xf->ref++;		chat("incref=%d, \"%s\", dev=%d...", xf->ref, xf->name, xf->dev);		close(fd);		poperror();		free(dir);		return xf;	}	if(fxf==0){		fxf = ealloc(sizeof(Xfs));		fxf->next = xhead;		xhead = fxf;	}	chat("alloc \"%s\", dev=%d...", name, fd);	fxf->ref = 1;	fxf->name = strcpy(ealloc(strlen(name)+1), name);	fxf->qid = dir->qid;	fxf->type = dir->type;	fxf->fdev = dir->dev;	fxf->dev = fd;	free(dir);	poperror();	return fxf;}static voidputxdata(Xdata *d){	if(d->ref <= 0)		panic(0, "putxdata");	d->ref--;	chat("decref=%d, \"%s\", dev=%d...", d->ref, d->name, d->dev);	if(d->ref == 0){		chat("purgebuf...");		purgebuf(d);		close(d->dev);		free(d->name);		d->name = 0;	}}voidrefxfs(Xfs *xf, int delta){	xf->ref += delta;	if(xf->ref == 0){		if(xf->d)			putxdata(xf->d);		if(xf->ptr)			free(xf->ptr);		free(xf);	}}Xfile*xfile(int fid, int flag){	int k = fid%FIDMOD;	Xfile **hp=&xfiles[k], *f, *pf;	for(f=*hp,pf=0; f; pf=f,f=f->next)		if(f->fid == fid)			break;	if(f && pf){		pf->next = f->next;		f->next = *hp;		*hp = f;	}	switch(flag){	default:		panic(0, "xfile");	case Asis:		if(f == 0)			error("unassigned fid");		return f;	case Clean:		break;	case Clunk:		if(f){			*hp = f->next;			clean(f);			f->next = freelist;			freelist = f;		}		return 0;	}	if(f)		return clean(f);	if(f = freelist)	/* assign = */		freelist = f->next;	else		f = ealloc(sizeof(Xfile));	f->next = *hp;	*hp = f;	f->xf = 0;	f->fid = fid;	f->flags = 0;	f->qid = (Qid){0,0,0};	f->len = 0;	f->ptr = 0;	return f;}static Xfile *clean(Xfile *f){	if(f->xf){		refxfs(f->xf, -1);		f->xf = 0;	}	if(f->len){		free(f->ptr);		f->len = 0;	}	f->ptr = 0;	f->flags = 0;	f->qid = (Qid){0,0,0};	return f;}

⌨️ 快捷键说明

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