xref: /onnv-gate/usr/src/lib/libast/common/sfio/sfflsbuf.c (revision 12068:08a39a083754)
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