xref: /titanic_50/usr/src/lib/libast/common/sfio/sfputr.c (revision 269473047d747f7815af570197e4ef7322d3632c)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2009 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *            http://www.opensource.org/licenses/cpl1.0.txt             *
11 *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #include	"sfhdr.h"
23 
24 /*	Put out a null-terminated string
25 **
26 **	Written by Kiem-Phong Vo.
27 */
28 #if __STD_C
29 ssize_t sfputr(Sfio_t* f, const char* s, int rc)
30 #else
31 ssize_t sfputr(f,s,rc)
32 Sfio_t*		f;	/* write to this stream	*/
33 char*		s;	/* string to write	*/
34 int		rc;	/* record separator.	*/
35 #endif
36 {
37 	reg ssize_t	p, n, w;
38 	reg uchar*	ps;
39 	SFMTXDECL(f);
40 
41 	SFMTXENTER(f,-1);
42 
43 	if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
44 		SFMTXRETURN(f, -1);
45 
46 	SFLOCK(f,0);
47 
48 	for(w = 0; (*s || rc >= 0); )
49 	{	if(SFWPEEK(f,ps,p) < 0)
50 			break;
51 
52 		if(p == 0 || (f->flags&SF_WHOLE) )
53 		{	n = strlen(s);
54 			if(p >= (n + (rc < 0 ? 0 : 1)) )
55 			{	/* buffer can hold everything */
56 				if(n > 0)
57 				{	memcpy(ps, s, n);
58 					ps += n;
59 					w += n;
60 				}
61 				if(rc >= 0)
62 				{	*ps++ = rc;
63 					w += 1;
64 				}
65 				f->next = ps;
66 			}
67 			else
68 			{	/* create a reserve buffer to hold data */
69 				Sfrsrv_t*	rsrv;
70 
71 				p = n + (rc >= 0 ? 1 : 0);
72 				if(!(rsrv = _sfrsrv(f, p)) )
73 					n = 0;
74 				else
75 				{	if(n > 0)
76 						memcpy(rsrv->data, s, n);
77 					if(rc >= 0)
78 						rsrv->data[n] = rc;
79 					if((n = SFWRITE(f,rsrv->data,p)) < 0 )
80 						n = 0;
81 				}
82 
83 				w += n;
84 			}
85 			break;
86 		}
87 
88 		if(*s == 0)
89 		{	*ps++ = rc;
90 			f->next = ps;
91 			w += 1;
92 			break;
93 		}
94 
95 #if _lib_memccpy && !__ia64 /* these guys may never get it right */
96 		if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
97 			ps -= 1;
98 		else	ps  = f->next+p;
99 		s += ps - f->next;
100 #else
101 		for(; p > 0; --p, ++ps, ++s)
102 			if((*ps = *s) == 0)
103 				break;
104 #endif
105 		w += ps - f->next;
106 		f->next = ps;
107 	}
108 
109 	/* sync unseekable shared streams */
110 	if(f->extent < 0 && (f->flags&SF_SHARE) )
111 		(void)SFFLSBUF(f,-1);
112 
113 	/* check for line buffering */
114 	else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
115 	{	if(n > w)
116 			n = w;
117 		f->next -= n;
118 		(void)SFWRITE(f,(Void_t*)f->next,n);
119 	}
120 
121 	SFOPEN(f,0);
122 	SFMTXRETURN(f, w);
123 }
124