xref: /onnv-gate/usr/src/lib/libast/common/sfio/sfputr.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 /*	Put out a null-terminated string
254887Schin **
264887Schin **	Written by Kiem-Phong Vo.
274887Schin */
284887Schin #if __STD_C
sfputr(Sfio_t * f,const char * s,int rc)298462SApril.Chin@Sun.COM ssize_t sfputr(Sfio_t* f, const char* s, int rc)
304887Schin #else
314887Schin ssize_t sfputr(f,s,rc)
328462SApril.Chin@Sun.COM Sfio_t*		f;	/* write to this stream	*/
334887Schin char*		s;	/* string to write	*/
348462SApril.Chin@Sun.COM int		rc;	/* record separator.	*/
354887Schin #endif
364887Schin {
374887Schin 	reg ssize_t	p, n, w;
384887Schin 	reg uchar*	ps;
398462SApril.Chin@Sun.COM 	SFMTXDECL(f);
404887Schin 
418462SApril.Chin@Sun.COM 	SFMTXENTER(f,-1);
424887Schin 
434887Schin 	if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
444887Schin 		SFMTXRETURN(f, -1);
454887Schin 
464887Schin 	SFLOCK(f,0);
474887Schin 
484887Schin 	for(w = 0; (*s || rc >= 0); )
4910898Sroland.mainz@nrubsig.org 	{	if(SFWPEEK(f,ps,p) < 0)
5010898Sroland.mainz@nrubsig.org 			break;
514887Schin 
524887Schin 		if(p == 0 || (f->flags&SF_WHOLE) )
534887Schin 		{	n = strlen(s);
544887Schin 			if(p >= (n + (rc < 0 ? 0 : 1)) )
554887Schin 			{	/* buffer can hold everything */
564887Schin 				if(n > 0)
574887Schin 				{	memcpy(ps, s, n);
584887Schin 					ps += n;
594887Schin 					w += n;
604887Schin 				}
614887Schin 				if(rc >= 0)
624887Schin 				{	*ps++ = rc;
634887Schin 					w += 1;
644887Schin 				}
654887Schin 				f->next = ps;
664887Schin 			}
674887Schin 			else
684887Schin 			{	/* create a reserve buffer to hold data */
694887Schin 				Sfrsrv_t*	rsrv;
704887Schin 
714887Schin 				p = n + (rc >= 0 ? 1 : 0);
724887Schin 				if(!(rsrv = _sfrsrv(f, p)) )
734887Schin 					n = 0;
744887Schin 				else
754887Schin 				{	if(n > 0)
764887Schin 						memcpy(rsrv->data, s, n);
774887Schin 					if(rc >= 0)
784887Schin 						rsrv->data[n] = rc;
794887Schin 					if((n = SFWRITE(f,rsrv->data,p)) < 0 )
804887Schin 						n = 0;
814887Schin 				}
824887Schin 
834887Schin 				w += n;
844887Schin 			}
854887Schin 			break;
864887Schin 		}
874887Schin 
884887Schin 		if(*s == 0)
894887Schin 		{	*ps++ = rc;
904887Schin 			f->next = ps;
914887Schin 			w += 1;
924887Schin 			break;
934887Schin 		}
944887Schin 
954887Schin #if _lib_memccpy && !__ia64 /* these guys may never get it right */
964887Schin 		if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
974887Schin 			ps -= 1;
984887Schin 		else	ps  = f->next+p;
994887Schin 		s += ps - f->next;
1004887Schin #else
1014887Schin 		for(; p > 0; --p, ++ps, ++s)
1024887Schin 			if((*ps = *s) == 0)
1034887Schin 				break;
1044887Schin #endif
1054887Schin 		w += ps - f->next;
1064887Schin 		f->next = ps;
1074887Schin 	}
1084887Schin 
1094887Schin 	/* sync unseekable shared streams */
1104887Schin 	if(f->extent < 0 && (f->flags&SF_SHARE) )
1114887Schin 		(void)SFFLSBUF(f,-1);
1124887Schin 
1134887Schin 	/* check for line buffering */
1144887Schin 	else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
1154887Schin 	{	if(n > w)
1164887Schin 			n = w;
1174887Schin 		f->next -= n;
1184887Schin 		(void)SFWRITE(f,(Void_t*)f->next,n);
1194887Schin 	}
1204887Schin 
1214887Schin 	SFOPEN(f,0);
1224887Schin 	SFMTXRETURN(f, w);
1234887Schin }
124