da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "sfhdr.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* Seek function that knows discipline
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin**
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin** Written by Kiem-Phong Vo.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if __STD_C
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinSfoff_t sfsk(Sfio_t* f, Sfoff_t addr, int type, Sfdisc_t* disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t sfsk(f,addr,type,disc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinSfio_t* f;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t addr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdisc_t* disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg Sfdisc_t* dc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg ssize_t s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reg int local, mode;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SFMTXDECL(f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin SFMTXENTER(f, (Sfoff_t)(-1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin GETLOCAL(f,local);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!local && !(f->bits&SF_DCDOWN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { if((mode = f->mode&SF_RDWR) != (int)f->mode && _sfmode(f,mode,0) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f, (Sfoff_t)(-1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(SFSYNC(f) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f, (Sfoff_t)(-1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef MAP_TYPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f->mode == SF_READ && (f->bits&SF_MMAP) && f->data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { SFMUNMAP(f, f->data, f->endb-f->data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->data = NIL(uchar*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f->next = f->endb = f->endr = f->endw = f->data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type &= (SEEK_SET|SEEK_CUR|SEEK_END)) > SEEK_END)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f, (Sfoff_t)(-1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;;)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { dc = disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f->flags&SF_STRING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { SFSTRSIZE(f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type == SEEK_SET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (ssize_t)addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(type == SEEK_CUR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = (ssize_t)(addr + f->here);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else s = (ssize_t)(addr + f->extent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { SFDISC(f,dc,seekf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dc && dc->seekf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { SFDCSK(f,addr,type,dc,p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { p = syslseekf(f->file,(sfoff_t)addr,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(p >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f,p);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SETLOCAL(f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(_sfexcept(f,SF_SEEK,s,dc))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SF_EDISC:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SF_ECONT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f->flags&SF_STRING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f, (Sfoff_t)s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto do_continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin SFMTXRETURN(f, (Sfoff_t)(-1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin do_continue:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(dc = f->disc; dc; dc = dc->disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dc == disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disc = dc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}