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 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