xref: /titanic_41/usr/src/lib/libast/common/sfio/sfputr.c (revision d5ace9454616652a717c9831d949dffa319381f9)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2008 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 	{	SFWPEEK(f,ps,p);
50 
51 		if(p == 0 || (f->flags&SF_WHOLE) )
52 		{	n = strlen(s);
53 			if(p >= (n + (rc < 0 ? 0 : 1)) )
54 			{	/* buffer can hold everything */
55 				if(n > 0)
56 				{	memcpy(ps, s, n);
57 					ps += n;
58 					w += n;
59 				}
60 				if(rc >= 0)
61 				{	*ps++ = rc;
62 					w += 1;
63 				}
64 				f->next = ps;
65 			}
66 			else
67 			{	/* create a reserve buffer to hold data */
68 				Sfrsrv_t*	rsrv;
69 
70 				p = n + (rc >= 0 ? 1 : 0);
71 				if(!(rsrv = _sfrsrv(f, p)) )
72 					n = 0;
73 				else
74 				{	if(n > 0)
75 						memcpy(rsrv->data, s, n);
76 					if(rc >= 0)
77 						rsrv->data[n] = rc;
78 					if((n = SFWRITE(f,rsrv->data,p)) < 0 )
79 						n = 0;
80 				}
81 
82 				w += n;
83 			}
84 			break;
85 		}
86 
87 		if(*s == 0)
88 		{	*ps++ = rc;
89 			f->next = ps;
90 			w += 1;
91 			break;
92 		}
93 
94 #if _lib_memccpy && !__ia64 /* these guys may never get it right */
95 		if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
96 			ps -= 1;
97 		else	ps  = f->next+p;
98 		s += ps - f->next;
99 #else
100 		for(; p > 0; --p, ++ps, ++s)
101 			if((*ps = *s) == 0)
102 				break;
103 #endif
104 		w += ps - f->next;
105 		f->next = ps;
106 	}
107 
108 	/* sync unseekable shared streams */
109 	if(f->extent < 0 && (f->flags&SF_SHARE) )
110 		(void)SFFLSBUF(f,-1);
111 
112 	/* check for line buffering */
113 	else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
114 	{	if(n > w)
115 			n = w;
116 		f->next -= n;
117 		(void)SFWRITE(f,(Void_t*)f->next,n);
118 	}
119 
120 	SFOPEN(f,0);
121 	SFMTXRETURN(f, w);
122 }
123