Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / lib / libast / sfio / sfflsbuf.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: sfflsbuf.c /main/3 1995/11/01 18:29:15 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 /*      Write a buffer out to a file descriptor or
49 **      extending a buffer for a SF_STRING stream.
50 **
51 **      Written by Kiem-Phong Vo (06/27/90)
52 */
53
54 #if __STD_C
55 _sfflsbuf(reg Sfio_t* f, reg int c)
56 #else
57 _sfflsbuf(f,c)
58 reg Sfio_t      *f;     /* write out the buffered content of this stream */
59 reg int         c;      /* if c>=0, c is also written out */ 
60 #endif
61 {
62         reg int         n, w;
63         reg uchar       *data;
64         uchar           outc;
65         reg int         local;
66         int             inpc = c;
67
68         GETLOCAL(f,local);
69
70         for(;; f->mode &= ~SF_LOCK)
71         {       /* check stream mode */
72                 if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0)
73                         return -1;
74                 SFLOCK(f,local);
75
76                 /* current data extent */
77                 n = f->next - (data = f->data);
78
79                 if(n == (f->endb-f->data) && (f->flags&SF_STRING))
80                 {       /* extend string stream buffer */
81                         (void)SFWR(f,data,1,f->disc);
82
83                         /* !(f->flags&SF_STRING) is required because exception
84                            handlers may turn a string stream to a file stream */
85                         if(f->next < f->endb || !(f->flags&SF_STRING) )
86                                 n = f->next - (data = f->data);
87                         else
88                         {       SFOPEN(f,local);
89                                 return -1;
90                         }
91                 }
92
93                 if(c >= 0)
94                 {       /* write into buffer */
95                         if(n < (f->endb - (data = f->data)))
96                         {       *f->next++ = c;
97                                 if(c != '\n' ||
98                                    !(f->flags&SF_LINE) || (f->flags&SF_STRING))
99                                         break;
100                                 c = -1;
101                                 n += 1;
102                         }
103                         else if(n == 0)
104                         {       /* unbuffered io */
105                                 outc = (uchar)c;
106                                 data = &outc;
107                                 c = -1;
108                                 n = 1;
109                         }
110                 }
111
112                 /* writing data */
113                 if(n == 0 || (f->flags&SF_STRING))
114                         break;
115                 else if((w = SFWR(f,data,n,f->disc)) > 0)
116                 {       if((n -= w) > 0) /* save unwritten data, then resume */
117                                 memcpy((char*)f->data,(char*)data+w,n);
118                         f->next = f->data+n;
119                         if(n == 0 && c < 0)
120                                 break;
121                 }
122                 else if(w == 0)
123                 {       SFOPEN(f,local);
124                         return -1;
125                 }
126                 else if(c < 0)
127                         break;
128         }
129
130         SFOPEN(f,local);
131         return inpc < 0 ? (f->endb-f->next) : inpc;
132 }