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

📄 sfrd.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       */#include	"sfhdr.h"/*	Internal function to do a hard read.**	This knows about discipline and memory mapping, peek read.****	Written by Kiem-Phong Vo.*//* synchronize unseekable write streams */#if __STD_Cstatic void _sfwrsync(void)#elsestatic void _sfwrsync()#endif{	reg Sfpool_t*	p;	reg Sfio_t*	f;	reg int		n;	/* sync all pool heads */	for(p = _Sfpool.next; p; p = p->next)	{	if(p->n_sf <= 0)			continue;		f = p->sf[0];		if(!SFFROZEN(f) && f->next > f->data &&		   (f->mode&SF_WRITE) && f->extent < 0 )			(void)_sfflsbuf(f,-1);	}	/* and all the ones in the discrete pool */	for(n = 0; n < _Sfpool.n_sf; ++n)	{	f = _Sfpool.sf[n];		if(!SFFROZEN(f) && f->next > f->data &&		   (f->mode&SF_WRITE) && f->extent < 0 )			(void)_sfflsbuf(f,-1);	}}#if __STD_Cssize_t sfrd(reg Sfio_t* f, reg Void_t* buf, reg size_t n, Sfdisc_t* disc)#elsessize_t sfrd(f,buf,n,disc)reg Sfio_t*	f;reg Void_t*	buf;reg size_t	n;Sfdisc_t*	disc;#endif{	Sfoff_t		r;	reg Sfdisc_t*	dc;	reg int		local, rcrv, dosync, oerrno;	SFMTXSTART(f,-1);	GETLOCAL(f,local);	if((rcrv = f->mode & (SF_RC|SF_RV)) )		f->mode &= ~(SF_RC|SF_RV);	f->bits &= ~SF_JUSTSEEK;	if(f->mode&SF_PKRD)		SFMTXRETURN(f, -1);	if(!local && !(f->bits&SF_DCDOWN)) /* an external user's call */	{	if(f->mode != SF_READ && _sfmode(f,SF_READ,0) < 0)			SFMTXRETURN(f, -1);		if(f->next < f->endb)		{	if(SFSYNC(f) < 0)				SFMTXRETURN(f, -1);#ifdef MAP_TYPE			if((f->bits&SF_MMAP) && f->data)			{	SFMUNMAP(f, f->data, f->endb-f->data);				f->data = NIL(uchar*);			}#endif			f->next = f->endb = f->endr = f->endw = f->data;		}	}	for(dosync = 0;;)	{	/* stream locked by sfsetfd() */		if(!(f->flags&SF_STRING) && f->file < 0)			SFMTXRETURN(f, 0);		f->flags &= ~(SF_EOF|SF_ERROR);		dc = disc;		if(f->flags&SF_STRING)		{	if((r = (f->data+f->extent) - f->next) < 0)				r = 0;			if(r <= 0)				goto do_except;			SFMTXRETURN(f, (ssize_t)r);		}		/* warn that a read is about to happen */		SFDISC(f,dc,readf);		if(dc && dc->exceptf && (f->flags&SF_IOCHECK) )		{	reg int	rv;			if(local)				SETLOCAL(f);			if((rv = _sfexcept(f,SF_READ,n,dc)) > 0)				n = rv;			else if(rv < 0)			{	f->flags |= SF_ERROR;				SFMTXRETURN(f, (ssize_t)rv);			}		}#ifdef MAP_TYPE		if(f->bits&SF_MMAP)		{	reg ssize_t	a, round;			sfstat_t	st;			/* determine if we have to copy data to buffer */			if((uchar*)buf >= f->data && (uchar*)buf <= f->endb)			{	n += f->endb - f->next;				buf = NIL(char*);			}			/* actual seek location */			if((f->flags&(SF_SHARE|SF_PUBLIC)) == (SF_SHARE|SF_PUBLIC) &&			   (r = SFSK(f,(Sfoff_t)0,SEEK_CUR,dc)) != f->here)				f->here = r;			else	f->here -= f->endb-f->next;			/* before mapping, make sure we have data to map */			if((f->flags&SF_SHARE) || (size_t)(r = f->extent-f->here) < n)			{	if((r = sysfstatf(f->file,&st)) < 0)					goto do_except;				if((r = (f->extent = st.st_size) - f->here) <= 0 )				{	r = 0;	/* eof */					goto do_except;				}			}			/* make sure current position is page aligned */			if((a = (size_t)(f->here%_Sfpage)) != 0)			{	f->here -= a;				r += a;			}			/* map minimal requirement */			if(r > (round = (1 + (n+a)/f->size)*f->size) )				r = round;			if(f->data)				SFMUNMAP(f, f->data, f->endb-f->data);			for(;;)			{	f->data = (uchar*) sysmmapf((caddr_t)0, (size_t)r,							(PROT_READ|PROT_WRITE),							MAP_PRIVATE,							f->file, (sfoff_t)f->here);				if(f->data && (caddr_t)f->data != (caddr_t)(-1))					break;				else				{	f->data = NIL(uchar*);					if((r >>= 1) < (_Sfpage*SF_NMAP) ||					   (errno != EAGAIN && errno != ENOMEM) )						break;				}			}			if(f->data)			{	if(f->bits&SF_SEQUENTIAL)					SFMMSEQON(f,f->data,r);				f->next = f->data+a;				f->endr = f->endb = f->data+r;				f->endw = f->data;				f->here += r;				/* make known our seek location */				(void)SFSK(f,f->here,SEEK_SET,dc);				if(buf)				{	if(n > (size_t)(r-a))						n = (ssize_t)(r-a);					memcpy(buf,f->next,n);					f->next += n;				}				else	n = f->endb - f->next;				SFMTXRETURN(f, n);			}			else			{	r = -1;				f->here += a;				/* reset seek pointer to its physical location */				(void)SFSK(f,f->here,SEEK_SET,dc);				/* make a buffer */				(void)SFSETBUF(f,(Void_t*)f->tiny,(size_t)SF_UNBOUND);				if(!buf)				{	buf = (Void_t*)f->data;					n = f->size;				}			}		}#endif		/* sync unseekable write streams to prevent deadlock */		if(!dosync && f->extent < 0)		{	dosync = 1;			_sfwrsync();		}		/* make sure file pointer is right */		if(f->extent >= 0 && (f->flags&SF_SHARE) )		{	if(!(f->flags&SF_PUBLIC) )				f->here = SFSK(f,f->here,SEEK_SET,dc);			else	f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,dc);		}		oerrno = errno;		errno = 0;		if(dc && dc->readf)		{	int	share = f->flags&SF_SHARE;			if(rcrv) /* pass on rcrv for possible continuations */				f->mode |= rcrv;				/* tell readf that no peeking necessary */			else	f->flags &= ~SF_SHARE;			SFDCRD(f,buf,n,dc,r);			/* reset flags */			if(rcrv)				f->mode &= ~rcrv;			else	f->flags |= share;		}		else if(SFISNULL(f))			r = 0;		else if(f->extent < 0 && (f->flags&SF_SHARE) && rcrv)		{	/* try peek read */			r = sfpkrd(f->file, (char*)buf, n,				    (rcrv&SF_RC) ? (int)f->getr : -1,				    -1L, (rcrv&SF_RV) ? 1 : 0);			if(r > 0)			{	if(rcrv&SF_RV)					f->mode |= SF_PKRD;				else	f->mode |= SF_RC;			}		}		else	r = sysreadf(f->file,buf,n);		if(errno == 0 )			errno = oerrno;		if(r > 0 )		{	if(!(f->bits&SF_DCDOWN) )	/* not a continuation call */			{	if(!(f->mode&SF_PKRD) )				{	f->here += r;					if(f->extent >= 0 && f->extent < f->here)						f->extent = f->here;				}				if((uchar*)buf >= f->data &&				   (uchar*)buf < f->data+f->size)					f->endb = f->endr = ((uchar*)buf) + r;			}			SFMTXRETURN(f, (ssize_t)r);		}	do_except:		if(local)			SETLOCAL(f);		switch(_sfexcept(f,SF_READ,(ssize_t)r,dc))		{		case SF_ECONT :			goto do_continue;		case SF_EDONE :			n = local ? 0 : (ssize_t)r;			SFMTXRETURN(f,n);		case SF_EDISC :			if(!local && !(f->flags&SF_STRING))				goto do_continue;			/* else fall thru */		case SF_ESTACK :			SFMTXRETURN(f, -1);		}	do_continue:		for(dc = f->disc; dc; dc = dc->disc)			if(dc == disc)				break;		disc = dc;	}}

⌨️ 快捷键说明

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