3d6ffec1031657e2a21b836b3120bcfd4b52f538
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / sfio / sfsize.c
1 /* $XConsortium: sfsize.c /main/3 1995/11/01 18:36:22 rswiston $ */
2 /***************************************************************
3 *                                                              *
4 *                      AT&T - PROPRIETARY                      *
5 *                                                              *
6 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
7 *                          AT&T CORP.                          *
8 *                                                              *
9 *                Copyright (c) 1995 AT&T Corp.                 *
10 *                     All Rights Reserved                      *
11 *                                                              *
12 *           This software is licensed by AT&T Corp.            *
13 *       under the terms and conditions of the license in       *
14 *       http://www.research.att.com/orgs/ssr/book/reuse        *
15 *                                                              *
16 *               This software was created by the               *
17 *           Software Engineering Research Department           *
18 *                    AT&T Bell Laboratories                    *
19 *                                                              *
20 *               For further information contact                *
21 *                     gsf@research.att.com                     *
22 *                                                              *
23 ***************************************************************/
24 #include        "sfhdr.h"
25
26 /*      Get the size of a stream.
27 **
28 **      Written by Kiem-Phong Vo (02/12/91)
29 */
30 #if __STD_C
31 long sfsize(reg Sfio_t *f)
32 #else
33 long sfsize(f)
34 reg Sfio_t      *f;
35 #endif
36 {
37         reg int mode;
38
39         if((mode = f->mode&SF_RDWR) != f->mode && _sfmode(f,mode,0) < 0)
40                 return -1L;
41
42         if(f->flags&SF_STRING)
43         {       SFSTRSIZE(f);
44                 return f->extent;
45         }
46
47         if(f->extent >= 0 && (f->flags&(SF_SHARE|SF_APPEND)) )
48         {       reg Sfdisc_t*   disc;
49                 for(disc = f->disc; disc; disc = disc->disc)
50                         if(disc->seekf)
51                                 break;
52                 if(disc)
53                 {       f->extent = SFSK(f,0L,2,disc);
54                         (void)SFSK(f,f->here,0,disc);
55                 }
56                 else
57                 {       struct stat     st;
58                         if(fstat(f->file,&st) < 0)
59                                 f->extent = -1L;
60                         else    f->extent = st.st_size;
61                 }
62         }
63
64         if(f->extent < 0)
65                 return -1L;
66         else if(f->mode&SF_READ)
67                 return f->extent;
68         else if(f->flags&SF_APPEND)
69                 return f->extent + (f->next - f->data);
70         else
71         {       reg long s;
72                 if((f->flags&(SF_SHARE|SF_PUBLIC)) == (SF_SHARE|SF_PUBLIC))
73                 {       if((s = SFSK(f,0L,1,f->disc)) < 0)
74                                 return -1L;
75                         f->here = s;
76                 }
77                 s = f->here + (f->next - f->data);
78                 return s >= f->extent ? s : f->extent;
79         }
80 }