1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1985-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
12da2e3ebdSchin * *
13da2e3ebdSchin * Information and Software Systems Research *
14da2e3ebdSchin * AT&T Research *
15da2e3ebdSchin * Florham Park NJ *
16da2e3ebdSchin * *
17da2e3ebdSchin * Glenn Fowler <gsf@research.att.com> *
18da2e3ebdSchin * David Korn <dgk@research.att.com> *
19da2e3ebdSchin * Phong Vo <kpv@research.att.com> *
20da2e3ebdSchin * *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #include "sfhdr.h"
23da2e3ebdSchin
24da2e3ebdSchin /* Synchronize data in buffers with the file system.
25da2e3ebdSchin ** If f is nil, all streams are sync-ed
26da2e3ebdSchin **
27da2e3ebdSchin ** Written by Kiem-Phong Vo.
28da2e3ebdSchin */
29da2e3ebdSchin
30da2e3ebdSchin #if __STD_C
_sfall(void)31da2e3ebdSchin static int _sfall(void)
32da2e3ebdSchin #else
33da2e3ebdSchin static int _sfall()
34da2e3ebdSchin #endif
35da2e3ebdSchin {
36da2e3ebdSchin reg Sfpool_t *p, *next;
37da2e3ebdSchin reg Sfio_t* f;
38da2e3ebdSchin reg int n, rv;
39da2e3ebdSchin reg int nsync, count, loop;
40da2e3ebdSchin #define MAXLOOP 3
41da2e3ebdSchin
42da2e3ebdSchin for(loop = 0; loop < MAXLOOP; ++loop)
43da2e3ebdSchin { rv = nsync = count = 0;
44da2e3ebdSchin for(p = &_Sfpool; p; p = next)
45da2e3ebdSchin { /* find the next legitimate pool */
46da2e3ebdSchin for(next = p->next; next; next = next->next)
47da2e3ebdSchin if(next->n_sf > 0)
48da2e3ebdSchin break;
49da2e3ebdSchin
50da2e3ebdSchin /* walk the streams for _Sfpool only */
51da2e3ebdSchin for(n = 0; n < ((p == &_Sfpool) ? p->n_sf : 1); ++n)
52da2e3ebdSchin { count += 1;
53da2e3ebdSchin f = p->sf[n];
54da2e3ebdSchin
55da2e3ebdSchin if(f->flags&SF_STRING )
56da2e3ebdSchin goto did_sync;
57da2e3ebdSchin if(SFFROZEN(f))
58da2e3ebdSchin continue;
59da2e3ebdSchin if((f->mode&SF_READ) && (f->mode&SF_SYNCED) )
60da2e3ebdSchin goto did_sync;
61da2e3ebdSchin if((f->mode&SF_READ) && !(f->bits&SF_MMAP) &&
62da2e3ebdSchin f->next == f->endb)
63da2e3ebdSchin goto did_sync;
64da2e3ebdSchin if((f->mode&SF_WRITE) && !(f->bits&SF_HOLE) &&
65da2e3ebdSchin f->next == f->data)
66da2e3ebdSchin goto did_sync;
67da2e3ebdSchin
68da2e3ebdSchin if(sfsync(f) < 0)
69da2e3ebdSchin rv = -1;
70da2e3ebdSchin
71da2e3ebdSchin did_sync:
72da2e3ebdSchin nsync += 1;
73da2e3ebdSchin }
74da2e3ebdSchin }
75da2e3ebdSchin
76da2e3ebdSchin if(nsync == count)
77da2e3ebdSchin break;
78da2e3ebdSchin }
79da2e3ebdSchin return rv;
80da2e3ebdSchin }
81da2e3ebdSchin
82da2e3ebdSchin #if __STD_C
sfsync(reg Sfio_t * f)83da2e3ebdSchin int sfsync(reg Sfio_t* f)
84da2e3ebdSchin #else
85da2e3ebdSchin int sfsync(f)
86da2e3ebdSchin reg Sfio_t* f; /* stream to be synchronized */
87da2e3ebdSchin #endif
88da2e3ebdSchin {
89da2e3ebdSchin int local, rv, mode, lock;
90da2e3ebdSchin Sfio_t* origf;
917c2fbfb3SApril Chin SFMTXDECL(f);
92da2e3ebdSchin
93da2e3ebdSchin if(!(origf = f) )
94da2e3ebdSchin return _sfall();
95da2e3ebdSchin
967c2fbfb3SApril Chin SFMTXENTER(origf,-1);
97da2e3ebdSchin
98da2e3ebdSchin GETLOCAL(origf,local);
99da2e3ebdSchin
100da2e3ebdSchin if(origf->disc == _Sfudisc) /* throw away ungetc */
101da2e3ebdSchin (void)sfclose((*_Sfstack)(origf,NIL(Sfio_t*)));
102da2e3ebdSchin
103da2e3ebdSchin rv = 0;
104da2e3ebdSchin
105da2e3ebdSchin lock = origf->mode&SF_LOCK;
106da2e3ebdSchin if(origf->mode == (SF_SYNCED|SF_READ) ) /* already synced */
107da2e3ebdSchin goto done;
108da2e3ebdSchin
109da2e3ebdSchin if((origf->mode&SF_RDWR) != SFMODE(origf,local) && _sfmode(origf,0,local) < 0)
110da2e3ebdSchin { rv = -1;
111da2e3ebdSchin goto done;
112da2e3ebdSchin }
113da2e3ebdSchin
114da2e3ebdSchin for(; f; f = f->push)
115da2e3ebdSchin {
116da2e3ebdSchin if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
117da2e3ebdSchin (void)(*f->disc->exceptf)(f,SF_SYNC,(Void_t*)((int)1),f->disc);
118da2e3ebdSchin
119da2e3ebdSchin SFLOCK(f,local);
120da2e3ebdSchin
121da2e3ebdSchin /* pretend that this stream is not on a stack */
122da2e3ebdSchin mode = f->mode&SF_PUSH;
123da2e3ebdSchin f->mode &= ~SF_PUSH;
124da2e3ebdSchin
125da2e3ebdSchin /* these streams do not need synchronization */
126da2e3ebdSchin if((f->flags&SF_STRING) || (f->mode&SF_SYNCED))
127da2e3ebdSchin goto next;
128da2e3ebdSchin
129da2e3ebdSchin if((f->mode&SF_WRITE) && (f->next > f->data || (f->bits&SF_HOLE)) )
130da2e3ebdSchin { /* sync the buffer, make sure pool don't move */
131da2e3ebdSchin reg int pool = f->mode&SF_POOL;
132da2e3ebdSchin f->mode &= ~SF_POOL;
133da2e3ebdSchin if(f->next > f->data && (SFWRALL(f), SFFLSBUF(f,-1)) < 0)
134da2e3ebdSchin rv = -1;
135da2e3ebdSchin if(!SFISNULL(f) && (f->bits&SF_HOLE) )
136da2e3ebdSchin { /* realize a previously created hole of 0's */
137da2e3ebdSchin if(SFSK(f,(Sfoff_t)(-1),SEEK_CUR,f->disc) >= 0)
138da2e3ebdSchin (void)SFWR(f,"",1,f->disc);
139da2e3ebdSchin f->bits &= ~SF_HOLE;
140da2e3ebdSchin }
141da2e3ebdSchin f->mode |= pool;
142da2e3ebdSchin }
143da2e3ebdSchin
144da2e3ebdSchin if((f->mode&SF_READ) && f->extent >= 0 &&
145da2e3ebdSchin ((f->bits&SF_MMAP) || f->next < f->endb) )
146da2e3ebdSchin { /* make sure the file pointer is at the right place */
147da2e3ebdSchin f->here -= (f->endb-f->next);
148da2e3ebdSchin f->endr = f->endw = f->data;
149da2e3ebdSchin f->mode = SF_READ|SF_SYNCED|lock;
150da2e3ebdSchin (void)SFSK(f,f->here,SEEK_SET,f->disc);
151da2e3ebdSchin
152da2e3ebdSchin if((f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) &&
153da2e3ebdSchin !(f->bits&SF_MMAP) )
154da2e3ebdSchin { f->endb = f->next = f->data;
155da2e3ebdSchin f->mode &= ~SF_SYNCED;
156da2e3ebdSchin }
157da2e3ebdSchin }
158da2e3ebdSchin
159da2e3ebdSchin next:
160da2e3ebdSchin f->mode |= mode;
161da2e3ebdSchin SFOPEN(f,local);
162da2e3ebdSchin
163da2e3ebdSchin if((f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
164da2e3ebdSchin (void)(*f->disc->exceptf)(f,SF_SYNC,(Void_t*)((int)0),f->disc);
165da2e3ebdSchin }
166da2e3ebdSchin
167da2e3ebdSchin done:
168da2e3ebdSchin if(!local && f && (f->mode&SF_POOL) && f->pool && f != f->pool->sf[0])
169da2e3ebdSchin SFSYNC(f->pool->sf[0]);
170da2e3ebdSchin
171da2e3ebdSchin SFMTXRETURN(origf, rv);
172da2e3ebdSchin }
173