1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1988 AT&T */ 28 /* All Rights Reserved */ 29 30 #pragma weak __filbuf = _filbuf 31 32 #include "lint.h" 33 #include "file64.h" 34 #include <stdio.h> 35 #include <errno.h> 36 #include <sys/types.h> 37 #include <unistd.h> 38 #include "stdiom.h" 39 40 41 static int 42 _xpg4_check(void) 43 { 44 extern int __xpg4; 45 46 return (__xpg4); 47 } 48 49 /* fill buffer, return first character or EOF */ 50 int 51 _filbuf(FILE *iop) 52 { 53 ssize_t res; 54 size_t nbyte; 55 Uchar *endbuf; 56 #ifdef _LP64 57 unsigned int flag; 58 #else 59 unsigned char flag; 60 #endif 61 62 if (!(iop->_flag & _IOREAD)) { /* check, correct permissions */ 63 if (iop->_flag & _IORW) { 64 iop->_flag |= _IOREAD; /* change direction */ 65 /* to read - fseek */ 66 } else { 67 errno = EBADF; 68 return (EOF); 69 } 70 } 71 72 if (iop->_base == 0) { 73 /* Get the buffer and end of buffer */ 74 if ((endbuf = _findbuf(iop)) == 0) { 75 return (EOF); 76 } 77 } else { 78 endbuf = _bufend(iop); 79 } 80 81 /* 82 * Flush all line-buffered streams before we 83 * read no-buffered or line-buffered input. 84 */ 85 if (iop->_flag & (_IONBF | _IOLBF)) 86 _flushlbf(); 87 /* 88 * Changed the get family fns in Solaris 10 to comply with the 89 * 1990 C Standard and standards based upon it. If the 90 * end-of-file indicator for the stream is set, or if the stream 91 * is at end-of-file, the function will return EOF, and the file 92 * position indicator for the stream will not be advanced. 93 * Additional bytes appended to the file do not clear the EOF 94 * indicator. 95 */ 96 if ((flag = iop->_flag) & _IOEOF) { 97 if (_xpg4_check()) { 98 /* 99 * A previous read() has returned 0 (below), 100 * therefore iop->_cnt was set to 0, and the EOF 101 * indicator was set before returning EOF. Reset 102 * iop->_cnt to 0; it has likely been changed by 103 * a function such as getc(). 104 */ 105 iop->_cnt = 0; 106 return (EOF); 107 } 108 } 109 110 /* 111 * Fill buffer or read 1 byte for unbuffered, handling any errors. 112 */ 113 iop->_ptr = iop->_base; 114 if (flag & _IONBF) 115 nbyte = 1; 116 else 117 nbyte = endbuf - iop->_base; 118 if ((res = _xread(iop, (char *)iop->_base, nbyte)) > 0) { 119 iop->_cnt = res - 1; 120 return (*iop->_ptr++); 121 } 122 123 iop->_cnt = 0; 124 if (res == 0) 125 iop->_flag |= _IOEOF; 126 else if (!cancel_active()) 127 iop->_flag |= _IOERR; 128 return (EOF); 129 } 130