14Srgrimes/*- 24Srgrimes * Copyright (c) 1990, 1993 34Srgrimes * The Regents of the University of California. All rights reserved. 44Srgrimes * 54Srgrimes * This code is derived from software contributed to Berkeley by 64Srgrimes * Chris Torek. 74Srgrimes * 84Srgrimes * Redistribution and use in source and binary forms, with or without 94Srgrimes * modification, are permitted provided that the following conditions 104Srgrimes * are met: 114Srgrimes * 1. Redistributions of source code must retain the above copyright 124Srgrimes * notice, this list of conditions and the following disclaimer. 134Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 144Srgrimes * notice, this list of conditions and the following disclaimer in the 154Srgrimes * documentation and/or other materials provided with the distribution. 164Srgrimes * 3. Neither the name of the University nor the names of its contributors 174Srgrimes * may be used to endorse or promote products derived from this software 184Srgrimes * without specific prior written permission. 194Srgrimes * 204Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 214Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 224Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 234Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 244Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 254Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 264Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 274Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 284Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 294Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 304Srgrimes * SUCH DAMAGE. 314Srgrimes */ 324Srgrimes 334Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 344Srgrimesstatic char sccsid[] = "@(#)stdio.c 8.1 (Berkeley) 6/4/93"; 354Srgrimes#endif /* LIBC_SCCS and not lint */ 36619Srgrimes#include <sys/cdefs.h> 3719173Sbde__FBSDID("$FreeBSD$"); 384Srgrimes 394Srgrimes#include "namespace.h" 403185Ssos#include <errno.h> 4119173Sbde#include <fcntl.h> 4219173Sbde#include <limits.h> 4319173Sbde#include <stdio.h> 4419173Sbde#include <stdlib.h> 453185Ssos#include <unistd.h> 463185Ssos#include "un-namespace.h" 473185Ssos#include "local.h" 483185Ssos 492913Sache/* 502913Sache * Small standard I/O/seek/close functions. 5116299Spst */ 5218842Sbdeint 5313228Swollman__sread(void *cookie, char *buf, int n) 542056Swollman{ 552056Swollman FILE *fp = cookie; 562056Swollman 572056Swollman return(_read(fp->_file, buf, (size_t)n)); 5815508Sbde} 5915508Sbde 604180Sbdeint 6115508Sbde__swrite(void *cookie, char const *buf, int n) 6215508Sbde{ 6315508Sbde FILE *fp = cookie; 6415508Sbde 652056Swollman return (_write(fp->_file, buf, (size_t)n)); 6615508Sbde} 672056Swollman 682056Swollmanfpos_t 697090Sbde__sseek(void *cookie, fpos_t offset, int whence) 702056Swollman{ 712056Swollman FILE *fp = cookie; 724Srgrimes 732873Sbde return (lseek(fp->_file, (off_t)offset, whence)); 742873Sbde} 752873Sbde 762873Sbdeint 772873Sbde__sclose(void *cookie) 782913Sache{ 792873Sbde 8015508Sbde return (_close(((FILE *)cookie)->_file)); 814Srgrimes} 824180Sbde 834180Sbde/* 844180Sbde * Higher level wrappers. 854180Sbde */ 864180Sbdeint 874180Sbde_sread(FILE *fp, char *buf, int n) 884180Sbde{ 894180Sbde int ret; 904180Sbde 914180Sbde ret = (*fp->_read)(fp->_cookie, buf, n); 9217236Sjoerg if (ret > 0) { 9317231Sjoerg if (fp->_flags & __SOFF) { 9417231Sjoerg if (fp->_offset <= OFF_MAX - ret) 9517231Sjoerg fp->_offset += ret; 9617231Sjoerg else 974180Sbde fp->_flags &= ~__SOFF; 9817231Sjoerg } 994180Sbde } else if (ret < 0) 10015045Sache fp->_flags &= ~__SOFF; 10115045Sache return (ret); 1028448Sbde} 10313000Sdg 10419173Sbdeint 10517353Sbde_swrite(FILE *fp, char const *buf, int n) 10617353Sbde{ 10717353Sbde int ret; 1082017Swollman int serrno; 10915345Snate 1105291Sbde if (fp->_flags & __SAPP) { 11117236Sjoerg serrno = errno; 11217236Sjoerg if (_sseek(fp, (fpos_t)0, SEEK_END) == -1 && 11317236Sjoerg (fp->_flags & __SOPT)) 11417236Sjoerg return (-1); 11517236Sjoerg errno = serrno; 11619173Sbde } 11719173Sbde ret = (*fp->_write)(fp->_cookie, buf, n); 11819173Sbde /* __SOFF removed even on success in case O_APPEND mode is set. */ 11919173Sbde if (ret >= 0) { 1201390Ssos if ((fp->_flags & (__SAPP|__SOFF)) == (__SAPP|__SOFF) && 1214180Sbde fp->_offset <= OFF_MAX - ret) 1225291Sbde fp->_offset += ret; 1234180Sbde else 12419173Sbde fp->_flags &= ~__SOFF; 1254180Sbde 1264180Sbde } else if (ret < 0) 1274180Sbde fp->_flags &= ~__SOFF; 1284180Sbde return (ret); 1294180Sbde} 1304180Sbde 13119173Sbdefpos_t 13219173Sbde_sseek(FILE *fp, fpos_t offset, int whence) 1334180Sbde{ 13415345Snate fpos_t ret; 13517231Sjoerg int serrno, errret; 13617231Sjoerg 13717236Sjoerg serrno = errno; 13817236Sjoerg errno = 0; 13917236Sjoerg ret = (*fp->_seek)(fp->_cookie, offset, whence); 14017236Sjoerg errret = errno; 14117231Sjoerg if (errno == 0) 14217231Sjoerg errno = serrno; 14317231Sjoerg /* 14419173Sbde * Disallow negative seeks per POSIX. 1454180Sbde * It is needed here to help upper level caller 14617353Sbde * in the cases it can't detect. 14717353Sbde */ 14817353Sbde if (ret < 0) { 14917353Sbde if (errret == 0) { 15012724Sphk if (offset != 0 || whence != SEEK_CUR) { 1513185Ssos if (HASUB(fp)) 1522074Swollman FREEUB(fp); 1531549Srgrimes fp->_p = fp->_bf._base; 1541442Ssos fp->_r = 0; 15517236Sjoerg fp->_flags &= ~__SEOF; 15617231Sjoerg } 1578448Sbde fp->_flags |= __SERR; 1581442Ssos errno = EINVAL; 15917236Sjoerg } else if (errret == ESPIPE) 16017231Sjoerg fp->_flags &= ~__SAPP; 1614180Sbde fp->_flags &= ~__SOFF; 1624180Sbde ret = -1; 1631549Srgrimes } else if (fp->_flags & __SOPT) { 1648448Sbde fp->_flags |= __SOFF; 1654180Sbde fp->_offset = ret; 1661390Ssos } 1671442Ssos return (ret); 16817236Sjoerg} 16917231Sjoerg