1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
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