/***********************************************************************1* *2* This software is part of the ast package *3* Copyright (c) 1985-2011 AT&T Intellectual Property *4* and is licensed under the *5* Eclipse Public License, Version 1.0 *6* by AT&T Intellectual Property *7* *8* A copy of the License is available at *9* http://www.eclipse.org/org/documents/epl-v10.html *10* (with md5 checksum b35adb5213ca9657e911e9befb180842) *11* *12* Information and Software Systems Research *13* AT&T Research *14* Florham Park NJ *15* *16* Glenn Fowler <[email protected]> *17* David Korn <[email protected]> *18* Phong Vo <[email protected]> *19* *20***********************************************************************/21#include "sfhdr.h"2223/* Write a buffer out to a file descriptor or24** extending a buffer for a SF_STRING stream.25**26** Written by Kiem-Phong Vo27*/2829#if __STD_C30int _sfflsbuf(Sfio_t* f, int c)31#else32int _sfflsbuf(f,c)33Sfio_t* f; /* write out the buffered content of this stream */34int c; /* if c>=0, c is also written out */35#endif36{37ssize_t n, w, written;38uchar* data;39uchar outc;40int local, isall;41int inpc = c;42SFMTXDECL(f); /* declare a local stream variable for multithreading */4344SFMTXENTER(f,-1);4546GETLOCAL(f,local);4748for(written = 0;; f->mode &= ~SF_LOCK)49{ /* check stream mode */50if(SFMODE(f,local) != SF_WRITE && _sfmode(f,SF_WRITE,local) < 0)51SFMTXRETURN(f, -1);52SFLOCK(f,local);5354/* current data extent */55n = f->next - (data = f->data);5657if(n == (f->endb-data) && (f->flags&SF_STRING))58{ /* call sfwr() to extend string buffer and process events */59w = ((f->bits&SF_PUTR) && f->val > 0) ? f->val : 1;60(void)SFWR(f, data, w, f->disc);6162/* !(f->flags&SF_STRING) is required because exception63handlers may turn a string stream to a file stream */64if(f->next < f->endb || !(f->flags&SF_STRING) )65n = f->next - (data = f->data);66else67{ SFOPEN(f,local);68SFMTXRETURN(f, -1);69}70}7172if(c >= 0)73{ /* write into buffer */74if(n < (f->endb - (data = f->data)))75{ *f->next++ = c;76if(c == '\n' &&77(f->flags&SF_LINE) && !(f->flags&SF_STRING))78{ c = -1;79n += 1;80}81else break;82}83else if(n == 0)84{ /* unbuffered io */85outc = (uchar)c;86data = &outc;87c = -1;88n = 1;89}90}9192if(n == 0 || (f->flags&SF_STRING))93break;9495isall = SFISALL(f,isall);96if((w = SFWR(f,data,n,f->disc)) > 0)97{ if((n -= w) > 0) /* save unwritten data, then resume */98memmove((char*)f->data,(char*)data+w,n);99written += w;100f->next = f->data+n;101if(c < 0 && (!isall || n == 0))102break;103}104else if(w == 0)105{ if(written > 0) /* some buffer was cleared */106break; /* do normal exit below */107else /* nothing was done, returning failure */108{ SFOPEN(f,local);109SFMTXRETURN(f, -1);110}111}112else /* w < 0 means SF_EDISC or SF_ESTACK in sfwr() */113{ if(c < 0) /* back to the calling write operation */114break;115else continue; /* try again to write out c */116}117}118119SFOPEN(f,local);120121if(inpc < 0)122inpc = f->endb-f->next;123124SFMTXRETURN(f,inpc);125}126127128