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