1da2e3ebchin/***********************************************************************
2da2e3ebchin*                                                                      *
3da2e3ebchin*               This software is part of the ast package               *
43e14f97Roger A. Faulkner*          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5da2e3ebchin*                      and is licensed under the                       *
6da2e3ebchin*                  Common Public License, Version 1.0                  *
77c2fbfbApril Chin*                    by AT&T Intellectual Property                     *
8da2e3ebchin*                                                                      *
9da2e3ebchin*                A copy of the License is available at                 *
10da2e3ebchin*            http://www.opensource.org/licenses/cpl1.0.txt             *
11da2e3ebchin*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12da2e3ebchin*                                                                      *
13da2e3ebchin*              Information and Software Systems Research               *
14da2e3ebchin*                            AT&T Research                             *
15da2e3ebchin*                           Florham Park NJ                            *
16da2e3ebchin*                                                                      *
17da2e3ebchin*                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebchin*                  David Korn <dgk@research.att.com>                   *
19da2e3ebchin*                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebchin*                                                                      *
21da2e3ebchin***********************************************************************/
22da2e3ebchin#include	"sfhdr.h"
23da2e3ebchin
24da2e3ebchin/*	Get the size of a stream.
25da2e3ebchin**
26da2e3ebchin**	Written by Kiem-Phong Vo.
27da2e3ebchin*/
28da2e3ebchin#if __STD_C
297c2fbfbApril ChinSfoff_t sfsize(Sfio_t* f)
30da2e3ebchin#else
31da2e3ebchinSfoff_t sfsize(f)
327c2fbfbApril ChinSfio_t*	f;
33da2e3ebchin#endif
34da2e3ebchin{
35da2e3ebchin	Sfdisc_t*	disc;
36da2e3ebchin	reg int		mode;
37da2e3ebchin	Sfoff_t		s;
387c2fbfbApril Chin	SFMTXDECL(f);
39da2e3ebchin
407c2fbfbApril Chin	SFMTXENTER(f, (Sfoff_t)(-1));
41da2e3ebchin
42da2e3ebchin	if((mode = f->mode&SF_RDWR) != (int)f->mode && _sfmode(f,mode,0) < 0)
43da2e3ebchin		SFMTXRETURN(f, (Sfoff_t)(-1));
44da2e3ebchin
45da2e3ebchin	if(f->flags&SF_STRING)
46da2e3ebchin	{	SFSTRSIZE(f);
47da2e3ebchin		SFMTXRETURN(f, f->extent);
48da2e3ebchin	}
49da2e3ebchin
50da2e3ebchin	SFLOCK(f,0);
51da2e3ebchin
52da2e3ebchin	s = f->here;
53da2e3ebchin
54da2e3ebchin	if(f->extent >= 0)
55da2e3ebchin	{	if(f->flags&(SF_SHARE|SF_APPENDWR))
56da2e3ebchin		{	for(disc = f->disc; disc; disc = disc->disc)
57da2e3ebchin				if(disc->seekf)
58da2e3ebchin					break;
59da2e3ebchin			if(!_sys_stat || disc)
60da2e3ebchin			{	Sfoff_t	e;
61da2e3ebchin				if((e = SFSK(f,0,SEEK_END,disc)) >= 0)
62da2e3ebchin					f->extent = e;
63da2e3ebchin				if(SFSK(f,f->here,SEEK_SET,disc) != f->here)
64da2e3ebchin					f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,disc);
65da2e3ebchin			}
66da2e3ebchin#if _sys_stat
67da2e3ebchin			else
68da2e3ebchin			{	sfstat_t	st;
69da2e3ebchin				if(sysfstatf(f->file,&st) < 0)
70da2e3ebchin					f->extent = -1;
71da2e3ebchin				else if((f->extent = st.st_size) < f->here)
72da2e3ebchin					f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,disc);
73da2e3ebchin			}
74da2e3ebchin#endif
75da2e3ebchin		}
76da2e3ebchin
77da2e3ebchin		if((f->flags&(SF_SHARE|SF_PUBLIC)) == (SF_SHARE|SF_PUBLIC))
78da2e3ebchin			f->here = SFSK(f,(Sfoff_t)0,SEEK_CUR,f->disc);
79da2e3ebchin	}
80da2e3ebchin
81da2e3ebchin	if(f->here != s && (f->mode&SF_READ) )
82da2e3ebchin	{	/* buffered data is known to be invalid */
83da2e3ebchin#ifdef MAP_TYPE
84da2e3ebchin		if((f->bits&SF_MMAP) && f->data)
85da2e3ebchin		{	SFMUNMAP(f,f->data,f->endb-f->data);
86da2e3ebchin			f->data = NIL(uchar*);
87da2e3ebchin		}
88da2e3ebchin#endif
89da2e3ebchin		f->next = f->endb = f->endr = f->endw = f->data;
90da2e3ebchin	}
91da2e3ebchin
92da2e3ebchin	if(f->here < 0)
93da2e3ebchin		f->extent = -1;
94da2e3ebchin	else if(f->extent < f->here)
95da2e3ebchin		f->extent = f->here;
96da2e3ebchin
97da2e3ebchin	if((s = f->extent) >= 0)
98da2e3ebchin	{	if(f->flags&SF_APPENDWR)
99da2e3ebchin			s += (f->next - f->data);
100da2e3ebchin		else if(f->mode&SF_WRITE)
101da2e3ebchin		{	s = f->here + (f->next - f->data);
102da2e3ebchin			if(s < f->extent)
103da2e3ebchin				s = f->extent;
104da2e3ebchin		}
105da2e3ebchin	}
106da2e3ebchin
107da2e3ebchin	SFOPEN(f,0);
108da2e3ebchin	SFMTXRETURN(f, s);
109da2e3ebchin}
110