xref: /titanic_50/usr/src/lib/libast/common/sfio/sfputr.c (revision 67e3a03ed4a2813074d36330f062ed6e593a4937)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                      by AT&T Knowledge Ventures                      *
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(reg Sfio_t* f, const char* s, reg int rc)
30 #else
31 ssize_t sfputr(f,s,rc)
32 reg Sfio_t*	f;	/* write to this stream	*/
33 char*		s;	/* string to write	*/
34 reg int		rc;	/* record separator.	*/
35 #endif
36 {
37 	reg ssize_t	p, n, w;
38 	reg uchar*	ps;
39 
40 	SFMTXSTART(f,-1);
41 
42 	if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
43 		SFMTXRETURN(f, -1);
44 
45 	SFLOCK(f,0);
46 
47 	for(w = 0; (*s || rc >= 0); )
48 	{	SFWPEEK(f,ps,p);
49 
50 		if(p == 0 || (f->flags&SF_WHOLE) )
51 		{	n = strlen(s);
52 			if(p >= (n + (rc < 0 ? 0 : 1)) )
53 			{	/* buffer can hold everything */
54 				if(n > 0)
55 				{	memcpy(ps, s, n);
56 					ps += n;
57 					w += n;
58 				}
59 				if(rc >= 0)
60 				{	*ps++ = rc;
61 					w += 1;
62 				}
63 				f->next = ps;
64 			}
65 			else
66 			{	/* create a reserve buffer to hold data */
67 				Sfrsrv_t*	rsrv;
68 
69 				p = n + (rc >= 0 ? 1 : 0);
70 				if(!(rsrv = _sfrsrv(f, p)) )
71 					n = 0;
72 				else
73 				{	if(n > 0)
74 						memcpy(rsrv->data, s, n);
75 					if(rc >= 0)
76 						rsrv->data[n] = rc;
77 					if((n = SFWRITE(f,rsrv->data,p)) < 0 )
78 						n = 0;
79 				}
80 
81 				w += n;
82 			}
83 			break;
84 		}
85 
86 		if(*s == 0)
87 		{	*ps++ = rc;
88 			f->next = ps;
89 			w += 1;
90 			break;
91 		}
92 
93 #if _lib_memccpy && !__ia64 /* these guys may never get it right */
94 		if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
95 			ps -= 1;
96 		else	ps  = f->next+p;
97 		s += ps - f->next;
98 #else
99 		for(; p > 0; --p, ++ps, ++s)
100 			if((*ps = *s) == 0)
101 				break;
102 #endif
103 		w += ps - f->next;
104 		f->next = ps;
105 	}
106 
107 	/* sync unseekable shared streams */
108 	if(f->extent < 0 && (f->flags&SF_SHARE) )
109 		(void)SFFLSBUF(f,-1);
110 
111 	/* check for line buffering */
112 	else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
113 	{	if(n > w)
114 			n = w;
115 		f->next -= n;
116 		(void)SFWRITE(f,(Void_t*)f->next,n);
117 	}
118 
119 	SFOPEN(f,0);
120 	SFMTXRETURN(f, w);
121 }
122