14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*10898Sroland.mainz@nrubsig.org * Copyright (c) 1985-2009 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 78462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * Glenn Fowler <gsf@research.att.com> * 184887Schin * David Korn <dgk@research.att.com> * 194887Schin * Phong Vo <kpv@research.att.com> * 204887Schin * * 214887Schin ***********************************************************************/ 224887Schin #include "sfhdr.h" 234887Schin 244887Schin /* Write a buffer out to a file descriptor or 254887Schin ** extending a buffer for a SF_STRING stream. 264887Schin ** 274887Schin ** Written by Kiem-Phong Vo 284887Schin */ 294887Schin 304887Schin #if __STD_C 318462SApril.Chin@Sun.COM int _sfflsbuf(Sfio_t* f, int c) 324887Schin #else 334887Schin int _sfflsbuf(f,c) 348462SApril.Chin@Sun.COM Sfio_t* f; /* write out the buffered content of this stream */ 358462SApril.Chin@Sun.COM int c; /* if c>=0, c is also written out */ 364887Schin #endif 374887Schin { 38*10898Sroland.mainz@nrubsig.org ssize_t n, w, written; 398462SApril.Chin@Sun.COM uchar* data; 404887Schin uchar outc; 418462SApril.Chin@Sun.COM int local, isall; 424887Schin int inpc = c; 43*10898Sroland.mainz@nrubsig.org SFMTXDECL(f); /* declare a local stream variable for multithreading */ 444887Schin 458462SApril.Chin@Sun.COM SFMTXENTER(f,-1); 464887Schin 474887Schin GETLOCAL(f,local); 484887Schin 49*10898Sroland.mainz@nrubsig.org for(written = 0;; f->mode &= ~SF_LOCK) 504887Schin { /* check stream mode */ 514887Schin if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0) 524887Schin SFMTXRETURN(f, -1); 534887Schin SFLOCK(f,local); 544887Schin 554887Schin /* current data extent */ 564887Schin n = f->next - (data = f->data); 574887Schin 584887Schin if(n == (f->endb-data) && (f->flags&SF_STRING)) 594887Schin { /* extend string stream buffer */ 604887Schin (void)SFWR(f,data,1,f->disc); 614887Schin 624887Schin /* !(f->flags&SF_STRING) is required because exception 634887Schin handlers may turn a string stream to a file stream */ 644887Schin if(f->next < f->endb || !(f->flags&SF_STRING) ) 654887Schin n = f->next - (data = f->data); 664887Schin else 674887Schin { SFOPEN(f,local); 684887Schin SFMTXRETURN(f, -1); 694887Schin } 704887Schin } 714887Schin 724887Schin if(c >= 0) 734887Schin { /* write into buffer */ 744887Schin if(n < (f->endb - (data = f->data))) 754887Schin { *f->next++ = c; 764887Schin if(c == '\n' && 774887Schin (f->flags&SF_LINE) && !(f->flags&SF_STRING)) 784887Schin { c = -1; 794887Schin n += 1; 804887Schin } 814887Schin else break; 824887Schin } 834887Schin else if(n == 0) 844887Schin { /* unbuffered io */ 854887Schin outc = (uchar)c; 864887Schin data = &outc; 874887Schin c = -1; 884887Schin n = 1; 894887Schin } 904887Schin } 914887Schin 924887Schin if(n == 0 || (f->flags&SF_STRING)) 934887Schin break; 944887Schin 954887Schin isall = SFISALL(f,isall); 964887Schin if((w = SFWR(f,data,n,f->disc)) > 0) 974887Schin { if((n -= w) > 0) /* save unwritten data, then resume */ 984887Schin memcpy((char*)f->data,(char*)data+w,n); 99*10898Sroland.mainz@nrubsig.org written += w; 1004887Schin f->next = f->data+n; 1014887Schin if(c < 0 && (!isall || n == 0)) 1024887Schin break; 1034887Schin } 1044887Schin else if(w == 0) 105*10898Sroland.mainz@nrubsig.org { if(written > 0) /* some buffer was cleared */ 106*10898Sroland.mainz@nrubsig.org break; /* do normal exit below */ 107*10898Sroland.mainz@nrubsig.org else /* nothing was done, returning failure */ 108*10898Sroland.mainz@nrubsig.org { SFOPEN(f,local); 109*10898Sroland.mainz@nrubsig.org SFMTXRETURN(f, -1); 110*10898Sroland.mainz@nrubsig.org } 1114887Schin } 112*10898Sroland.mainz@nrubsig.org else /* w < 0 means SF_EDISC or SF_ESTACK in sfwr() */ 113*10898Sroland.mainz@nrubsig.org { if(c < 0) /* back to the calling write operation */ 114*10898Sroland.mainz@nrubsig.org break; 115*10898Sroland.mainz@nrubsig.org else continue; /* try again to write out c */ 116*10898Sroland.mainz@nrubsig.org } 1174887Schin } 1184887Schin 1194887Schin SFOPEN(f,local); 1204887Schin 1214887Schin if(inpc < 0) 1224887Schin inpc = f->endb-f->next; 1234887Schin 1244887Schin SFMTXRETURN(f,inpc); 1254887Schin } 126