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 ident "%Z%%M% %I% %E% SMI" 31 32 33 #pragma weak __filbuf = _filbuf 34 35 #include "lint.h" 36 #include "file64.h" 37 #include <stdio.h> 38 #include <errno.h> 39 #include <sys/types.h> 40 #include <unistd.h> 41 #include "stdiom.h" 42 43 44 static int 45 _xpg4_check(void) 46 { 47 extern int __xpg4; 48 49 return (__xpg4); 50 } 51 52 /* fill buffer, return first character or EOF */ 53 int 54 _filbuf(FILE *iop) 55 { 56 ssize_t res; 57 size_t nbyte; 58 Uchar *endbuf; 59 #ifdef _LP64 60 unsigned int flag; 61 #else 62 unsigned char flag; 63 #endif 64 65 if (!(iop->_flag & _IOREAD)) /* check, correct permissions */ 66 { 67 if (iop->_flag & _IORW) 68 iop->_flag |= _IOREAD; /* change direction */ 69 /* to read - fseek */ 70 else { 71 errno = EBADF; 72 return (EOF); 73 } 74 } 75 76 if (iop->_base == 0) { 77 if ((endbuf = _findbuf(iop)) == 0) /* get buffer and */ 78 /* end_of_buffer */ 79 return (EOF); 80 } 81 else 82 endbuf = _bufend(iop); 83 84 /* 85 * Flush all line-buffered streams before we 86 * read no-buffered or line-buffered input. 87 */ 88 if (iop->_flag & (_IONBF | _IOLBF)) 89 _flushlbf(); 90 /* 91 * Changed the get family fns in Solaris 10 to comply with the 92 * 1990 C Standard and standards based upon it. If the 93 * end-of-file indicator for the stream is set, or if the stream 94 * is at end-of-file, the function will return EOF, and the file 95 * position indicator for the stream will not be advanced. 96 * Additional bytes appended to the file do not clear the EOF 97 * indicator. 98 */ 99 if ((flag = iop->_flag) & _IOEOF) { 100 if (_xpg4_check()) { 101 /* 102 * A previous read() has returned 0 (below), 103 * therefore iop->_cnt was set to 0, and the EOF 104 * indicator was set before returning EOF. Reset 105 * iop->_cnt to 0; it has likely been changed by 106 * a function such as getc(). 107 */ 108 iop->_cnt = 0; 109 return (EOF); 110 } 111 } 112 /* 113 * Fill buffer or read 1 byte for unbuffered, handling any errors. 114 */ 115 iop->_ptr = iop->_base; 116 if (flag & _IONBF) 117 nbyte = 1; 118 else 119 nbyte = endbuf - iop->_base; 120 if ((res = read(GET_FD(iop), (char *)iop->_base, nbyte)) > 0) { 121 iop->_cnt = res - 1; 122 return (*iop->_ptr++); 123 } 124 125 iop->_cnt = 0; 126 if (res == 0) 127 iop->_flag |= _IOEOF; 128 else if (!cancel_active()) 129 iop->_flag |= _IOERR; 130 return (EOF); 131 } 132