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 /* Write a buffer out to a file descriptor or 25 ** extending a buffer for a SF_STRING stream. 26 ** 27 ** Written by Kiem-Phong Vo 28 */ 29 30 #if __STD_C 31 int _sfflsbuf(reg Sfio_t* f, reg int c) 32 #else 33 int _sfflsbuf(f,c) 34 reg Sfio_t* f; /* write out the buffered content of this stream */ 35 reg int c; /* if c>=0, c is also written out */ 36 #endif 37 { 38 reg ssize_t n, w; 39 reg uchar* data; 40 uchar outc; 41 reg int local, isall; 42 int inpc = c; 43 44 SFMTXSTART(f,-1); 45 46 GETLOCAL(f,local); 47 48 for(;; f->mode &= ~SF_LOCK) 49 { /* check stream mode */ 50 if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0) 51 SFMTXRETURN(f, -1); 52 SFLOCK(f,local); 53 54 /* current data extent */ 55 n = f->next - (data = f->data); 56 57 if(n == (f->endb-data) && (f->flags&SF_STRING)) 58 { /* extend string stream buffer */ 59 (void)SFWR(f,data,1,f->disc); 60 61 /* !(f->flags&SF_STRING) is required because exception 62 handlers may turn a string stream to a file stream */ 63 if(f->next < f->endb || !(f->flags&SF_STRING) ) 64 n = f->next - (data = f->data); 65 else 66 { SFOPEN(f,local); 67 SFMTXRETURN(f, -1); 68 } 69 } 70 71 if(c >= 0) 72 { /* write into buffer */ 73 if(n < (f->endb - (data = f->data))) 74 { *f->next++ = c; 75 if(c == '\n' && 76 (f->flags&SF_LINE) && !(f->flags&SF_STRING)) 77 { c = -1; 78 n += 1; 79 } 80 else break; 81 } 82 else if(n == 0) 83 { /* unbuffered io */ 84 outc = (uchar)c; 85 data = &outc; 86 c = -1; 87 n = 1; 88 } 89 } 90 91 if(n == 0 || (f->flags&SF_STRING)) 92 break; 93 94 isall = SFISALL(f,isall); 95 if((w = SFWR(f,data,n,f->disc)) > 0) 96 { if((n -= w) > 0) /* save unwritten data, then resume */ 97 memcpy((char*)f->data,(char*)data+w,n); 98 f->next = f->data+n; 99 if(c < 0 && (!isall || n == 0)) 100 break; 101 } 102 else if(w == 0) 103 { SFOPEN(f,local); 104 SFMTXRETURN(f, -1); 105 } 106 else if(c < 0) 107 break; 108 } 109 110 SFOPEN(f,local); 111 112 if(inpc < 0) 113 inpc = f->endb-f->next; 114 115 SFMTXRETURN(f,inpc); 116 } 117