14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #include "sfhdr.h"
234887Schin
244887Schin /* Write a buffer out to a file descriptor or
254887Schin ** extending a buffer for a SF_STRING stream.
264887Schin **
274887Schin ** Written by Kiem-Phong Vo
284887Schin */
294887Schin
304887Schin #if __STD_C
_sfflsbuf(Sfio_t * f,int c)318462SApril.Chin@Sun.COM int _sfflsbuf(Sfio_t* f, int c)
324887Schin #else
334887Schin int _sfflsbuf(f,c)
348462SApril.Chin@Sun.COM Sfio_t* f; /* write out the buffered content of this stream */
358462SApril.Chin@Sun.COM int c; /* if c>=0, c is also written out */
364887Schin #endif
374887Schin {
3810898Sroland.mainz@nrubsig.org ssize_t n, w, written;
398462SApril.Chin@Sun.COM uchar* data;
404887Schin uchar outc;
418462SApril.Chin@Sun.COM int local, isall;
424887Schin int inpc = c;
4310898Sroland.mainz@nrubsig.org SFMTXDECL(f); /* declare a local stream variable for multithreading */
444887Schin
458462SApril.Chin@Sun.COM SFMTXENTER(f,-1);
464887Schin
474887Schin GETLOCAL(f,local);
484887Schin
4910898Sroland.mainz@nrubsig.org for(written = 0;; f->mode &= ~SF_LOCK)
504887Schin { /* check stream mode */
514887Schin if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0)
524887Schin SFMTXRETURN(f, -1);
534887Schin SFLOCK(f,local);
544887Schin
554887Schin /* current data extent */
564887Schin n = f->next - (data = f->data);
574887Schin
584887Schin if(n == (f->endb-data) && (f->flags&SF_STRING))
594887Schin { /* extend string stream buffer */
604887Schin (void)SFWR(f,data,1,f->disc);
614887Schin
624887Schin /* !(f->flags&SF_STRING) is required because exception
634887Schin handlers may turn a string stream to a file stream */
644887Schin if(f->next < f->endb || !(f->flags&SF_STRING) )
654887Schin n = f->next - (data = f->data);
664887Schin else
674887Schin { SFOPEN(f,local);
684887Schin SFMTXRETURN(f, -1);
694887Schin }
704887Schin }
714887Schin
724887Schin if(c >= 0)
734887Schin { /* write into buffer */
744887Schin if(n < (f->endb - (data = f->data)))
754887Schin { *f->next++ = c;
764887Schin if(c == '\n' &&
774887Schin (f->flags&SF_LINE) && !(f->flags&SF_STRING))
784887Schin { c = -1;
794887Schin n += 1;
804887Schin }
814887Schin else break;
824887Schin }
834887Schin else if(n == 0)
844887Schin { /* unbuffered io */
854887Schin outc = (uchar)c;
864887Schin data = &outc;
874887Schin c = -1;
884887Schin n = 1;
894887Schin }
904887Schin }
914887Schin
924887Schin if(n == 0 || (f->flags&SF_STRING))
934887Schin break;
944887Schin
954887Schin isall = SFISALL(f,isall);
964887Schin if((w = SFWR(f,data,n,f->disc)) > 0)
974887Schin { if((n -= w) > 0) /* save unwritten data, then resume */
984887Schin memcpy((char*)f->data,(char*)data+w,n);
9910898Sroland.mainz@nrubsig.org written += w;
1004887Schin f->next = f->data+n;
1014887Schin if(c < 0 && (!isall || n == 0))
1024887Schin break;
1034887Schin }
1044887Schin else if(w == 0)
10510898Sroland.mainz@nrubsig.org { if(written > 0) /* some buffer was cleared */
10610898Sroland.mainz@nrubsig.org break; /* do normal exit below */
10710898Sroland.mainz@nrubsig.org else /* nothing was done, returning failure */
10810898Sroland.mainz@nrubsig.org { SFOPEN(f,local);
10910898Sroland.mainz@nrubsig.org SFMTXRETURN(f, -1);
11010898Sroland.mainz@nrubsig.org }
1114887Schin }
11210898Sroland.mainz@nrubsig.org else /* w < 0 means SF_EDISC or SF_ESTACK in sfwr() */
11310898Sroland.mainz@nrubsig.org { if(c < 0) /* back to the calling write operation */
11410898Sroland.mainz@nrubsig.org break;
11510898Sroland.mainz@nrubsig.org else continue; /* try again to write out c */
11610898Sroland.mainz@nrubsig.org }
1174887Schin }
1184887Schin
1194887Schin SFOPEN(f,local);
1204887Schin
1214887Schin if(inpc < 0)
1224887Schin inpc = f->endb-f->next;
1234887Schin
1244887Schin SFMTXRETURN(f,inpc);
1254887Schin }
126