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