summaryrefslogtreecommitdiff
path: root/usr/src/lib/libast/common/sfio/sfputr.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libast/common/sfio/sfputr.c')
-rw-r--r--usr/src/lib/libast/common/sfio/sfputr.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/usr/src/lib/libast/common/sfio/sfputr.c b/usr/src/lib/libast/common/sfio/sfputr.c
new file mode 100644
index 0000000000..7f2da997a5
--- /dev/null
+++ b/usr/src/lib/libast/common/sfio/sfputr.c
@@ -0,0 +1,121 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2007 AT&T Knowledge Ventures *
+* and is licensed under the *
+* Common Public License, Version 1.0 *
+* by AT&T Knowledge Ventures *
+* *
+* A copy of the License is available at *
+* http://www.opensource.org/licenses/cpl1.0.txt *
+* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#include "sfhdr.h"
+
+/* Put out a null-terminated string
+**
+** Written by Kiem-Phong Vo.
+*/
+#if __STD_C
+ssize_t sfputr(reg Sfio_t* f, const char* s, reg int rc)
+#else
+ssize_t sfputr(f,s,rc)
+reg Sfio_t* f; /* write to this stream */
+char* s; /* string to write */
+reg int rc; /* record separator. */
+#endif
+{
+ reg ssize_t p, n, w;
+ reg uchar* ps;
+
+ SFMTXSTART(f,-1);
+
+ if(f->mode != SF_WRITE && _sfmode(f,SF_WRITE,0) < 0)
+ SFMTXRETURN(f, -1);
+
+ SFLOCK(f,0);
+
+ for(w = 0; (*s || rc >= 0); )
+ { SFWPEEK(f,ps,p);
+
+ if(p == 0 || (f->flags&SF_WHOLE) )
+ { n = strlen(s);
+ if(p >= (n + (rc < 0 ? 0 : 1)) )
+ { /* buffer can hold everything */
+ if(n > 0)
+ { memcpy(ps, s, n);
+ ps += n;
+ w += n;
+ }
+ if(rc >= 0)
+ { *ps++ = rc;
+ w += 1;
+ }
+ f->next = ps;
+ }
+ else
+ { /* create a reserve buffer to hold data */
+ Sfrsrv_t* rsrv;
+
+ p = n + (rc >= 0 ? 1 : 0);
+ if(!(rsrv = _sfrsrv(f, p)) )
+ n = 0;
+ else
+ { if(n > 0)
+ memcpy(rsrv->data, s, n);
+ if(rc >= 0)
+ rsrv->data[n] = rc;
+ if((n = SFWRITE(f,rsrv->data,p)) < 0 )
+ n = 0;
+ }
+
+ w += n;
+ }
+ break;
+ }
+
+ if(*s == 0)
+ { *ps++ = rc;
+ f->next = ps;
+ w += 1;
+ break;
+ }
+
+#if _lib_memccpy && !__ia64 /* these guys may never get it right */
+ if((ps = (uchar*)memccpy(ps,s,'\0',p)) != NIL(uchar*))
+ ps -= 1;
+ else ps = f->next+p;
+ s += ps - f->next;
+#else
+ for(; p > 0; --p, ++ps, ++s)
+ if((*ps = *s) == 0)
+ break;
+#endif
+ w += ps - f->next;
+ f->next = ps;
+ }
+
+ /* sync unseekable shared streams */
+ if(f->extent < 0 && (f->flags&SF_SHARE) )
+ (void)SFFLSBUF(f,-1);
+
+ /* check for line buffering */
+ else if((f->flags&SF_LINE) && !(f->flags&SF_STRING) && (n = f->next-f->data) > 0)
+ { if(n > w)
+ n = w;
+ f->next -= n;
+ (void)SFWRITE(f,(Void_t*)f->next,n);
+ }
+
+ SFOPEN(f,0);
+ SFMTXRETURN(f, w);
+}