Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / sfio / sfsync.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: sfsync.c /main/3 1995/11/01 18:37:23 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *         THIS IS PROPRIETARY SOURCE CODE LICENSED BY          *
29 *                          AT&T CORP.                          *
30 *                                                              *
31 *                Copyright (c) 1995 AT&T Corp.                 *
32 *                     All Rights Reserved                      *
33 *                                                              *
34 *           This software is licensed by AT&T Corp.            *
35 *       under the terms and conditions of the license in       *
36 *       http://www.research.att.com/orgs/ssr/book/reuse        *
37 *                                                              *
38 *               This software was created by the               *
39 *           Software Engineering Research Department           *
40 *                    AT&T Bell Laboratories                    *
41 *                                                              *
42 *               For further information contact                *
43 *                     gsf@research.att.com                     *
44 *                                                              *
45 ***************************************************************/
46 #include        "sfhdr.h"
47
48 /*      Synchronize data in buffers with the file system.
49 **      If f is nil, all streams are sync-ed
50 **
51 **      Written by Kiem-Phong Vo (06/27/90)
52 */
53
54 static _sfall()
55 {
56         reg Sfpool_t    *p, *next;
57         reg Sfio_t*     f;
58         reg int         n, rv;
59         reg int         nsync, count, loop;
60 #define MAXLOOP 3
61
62         for(loop = 0; loop < MAXLOOP; ++loop)
63         {       rv = nsync = count = 0;
64                 for(p = &_Sfpool; p; p = next)
65                 {       /* find the next legitimate pool */
66                         for(next = p->next; next; next = next->next)
67                                 if(next->n_sf > 0)
68                                         break;
69
70                         /* walk the streams for _Sfpool only */
71                         for(n = 0; n < ((p == &_Sfpool) ? p->n_sf : 1); ++n)
72                         {       count += 1;
73                                 f = p->sf[n];
74
75                                 if(f->flags&SF_STRING )
76                                         goto did_sync;
77                                 if(SFFROZEN(f))
78                                         continue;
79                                 if((f->mode&SF_READ) && (f->mode&SF_SYNCED) )
80                                         goto did_sync;
81                                 if((f->mode&SF_READ) && !(f->flags&SF_MMAP) &&
82                                    f->next == f->endb)
83                                         goto did_sync;
84                                 if((f->mode&SF_WRITE) && !(f->flags&SF_HOLE) &&
85                                    f->next == f->data)
86                                         goto did_sync;
87
88                                 SFLOCK(f,0);
89                                 if(SFSYNC(f) < 0)
90                                         rv = -1;
91                                 SFOPEN(f,0);
92
93                         did_sync:
94                                 nsync += 1;
95                         }
96                 }
97
98                 if(nsync == count)
99                         break;
100         }
101         return rv;
102 }
103
104 #if __STD_C
105 sfsync(reg Sfio_t* f)
106 #else
107 sfsync(f)
108 reg Sfio_t*     f;      /* stream to be synchronized */
109 #endif
110 {
111         reg int local, rv, mode;
112
113         if(!f)
114                 return _sfall();
115
116         GETLOCAL(f,local);
117
118         if(f->disc == _Sfudisc) /* throw away ungetc */
119                 (void)sfclose((*_Sfstack)(f,NIL(Sfio_t*)));
120
121         rv = 0;
122
123         if((f->mode&SF_RDWR) != SFMODE(f,local) && _sfmode(f,0,local) < 0)
124         {       rv = -1;
125                 goto done;
126         }
127
128         for(; f; f = f->push)
129         {       SFLOCK(f,local);
130
131                 /* pretend that this stream is not on a stack */
132                 mode = f->mode&SF_PUSH;
133                 f->mode &= ~SF_PUSH;
134
135                 /* these streams do not need synchronization */
136                 if((f->flags&SF_STRING) || (f->mode&SF_SYNCED))
137                         goto next;
138
139                 if((f->mode&SF_WRITE) && (f->next > f->data || (f->flags&SF_HOLE)) )
140                 {       /* sync the buffer, make sure pool don't move */
141                         reg int pool = f->mode&SF_POOL;
142                         f->mode &= ~SF_POOL;
143                         if(f->next > f->data && SFFLSBUF(f,-1) < 0)
144                                 rv = -1;
145                         if(!SFISNULL(f) && (f->flags&SF_HOLE) )
146                         {       /* realize a previously created hole of 0's */
147                                 if(lseek(f->file,-1L,1) >= 0)
148                                         (void)write(f->file,"",1);
149                                 f->flags &= ~SF_HOLE;
150                         }
151                         f->mode |= pool;
152                 }
153
154                 if((f->mode&SF_READ) && f->extent >= 0 &&
155                    ((f->flags&SF_MMAP) || f->next < f->endb) )
156                 {       /* make sure the file pointer is at the right place */
157                         f->here -= (f->endb-f->next);
158                         f->endr = f->endw = f->data;
159                         f->mode = SF_READ|SF_SYNCED|SF_LOCK;
160                         (void)SFSK(f,f->here,0,f->disc);
161
162                         if((f->flags&SF_SHARE) && !(f->flags&SF_PUBLIC) &&
163                            !(f->flags&SF_MMAP) )
164                         {       f->endb = f->next = f->data;
165                                 f->mode &= ~SF_SYNCED;
166                         }
167                 }
168
169         next:
170                 f->mode |= mode;
171                 SFOPEN(f,local);
172
173                 if(!local && !(f->flags&SF_ERROR) && (f->mode&~SF_RDWR) == 0 &&
174                    (f->flags&SF_IOCHECK) && f->disc && f->disc->exceptf)
175                         (void)(*f->disc->exceptf)(f,SF_SYNC,f->disc);
176         }
177
178 done:
179         if(!local && f && (f->mode&SF_POOL) && f->pool && f != f->pool->sf[0])
180                 SFSYNC(f->pool->sf[0]);
181
182         return rv;
183 }