xref: /onnv-gate/usr/src/lib/libast/common/sfio/sfsk.c (revision 12068:08a39a083754)
14887Schin /***********************************************************************
24887Schin *                                                                      *
34887Schin *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
54887Schin *                      and is licensed under the                       *
64887Schin *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
84887Schin *                                                                      *
94887Schin *                A copy of the License is available at                 *
104887Schin *            http://www.opensource.org/licenses/cpl1.0.txt             *
114887Schin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
124887Schin *                                                                      *
134887Schin *              Information and Software Systems Research               *
144887Schin *                            AT&T Research                             *
154887Schin *                           Florham Park NJ                            *
164887Schin *                                                                      *
174887Schin *                 Glenn Fowler <gsf@research.att.com>                  *
184887Schin *                  David Korn <dgk@research.att.com>                   *
194887Schin *                   Phong Vo <kpv@research.att.com>                    *
204887Schin *                                                                      *
214887Schin ***********************************************************************/
224887Schin #include	"sfhdr.h"
234887Schin 
244887Schin /*	Seek function that knows discipline
254887Schin **
264887Schin **	Written by Kiem-Phong Vo.
274887Schin */
284887Schin #if __STD_C
sfsk(Sfio_t * f,Sfoff_t addr,int type,Sfdisc_t * disc)298462SApril.Chin@Sun.COM Sfoff_t sfsk(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc)
304887Schin #else
314887Schin Sfoff_t sfsk(f,addr,type,disc)
328462SApril.Chin@Sun.COM Sfio_t*		f;
334887Schin Sfoff_t		addr;
348462SApril.Chin@Sun.COM int		type;
354887Schin Sfdisc_t*	disc;
364887Schin #endif
374887Schin {
384887Schin 	Sfoff_t		p;
394887Schin 	reg Sfdisc_t*	dc;
404887Schin 	reg ssize_t	s;
414887Schin 	reg int		local, mode;
428462SApril.Chin@Sun.COM 	SFMTXDECL(f);
434887Schin 
448462SApril.Chin@Sun.COM 	SFMTXENTER(f, (Sfoff_t)(-1));
454887Schin 
464887Schin 	GETLOCAL(f,local);
474887Schin 	if(!local && !(f->bits&SF_DCDOWN))
484887Schin 	{	if((mode = f->mode&SF_RDWR) != (int)f->mode && _sfmode(f,mode,0) < 0)
494887Schin 			SFMTXRETURN(f, (Sfoff_t)(-1));
504887Schin 		if(SFSYNC(f) < 0)
514887Schin 			SFMTXRETURN(f, (Sfoff_t)(-1));
524887Schin #ifdef MAP_TYPE
534887Schin 		if(f->mode == SF_READ && (f->bits&SF_MMAP) && f->data)
544887Schin 		{	SFMUNMAP(f, f->data, f->endb-f->data);
554887Schin 			f->data = NIL(uchar*);
564887Schin 		}
574887Schin #endif
584887Schin 		f->next = f->endb = f->endr = f->endw = f->data;
594887Schin 	}
604887Schin 
614887Schin 	if((type &= (SEEK_SET|SEEK_CUR|SEEK_END)) > SEEK_END)
624887Schin 		SFMTXRETURN(f, (Sfoff_t)(-1));
634887Schin 
644887Schin 	for(;;)
654887Schin 	{	dc = disc;
664887Schin 		if(f->flags&SF_STRING)
674887Schin 		{	SFSTRSIZE(f);
684887Schin 			if(type == SEEK_SET)
694887Schin 				s = (ssize_t)addr;
704887Schin 			else if(type == SEEK_CUR)
714887Schin 				s = (ssize_t)(addr + f->here);
724887Schin 			else	s = (ssize_t)(addr + f->extent);
734887Schin 		}
744887Schin 		else
754887Schin 		{	SFDISC(f,dc,seekf);
764887Schin 			if(dc && dc->seekf)
774887Schin 			{	SFDCSK(f,addr,type,dc,p);
784887Schin 			}
794887Schin 			else
804887Schin 			{	p = syslseekf(f->file,(sfoff_t)addr,type);
814887Schin 			}
824887Schin 			if(p >= 0)
834887Schin 				SFMTXRETURN(f,p);
844887Schin 			s = -1;
854887Schin 		}
864887Schin 
874887Schin 		if(local)
884887Schin 			SETLOCAL(f);
894887Schin 		switch(_sfexcept(f,SF_SEEK,s,dc))
904887Schin 		{
914887Schin 		case SF_EDISC:
924887Schin 		case SF_ECONT:
934887Schin 			if(f->flags&SF_STRING)
944887Schin 				SFMTXRETURN(f, (Sfoff_t)s);
954887Schin 			goto do_continue;
964887Schin 		default:
974887Schin 			SFMTXRETURN(f, (Sfoff_t)(-1));
984887Schin 		}
994887Schin 
1004887Schin 	do_continue:
1014887Schin 		for(dc = f->disc; dc; dc = dc->disc)
1024887Schin 			if(dc == disc)
1034887Schin 				break;
1044887Schin 		disc = dc;
1054887Schin 	}
1064887Schin }
107