| Elliott Hughes | 0133944 | 2014-02-20 18:04:58 -0800 | [diff] [blame] | 1 | /*	$OpenBSD: refill.c,v 1.11 2009/11/09 00:18:27 kurt Exp $ */ | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 2 | /*- | 
 | 3 |  * Copyright (c) 1990, 1993 | 
 | 4 |  *	The Regents of the University of California.  All rights reserved. | 
 | 5 |  * | 
 | 6 |  * This code is derived from software contributed to Berkeley by | 
 | 7 |  * Chris Torek. | 
 | 8 |  * | 
 | 9 |  * Redistribution and use in source and binary forms, with or without | 
 | 10 |  * modification, are permitted provided that the following conditions | 
 | 11 |  * are met: | 
 | 12 |  * 1. Redistributions of source code must retain the above copyright | 
 | 13 |  *    notice, this list of conditions and the following disclaimer. | 
 | 14 |  * 2. Redistributions in binary form must reproduce the above copyright | 
 | 15 |  *    notice, this list of conditions and the following disclaimer in the | 
 | 16 |  *    documentation and/or other materials provided with the distribution. | 
 | 17 |  * 3. Neither the name of the University nor the names of its contributors | 
 | 18 |  *    may be used to endorse or promote products derived from this software | 
 | 19 |  *    without specific prior written permission. | 
 | 20 |  * | 
 | 21 |  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 
 | 22 |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
 | 23 |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
 | 24 |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 
 | 25 |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
 | 26 |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
 | 27 |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
 | 28 |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
 | 29 |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
 | 30 |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
 | 31 |  * SUCH DAMAGE. | 
 | 32 |  */ | 
 | 33 |  | 
 | 34 | #include <errno.h> | 
 | 35 | #include <stdio.h> | 
 | 36 | #include <stdlib.h> | 
 | 37 | #include "local.h" | 
 | 38 |  | 
 | 39 | static int | 
 | 40 | lflush(FILE *fp) | 
 | 41 | { | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 42 | 	if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) | 
| Ryan Prichard | c485cdb | 2019-04-30 14:47:34 -0700 | [diff] [blame] | 43 | 		return (__sflush_locked(fp));	/* ignored... */ | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 44 | 	return (0); | 
 | 45 | } | 
 | 46 |  | 
 | 47 | /* | 
 | 48 |  * Refill a stdio buffer. | 
 | 49 |  * Return EOF on eof or error, 0 otherwise. | 
 | 50 |  */ | 
 | 51 | int | 
 | 52 | __srefill(FILE *fp) | 
 | 53 | { | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 54 | 	fp->_r = 0;		/* largely a convenience for callers */ | 
 | 55 |  | 
| Elliott Hughes | a9209d7 | 2016-09-16 18:16:47 -0700 | [diff] [blame] | 56 | #if !defined(__BIONIC__) | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 57 | 	/* SysV does not make this test; take it out for compatibility */ | 
 | 58 | 	if (fp->_flags & __SEOF) | 
 | 59 | 		return (EOF); | 
| Elliott Hughes | 8ab433d | 2015-10-09 17:57:26 -0700 | [diff] [blame] | 60 | #endif | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 61 |  | 
 | 62 | 	/* if not already reading, have to be reading and writing */ | 
 | 63 | 	if ((fp->_flags & __SRD) == 0) { | 
 | 64 | 		if ((fp->_flags & __SRW) == 0) { | 
 | 65 | 			errno = EBADF; | 
 | 66 | 			fp->_flags |= __SERR; | 
 | 67 | 			return (EOF); | 
 | 68 | 		} | 
 | 69 | 		/* switch to reading */ | 
 | 70 | 		if (fp->_flags & __SWR) { | 
 | 71 | 			if (__sflush(fp)) | 
 | 72 | 				return (EOF); | 
 | 73 | 			fp->_flags &= ~__SWR; | 
 | 74 | 			fp->_w = 0; | 
 | 75 | 			fp->_lbfsize = 0; | 
 | 76 | 		} | 
 | 77 | 		fp->_flags |= __SRD; | 
 | 78 | 	} else { | 
 | 79 | 		/* | 
 | 80 | 		 * We were reading.  If there is an ungetc buffer, | 
 | 81 | 		 * we must have been reading from that.  Drop it, | 
 | 82 | 		 * restoring the previous buffer (if any).  If there | 
 | 83 | 		 * is anything in that buffer, return. | 
 | 84 | 		 */ | 
 | 85 | 		if (HASUB(fp)) { | 
 | 86 | 			FREEUB(fp); | 
 | 87 | 			if ((fp->_r = fp->_ur) != 0) { | 
 | 88 | 				fp->_p = fp->_up; | 
 | 89 | 				return (0); | 
 | 90 | 			} | 
 | 91 | 		} | 
 | 92 | 	} | 
 | 93 |  | 
 | 94 | 	if (fp->_bf._base == NULL) | 
 | 95 | 		__smakebuf(fp); | 
 | 96 |  | 
 | 97 | 	/* | 
 | 98 | 	 * Before reading from a line buffered or unbuffered file, | 
 | 99 | 	 * flush all line buffered output files, per the ANSI C | 
 | 100 | 	 * standard. | 
 | 101 | 	 */ | 
| Kenny Root | f582340 | 2011-02-12 07:13:44 -0800 | [diff] [blame] | 102 | 	if (fp->_flags & (__SLBF|__SNBF)) { | 
 | 103 | 		/* Ignore this file in _fwalk to avoid potential deadlock. */ | 
 | 104 | 		fp->_flags |= __SIGN; | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 105 | 		(void) _fwalk(lflush); | 
| Kenny Root | f582340 | 2011-02-12 07:13:44 -0800 | [diff] [blame] | 106 | 		fp->_flags &= ~__SIGN; | 
 | 107 |  | 
 | 108 | 		/* Now flush this file without locking it. */ | 
 | 109 | 		if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) | 
| Elliott Hughes | 0133944 | 2014-02-20 18:04:58 -0800 | [diff] [blame] | 110 | 			__sflush(fp); | 
| Kenny Root | f582340 | 2011-02-12 07:13:44 -0800 | [diff] [blame] | 111 | 	} | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 112 | 	fp->_p = fp->_bf._base; | 
 | 113 | 	fp->_r = (*fp->_read)(fp->_cookie, (char *)fp->_p, fp->_bf._size); | 
| The Android Open Source Project | 1dc9e47 | 2009-03-03 19:28:35 -0800 | [diff] [blame] | 114 | 	if (fp->_r <= 0) { | 
 | 115 | 		if (fp->_r == 0) | 
 | 116 | 			fp->_flags |= __SEOF; | 
 | 117 | 		else { | 
 | 118 | 			fp->_r = 0; | 
 | 119 | 			fp->_flags |= __SERR; | 
 | 120 | 		} | 
 | 121 | 		return (EOF); | 
 | 122 | 	} | 
 | 123 | 	return (0); | 
 | 124 | } |