1 /***********************************************************************
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 *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
24 /* Synchronize data in buffers with the file system.
25 ** If f is nil, all streams are sync-ed
27 ** Written by Kiem-Phong Vo.
31 static int _sfall(void)
36 reg Sfpool_t
*p
, *next
;
39 reg
int nsync
, count
, loop
;
42 for(loop
= 0; loop
< MAXLOOP
; ++loop
)
43 { rv
= nsync
= count
= 0;
44 for(p
= &_Sfpool
; p
; p
= next
)
45 { /* find the next legitimate pool */
46 for(next
= p
->next
; next
; next
= next
->next
)
50 /* walk the streams for _Sfpool only */
51 for(n
= 0; n
< ((p
== &_Sfpool
) ? p
->n_sf
: 1); ++n
)
55 if(f
->flags
&SF_STRING
)
59 if((f
->mode
&SF_READ
) && (f
->mode
&SF_SYNCED
) )
61 if((f
->mode
&SF_READ
) && !(f
->bits
&SF_MMAP
) &&
64 if((f
->mode
&SF_WRITE
) && !(f
->bits
&SF_HOLE
) &&
83 int sfsync(reg Sfio_t
* f
)
86 reg Sfio_t
* f
; /* stream to be synchronized */
89 int local
, rv
, mode
, lock
;
98 GETLOCAL(origf
,local
);
100 if(origf
->disc
== _Sfudisc
) /* throw away ungetc */
101 (void)sfclose((*_Sfstack
)(origf
,NIL(Sfio_t
*)));
105 lock
= origf
->mode
&SF_LOCK
;
106 if(origf
->mode
== (SF_SYNCED
|SF_READ
) ) /* already synced */
109 if((origf
->mode
&SF_RDWR
) != SFMODE(origf
,local
) && _sfmode(origf
,0,local
) < 0)
114 for(; f
; f
= f
->push
)
116 if((f
->flags
&SF_IOCHECK
) && f
->disc
&& f
->disc
->exceptf
)
117 (void)(*f
->disc
->exceptf
)(f
,SF_SYNC
,(Void_t
*)((int)1),f
->disc
);
121 /* pretend that this stream is not on a stack */
122 mode
= f
->mode
&SF_PUSH
;
125 /* these streams do not need synchronization */
126 if((f
->flags
&SF_STRING
) || (f
->mode
&SF_SYNCED
))
129 if((f
->mode
&SF_WRITE
) && (f
->next
> f
->data
|| (f
->bits
&SF_HOLE
)) )
130 { /* sync the buffer, make sure pool don't move */
131 reg
int pool
= f
->mode
&SF_POOL
;
133 if(f
->next
> f
->data
&& (SFWRALL(f
), SFFLSBUF(f
,-1)) < 0)
135 if(!SFISNULL(f
) && (f
->bits
&SF_HOLE
) )
136 { /* realize a previously created hole of 0's */
137 if(SFSK(f
,(Sfoff_t
)(-1),SEEK_CUR
,f
->disc
) >= 0)
138 (void)SFWR(f
,"",1,f
->disc
);
144 if((f
->mode
&SF_READ
) && f
->extent
>= 0 &&
145 ((f
->bits
&SF_MMAP
) || f
->next
< f
->endb
) )
146 { /* make sure the file pointer is at the right place */
147 f
->here
-= (f
->endb
-f
->next
);
148 f
->endr
= f
->endw
= f
->data
;
149 f
->mode
= SF_READ
|SF_SYNCED
|lock
;
150 (void)SFSK(f
,f
->here
,SEEK_SET
,f
->disc
);
152 if((f
->flags
&SF_SHARE
) && !(f
->flags
&SF_PUBLIC
) &&
154 { f
->endb
= f
->next
= f
->data
;
155 f
->mode
&= ~SF_SYNCED
;
163 if((f
->flags
&SF_IOCHECK
) && f
->disc
&& f
->disc
->exceptf
)
164 (void)(*f
->disc
->exceptf
)(f
,SF_SYNC
,(Void_t
*)((int)0),f
->disc
);
168 if(!local
&& f
&& (f
->mode
&SF_POOL
) && f
->pool
&& f
!= f
->pool
->sf
[0])
169 SFSYNC(f
->pool
->sf
[0]);
171 SFMTXRETURN(origf
, rv
);