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

📄 vfile.c

📁 举世闻名的joe记事本源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	Software virtual memory system *	Copyright *		(C) 1992 Joseph H. Allen * *	This file is part of JOE (Joe's Own Editor) */#include "types.h"static VFILE vfiles = { {&vfiles, &vfiles} };	/* Known vfiles */static VPAGE *freepages = NULL;	/* Linked list of free pages */static VPAGE *htab[HTSIZE];	/* Hash table of page headers */static long curvalloc = 0;	/* Amount of memory in use */static long maxvalloc = ILIMIT;	/* Maximum allowed */unsigned char *vbase;			/* Data first entry in vheader refers to */VPAGE **vheaders = NULL;	/* Array of header addresses */static int vheadsz = 0;		/* No. entries allocated to vheaders */void vflsh(void){	VPAGE *vp;	VPAGE *vlowest;	off_t addr;	off_t last;	VFILE *vfile;	int x;	for (vfile = vfiles.link.next; vfile != &vfiles; vfile = vfile->link.next) {		last = -1;	      loop:		addr = MAXOFF;		vlowest = NULL;		for (x = 0; x != HTSIZE; x++)			for (vp = htab[x]; vp; vp = vp->next)				if (vp->addr < addr && vp->addr > last && vp->vfile == vfile && (vp->addr >= vfile->size || (vp->dirty && !vp->count))) {					addr = vp->addr;					vlowest = vp;				}		if (vlowest) {			if (!vfile->name)				vfile->name = mktmp(NULL);			if (!vfile->fd)				vfile->fd = open((char *)(vfile->name), O_RDWR);			lseek(vfile->fd, addr, 0);			if (addr + PGSIZE > vsize(vfile)) {				joe_write(vfile->fd, vlowest->data, (int) (vsize(vfile) - addr));				vfile->size = vsize(vfile);			} else {				joe_write(vfile->fd, vlowest->data, PGSIZE);				if (addr + PGSIZE > vfile->size)					vfile->size = addr + PGSIZE;			}			vlowest->dirty = 0;			last = addr;			goto loop;		}	}}void vflshf(VFILE *vfile){	VPAGE *vp;	VPAGE *vlowest;	off_t addr;	int x;      loop:	addr = MAXOFF;	vlowest = NULL;	for (x = 0; x != HTSIZE; x++)		for (vp = htab[x]; vp; vp = vp->next)			if (vp->addr < addr && vp->dirty && vp->vfile == vfile && !vp->count) {				addr = vp->addr;				vlowest = vp;			}	if (vlowest) {		if (!vfile->name)			vfile->name = mktmp(NULL);		if (!vfile->fd) {			vfile->fd = open((char *)(vfile->name), O_RDWR);		}		lseek(vfile->fd, addr, 0);		if (addr + PGSIZE > vsize(vfile)) {			joe_write(vfile->fd, vlowest->data, (int) (vsize(vfile) - addr));			vfile->size = vsize(vfile);		} else {			joe_write(vfile->fd, vlowest->data, PGSIZE);			if (addr + PGSIZE > vfile->size)				vfile->size = addr + PGSIZE;		}		vlowest->dirty = 0;		goto loop;	}}static unsigned char *mema(int align, int size){	unsigned char *z = (unsigned char *) joe_malloc(align + size);	return z + align - physical(z) % align;}unsigned char *vlock(VFILE *vfile, off_t addr){	VPAGE *vp, *pp;	int x, y;	off_t ofst = (addr & (PGSIZE - 1));	addr -= ofst;	for (vp = htab[((addr >> LPGSIZE) + (unsigned long) vfile) & (HTSIZE - 1)]; vp; vp = vp->next)		if (vp->vfile == vfile && vp->addr == addr) {			++vp->count;			return vp->data + ofst;		}	if (freepages) {		vp = freepages;		freepages = vp->next;		goto gotit;	}	if (curvalloc + PGSIZE <= maxvalloc) {		vp = (VPAGE *) joe_malloc(sizeof(VPAGE) * INC);		if (vp) {			vp->data = (unsigned char *) mema(PGSIZE, PGSIZE * INC);			if (vp->data) {				int q;				curvalloc += PGSIZE * INC;				if (!vheaders) {					vheaders = (VPAGE **) joe_malloc((vheadsz = INC) * sizeof(VPAGE *));					vbase = vp->data;				} else if (physical(vp->data) < physical(vbase)) {					VPAGE **t = vheaders;					int amnt = (physical(vbase) - physical(vp->data)) >> LPGSIZE;					vheaders = (VPAGE **) joe_malloc((amnt + vheadsz) * sizeof(VPAGE *));					mmove(vheaders + amnt, t, vheadsz * sizeof(VPAGE *));					vheadsz += amnt;					vbase = vp->data;					joe_free(t);				} else if (((physical(vp->data + PGSIZE * INC) - physical(vbase)) >> LPGSIZE) > vheadsz) {					vheaders = (VPAGE **)					    joe_realloc(vheaders, (vheadsz = (((physical(vp->data + PGSIZE * INC) - physical(vbase)) >> LPGSIZE))) * sizeof(VPAGE *));				}				for (q = 1; q != INC; ++q) {					vp[q].next = freepages;					freepages = vp + q;					vp[q].data = vp->data + q * PGSIZE;					vheader(vp->data + q * PGSIZE) = vp + q;				}				vheader(vp->data) = vp;				goto gotit;			}			joe_free(vp);			vp = NULL;		}	}	for (y = HTSIZE, x = (random() & (HTSIZE - 1)); y; x = ((x + 1) & (HTSIZE - 1)), --y)		for (pp = (VPAGE *) (htab + x), vp = pp->next; vp; pp = vp, vp = vp->next)			if (!vp->count && !vp->dirty) {				pp->next = vp->next;				goto gotit;			}	vflsh();	for (y = HTSIZE, x = (random() & (HTSIZE - 1)); y; x = ((x + 1) & (HTSIZE - 1)), --y)		for (pp = (VPAGE *) (htab + x), vp = pp->next; vp; pp = vp, vp = vp->next)			if (!vp->count && !vp->dirty) {				pp->next = vp->next;				goto gotit;			}	write(2, (char *)sz(joe_gettext(_("vfile: out of memory\n"))));	exit(1);      gotit:	vp->addr = addr;	vp->vfile = vfile;	vp->dirty = 0;	vp->count = 1;	vp->next = htab[((addr >> LPGSIZE) + (unsigned long)vfile) & (HTSIZE - 1)];	htab[((addr >> LPGSIZE) + (unsigned long)vfile) & (HTSIZE - 1)] = vp;	if (addr < vfile->size) {		if (!vfile->fd) {			vfile->fd = open((char *)(vfile->name), O_RDWR);		}		lseek(vfile->fd, addr, 0);		if (addr + PGSIZE > vfile->size) {			joe_read(vfile->fd, vp->data, (int) (vfile->size - addr));			mset(vp->data + vfile->size - addr, 0, PGSIZE - (int) (vfile->size - addr));		} else			joe_read(vfile->fd, vp->data, PGSIZE);	} else		mset(vp->data, 0, PGSIZE);	return vp->data + ofst;}VFILE *vtmp(void){	VFILE *new = (VFILE *) joe_malloc(sizeof(VFILE));	new->fd = 0;	new->name = NULL;	new->alloc = 0;	new->size = 0;	new->left = 0;	new->lv = 0;	new->vpage = NULL;	new->flags = 1;	new->vpage1 = NULL;	new->addr = -1;	return enqueb_f(VFILE, link, &vfiles, new);}#ifdef junkVFILE *vopen(name)unsigned char *name;{	struct stat buf;	VFILE *new = (VFILE *) joe_malloc(sizeof(VFILE));	new->name = vsncpy(NULL, 0, sz(name));	new->fd = open(name, O_RDWR);	if (!new->fd) {		fprintf(stderr, (char *)joe_gettext(_("Couldn\'t open file \'%s\'\n")), name);		joe_free(new);		return NULL;	}	fstat(new->fd, &buf);	new->size = buf.st_size;	new->alloc = new->size;	new->left = 0;	new->lv = 0;	new->vpage = NULL;	new->flags = 0;	new->vpage1 = NULL;	new->addr = -1;	return enqueb_f(VFILE, link, &vfiles, new);}#endifvoid vclose(VFILE *vfile){	VPAGE *vp, *pp;	int x;	if (vfile->vpage)		vunlock(vfile->vpage);	if (vfile->vpage1)		vunlock(vfile->vpage1);	if (vfile->name) {		if (vfile->flags)			unlink((char *)vfile->name);		else			vflshf(vfile);		vsrm(vfile->name);	}	if (vfile->fd)		close(vfile->fd);	joe_free(deque_f(VFILE, link, vfile));	for (x = 0; x != HTSIZE; x++)		for (pp = (VPAGE *) (htab + x), vp = pp->next; vp;)			if (vp->vfile == vfile) {				pp->next = vp->next;				vp->next = freepages;				freepages = vp;				vp = pp->next;			} else {				pp = vp;				vp = vp->next;			}}#ifdef junk/* this is now broken */void vlimit(amount)long amount;{	VPAGE *vp, *pp;	int x, y;	maxvalloc = amount;	while (curvalloc > maxvalloc)		if (freepages) {			vp = freepages;			freepages = vp->next;			joe_free(vp->data);			joe_free(vp);			curvalloc -= PGSIZE;		} else {		      again:			for (y = HTSIZE, x = (random() & (HTSIZE - 1)); y; x = ((x + 1) & (HTSIZE - 1)), --y)				for (pp = (VPAGE *) (htab + x), vp = pp->next; vp; pp = vp, vp = vp->next)					if (!vp->count && !vp->dirty) {						pp->next = vp->next;						joe_free(vp->data);						joe_free(vp);						if ((curvalloc -= PGSIZE)						    <= maxvalloc)							return;						goto again;					}			vflsh();		      again1:			for (y = HTSIZE, x = (random() & (HTSIZE - 1)); y; x = ((x + 1) & (HTSIZE - 1)), --y)				for (pp = (VPAGE *) (htab + x), vp = pp->next; vp; pp = vp, vp = vp->next)					if (!vp->count && !vp->dirty) {						pp->next = vp->next;						joe_free(vp->data);						joe_free(vp);						if ((curvalloc -= PGSIZE)						    <= maxvalloc)							return;						goto again1;					}			return;		}}#endifoff_t my_valloc(VFILE *vfile, off_t size){	off_t start = vsize(vfile);	vfile->alloc = start + size;	if (vfile->lv) {		if (vheader(vfile->vpage)->addr + PGSIZE > vfile->alloc)			vfile->lv = PGSIZE - (vfile->alloc - vheader(vfile->vpage)->addr);		else			vfile->lv = 0;	}	return start;}#ifdef junkvoid vseek(vfile, addr)VFILE *vfile;long addr;{	vfile->alloc = vsize(vfile);	if (addr > vfile->alloc)		vfile->alloc = addr;	if (!vfile->vpage)		vfile->vpage = vlock(vfile, addr & ~(long) (PGSIZE - 1));	else if (vheader(vfile->vpage)->addr != (addr & ~(long) (PGSIZE - 1))) {		vunlock(vfile->vpage);		vfile->vpage = vlock(vfile, addr & ~(long) (PGSIZE - 1));	}	vfile->bufp = vfile->vpage + (addr & (PGSIZE - 1));	vfile->left = vfile->vpage + PGSIZE - vfile->bufp;	if (vheader(vfile->vpage)->addr + PGSIZE > vfile->alloc)		vfile->lv = PGSIZE - (vfile->alloc - vheader(vfile->vpage)->addr);	else		vfile->lv = 0;}int _vrgetc(vfile)VFILE *vfile;{	if (vtell(vfile) == 0)		return NO_MORE_DATA;	vseek(vfile, vtell(vfile) - 1);	++vfile->bufp;	--vfile->left;	return vrgetc(vfile);}int _vgetc(vfile)VFILE *vfile;{	if (vtell(vfile) == vsize(vfile))		return NO_MORE_DATA;	vseek(vfile, vtell(vfile));	return vgetc(vfile);}int nmvgetc(v)VFILE *v;{	return vgetc(v);}int _vputc(vfile, c)

⌨️ 快捷键说明

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