2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: sfseek.c /main/3 1995/11/01 18:35:35 rswiston $ */
24 /***************************************************************
26 * AT&T - PROPRIETARY *
28 * THIS IS PROPRIETARY SOURCE CODE LICENSED BY *
31 * Copyright (c) 1995 AT&T Corp. *
32 * All Rights Reserved *
34 * This software is licensed by AT&T Corp. *
35 * under the terms and conditions of the license in *
36 * http://www.research.att.com/orgs/ssr/book/reuse *
38 * This software was created by the *
39 * Software Engineering Research Department *
40 * AT&T Bell Laboratories *
42 * For further information contact *
43 * gsf@research.att.com *
45 ***************************************************************/
48 /* Set the IO pointer to a specific location in the stream
50 ** Written by Kiem-Phong Vo (06/27/90)
54 long sfseek(reg Sfio_t* f, reg long p, reg int type)
57 reg Sfio_t *f; /* seek to a new location in this stream */
58 reg long p; /* place to seek to */
59 int type; /* 0: from org, 1: from here, 2: from end */
67 /* set and initialize the stream to a definite mode */
68 if(SFMODE(f,local) != (mode = f->mode&SF_RDWR) && _sfmode(f,mode,local) < 0 )
71 if(type < 0 || type > 2 || f->extent < 0L)
74 /* throw away ungetc data */
75 if(f->disc == _Sfudisc)
76 (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
78 /* lock the stream for internal manipulations */
81 /* clear error and eof bits */
82 f->flags &= ~(SF_EOF|SF_ERROR);
84 while(f->flags&SF_STRING)
88 r = p + (f->next - f->data);
93 if(r >= 0 && r <= f->size)
98 memclear((char*)(f->data+f->extent),(int)(p-f->extent));
102 /* check exception handler, note that this may pop stream */
103 if(SFSK(f,r,0,f->disc) != 0)
109 /* flush any pending write data */
110 if((f->mode&SF_WRITE) && f->next > f->data && SFSYNC(f) < 0)
115 /* currently known seek location */
116 if((f->flags&(SF_SHARE|SF_PUBLIC)) == (SF_SHARE|SF_PUBLIC))
117 { s = SFSK(f,0L,1,f->disc);
123 s = f->here + ((f->mode&SF_READ) ? f->next-f->endb : f->next-f->data);
126 /* no need to do anything */
127 if(!(f->flags&SF_SHARE) && type == 0 && s == p)
132 { /* move buffer pointer if possible */
133 p += type == 0 ? 0L : type == 1 ? s : f->extent;
134 if(p >= (f->here - (f->endb-f->data)) && p < f->here)
135 f->next = f->endb - (f->here - p);
137 { if(!(f->flags&SF_SHARE) || SFSK(f,p,0,f->disc) == p)
140 /* map is now invalid */
142 { (void)munmap((caddr_t)f->data,f->endb-f->data);
143 f->endb = f->endr = f->endw =
144 f->next = f->data = NIL(uchar*);
152 if(type == 1 && p == 0 && !(f->flags&(SF_APPEND|SF_SHARE)) )
153 { /* certify current location only */
154 if((p = SFSK(f,f->here,0,f->disc)) != f->here)
161 { if(!(f->flags&SF_SHARE) && type < 2 && ((r = type == 0 ? p : p+s)) == s)
162 { /* at where we are supposed to be */
167 else if(type < 2 && !(f->flags&(SF_SHARE|SF_APPEND)) &&
168 (r = p + (type == 0 ? 0L : s)) > f->here && r < f->extent)
169 { /* move forward by reading */
170 if(f->next == f->endb)
171 f->endb = f->endr = f->next = f->data;
172 if(r < (s + (f->size - (f->endb-f->data))))
173 (void)SFFILBUF(f,-1);
177 { /* place to seek to */
178 p += type == 0 ? 0L : s;
180 if((f->mode&SF_READ) && !(f->flags&(SF_SHARE|SF_APPEND)) &&
181 p >= (f->here - (f->endb-f->data)) && p <= f->here)
182 { /* still in bound, safe to just move the pointer */
183 f->next = f->endb - (f->here-p);
188 { if((p = SFSK(f,p,2,f->disc)) < 0)
194 { /* any buffered data is invalid */
195 f->next = f->endr = f->endb = f->data;
197 /* seek to a rounded boundary to improve performance */
198 if(f->size > 1 && p < f->extent && (r = (p/f->size)*f->size) < p &&
199 SFSK(f,r,0,f->disc) == r)
204 else f->next = f->endb - (f->here-p);
209 /* if get here must do a seek */
210 if(type < 2 && (p = SFSK(f,p,0,f->disc)) >= 0)