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 /* Write a buffer out to a file descriptor or
25 ** extending a buffer for a SF_STRING stream.
27 ** Written by Kiem-Phong Vo
31 int _sfflsbuf(Sfio_t
* f
, int c
)
34 Sfio_t
* f
; /* write out the buffered content of this stream */
35 int c
; /* if c>=0, c is also written out */
38 ssize_t n
, w
, written
;
43 SFMTXDECL(f
); /* declare a local stream variable for multithreading */
49 for(written
= 0;; f
->mode
&= ~SF_LOCK
)
50 { /* check stream mode */
51 if(SFMODE(f
,local
) != SF_WRITE
&& _sfmode(f
,SF_WRITE
,local
) < 0)
55 /* current data extent */
56 n
= f
->next
- (data
= f
->data
);
58 if(n
== (f
->endb
-data
) && (f
->flags
&SF_STRING
))
59 { /* extend string stream buffer */
60 (void)SFWR(f
,data
,1,f
->disc
);
62 /* !(f->flags&SF_STRING) is required because exception
63 handlers may turn a string stream to a file stream */
64 if(f
->next
< f
->endb
|| !(f
->flags
&SF_STRING
) )
65 n
= f
->next
- (data
= f
->data
);
73 { /* write into buffer */
74 if(n
< (f
->endb
- (data
= f
->data
)))
77 (f
->flags
&SF_LINE
) && !(f
->flags
&SF_STRING
))
92 if(n
== 0 || (f
->flags
&SF_STRING
))
95 isall
= SFISALL(f
,isall
);
96 if((w
= SFWR(f
,data
,n
,f
->disc
)) > 0)
97 { if((n
-= w
) > 0) /* save unwritten data, then resume */
98 memcpy((char*)f
->data
,(char*)data
+w
,n
);
101 if(c
< 0 && (!isall
|| n
== 0))
105 { if(written
> 0) /* some buffer was cleared */
106 break; /* do normal exit below */
107 else /* nothing was done, returning failure */
112 else /* w < 0 means SF_EDISC or SF_ESTACK in sfwr() */
113 { if(c
< 0) /* back to the calling write operation */
115 else continue; /* try again to write out c */
122 inpc
= f
->endb
-f
->next
;