1 /*- 2 * Copyright (c) 1990, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Chris Torek. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #if defined(LIBC_SCCS) && !defined(lint) 12 static char sccsid[] = "@(#)wbuf.c 8.1 (Berkeley) 06/04/93"; 13 #endif /* LIBC_SCCS and not lint */ 14 15 #include <stdio.h> 16 #include "local.h" 17 18 /* 19 * Write the given character into the (probably full) buffer for 20 * the given file. Flush the buffer out if it is or becomes full, 21 * or if c=='\n' and the file is line buffered. 22 */ 23 __swbuf(c, fp) 24 register int c; 25 register FILE *fp; 26 { 27 register int n; 28 29 /* 30 * In case we cannot write, or longjmp takes us out early, 31 * make sure _w is 0 (if fully- or un-buffered) or -_bf._size 32 * (if line buffered) so that we will get called again. 33 * If we did not do this, a sufficient number of putc() 34 * calls might wrap _w from negative to positive. 35 */ 36 fp->_w = fp->_lbfsize; 37 if (cantwrite(fp)) 38 return (EOF); 39 c = (unsigned char)c; 40 41 /* 42 * If it is completely full, flush it out. Then, in any case, 43 * stuff c into the buffer. If this causes the buffer to fill 44 * completely, or if c is '\n' and the file is line buffered, 45 * flush it (perhaps a second time). The second flush will always 46 * happen on unbuffered streams, where _bf._size==1; fflush() 47 * guarantees that putc() will always call wbuf() by setting _w 48 * to 0, so we need not do anything else. 49 */ 50 n = fp->_p - fp->_bf._base; 51 if (n >= fp->_bf._size) { 52 if (fflush(fp)) 53 return (EOF); 54 n = 0; 55 } 56 fp->_w--; 57 *fp->_p++ = c; 58 if (++n == fp->_bf._size || (fp->_flags & __SLBF && c == '\n')) 59 if (fflush(fp)) 60 return (EOF); 61 return (c); 62 } 63