11573Srgrimes/*- 21573Srgrimes * Copyright (c) 1990, 1993 31573Srgrimes * The Regents of the University of California. All rights reserved. 41573Srgrimes * 51573Srgrimes * This code is derived from software contributed to Berkeley by 61573Srgrimes * Chris Torek. 71573Srgrimes * 81573Srgrimes * Redistribution and use in source and binary forms, with or without 91573Srgrimes * modification, are permitted provided that the following conditions 101573Srgrimes * are met: 111573Srgrimes * 1. Redistributions of source code must retain the above copyright 121573Srgrimes * notice, this list of conditions and the following disclaimer. 131573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141573Srgrimes * notice, this list of conditions and the following disclaimer in the 151573Srgrimes * documentation and/or other materials provided with the distribution. 16249808Semaste * 3. Neither the name of the University nor the names of its contributors 171573Srgrimes * may be used to endorse or promote products derived from this software 181573Srgrimes * without specific prior written permission. 191573Srgrimes * 201573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231573Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301573Srgrimes * SUCH DAMAGE. 311573Srgrimes */ 321573Srgrimes 331573Srgrimes#if defined(LIBC_SCCS) && !defined(lint) 341573Srgrimesstatic char sccsid[] = "@(#)stdio.c 8.1 (Berkeley) 6/4/93"; 351573Srgrimes#endif /* LIBC_SCCS and not lint */ 3692986Sobrien#include <sys/cdefs.h> 3792986Sobrien__FBSDID("$FreeBSD: stable/10/lib/libc/stdio/stdio.c 321074 2017-07-17 14:09:34Z kib $"); 381573Srgrimes 3971579Sdeischen#include "namespace.h" 4081666Sache#include <errno.h> 411573Srgrimes#include <fcntl.h> 4282838Sache#include <limits.h> 4382653Sache#include <stdio.h> 44108866Stjr#include <stdlib.h> 451573Srgrimes#include <unistd.h> 4671579Sdeischen#include "un-namespace.h" 471573Srgrimes#include "local.h" 481573Srgrimes 491573Srgrimes/* 501573Srgrimes * Small standard I/O/seek/close functions. 511573Srgrimes */ 5216586Sjraynardint 53249810Semaste__sread(void *cookie, char *buf, int n) 541573Srgrimes{ 5592889Sobrien FILE *fp = cookie; 568870Srgrimes 5782807Sache return(_read(fp->_file, buf, (size_t)n)); 581573Srgrimes} 591573Srgrimes 6016586Sjraynardint 61249810Semaste__swrite(void *cookie, char const *buf, int n) 621573Srgrimes{ 6392889Sobrien FILE *fp = cookie; 641573Srgrimes 6556698Sjasone return (_write(fp->_file, buf, (size_t)n)); 661573Srgrimes} 671573Srgrimes 681573Srgrimesfpos_t 69249810Semaste__sseek(void *cookie, fpos_t offset, int whence) 701573Srgrimes{ 7192889Sobrien FILE *fp = cookie; 728870Srgrimes 7382807Sache return (lseek(fp->_file, (off_t)offset, whence)); 741573Srgrimes} 751573Srgrimes 7616586Sjraynardint 77249810Semaste__sclose(void *cookie) 781573Srgrimes{ 791573Srgrimes 8056698Sjasone return (_close(((FILE *)cookie)->_file)); 811573Srgrimes} 8282838Sache 8382838Sache/* 8482838Sache * Higher level wrappers. 8582838Sache */ 8682838Sacheint 87249810Semaste_sread(FILE *fp, char *buf, int n) 8882838Sache{ 8982838Sache int ret; 9082838Sache 9182838Sache ret = (*fp->_read)(fp->_cookie, buf, n); 9282838Sache if (ret > 0) { 9382838Sache if (fp->_flags & __SOFF) { 9482838Sache if (fp->_offset <= OFF_MAX - ret) 9582838Sache fp->_offset += ret; 9682838Sache else 9782838Sache fp->_flags &= ~__SOFF; 9882838Sache } 9982838Sache } else if (ret < 0) 10082838Sache fp->_flags &= ~__SOFF; 10182838Sache return (ret); 10282838Sache} 10382838Sache 10482838Sacheint 105249810Semaste_swrite(FILE *fp, char const *buf, int n) 10682838Sache{ 10782838Sache int ret; 10883211Sache int serrno; 10982838Sache 11083211Sache if (fp->_flags & __SAPP) { 11183211Sache serrno = errno; 11283211Sache if (_sseek(fp, (fpos_t)0, SEEK_END) == -1 && 11383211Sache (fp->_flags & __SOPT)) 11483211Sache return (-1); 11583211Sache errno = serrno; 11683211Sache } 11782838Sache ret = (*fp->_write)(fp->_cookie, buf, n); 11882838Sache /* __SOFF removed even on success in case O_APPEND mode is set. */ 11982838Sache if (ret >= 0) { 120290544Sache if ((fp->_flags & __SOFF) && !(fp->_flags2 & __S2OAP) && 12182838Sache fp->_offset <= OFF_MAX - ret) 12282838Sache fp->_offset += ret; 12382838Sache else 12482838Sache fp->_flags &= ~__SOFF; 12582838Sache 12682838Sache } else if (ret < 0) 12782838Sache fp->_flags &= ~__SOFF; 12882838Sache return (ret); 12982838Sache} 13082838Sache 13182838Sachefpos_t 132249810Semaste_sseek(FILE *fp, fpos_t offset, int whence) 13382838Sache{ 13482838Sache fpos_t ret; 13582838Sache int serrno, errret; 13682838Sache 13782838Sache serrno = errno; 13882838Sache errno = 0; 13982838Sache ret = (*fp->_seek)(fp->_cookie, offset, whence); 14082838Sache errret = errno; 14182838Sache if (errno == 0) 14282838Sache errno = serrno; 14382838Sache /* 14482838Sache * Disallow negative seeks per POSIX. 14582838Sache * It is needed here to help upper level caller 14682838Sache * in the cases it can't detect. 14782838Sache */ 14882838Sache if (ret < 0) { 14982838Sache if (errret == 0) { 15085418Sache if (offset != 0 || whence != SEEK_CUR) { 15185418Sache if (HASUB(fp)) 15285418Sache FREEUB(fp); 15385418Sache fp->_p = fp->_bf._base; 15485418Sache fp->_r = 0; 15585418Sache fp->_flags &= ~__SEOF; 15685418Sache } 15782838Sache fp->_flags |= __SERR; 15882838Sache errno = EINVAL; 15983211Sache } else if (errret == ESPIPE) 16083211Sache fp->_flags &= ~__SAPP; 16182838Sache fp->_flags &= ~__SOFF; 16282838Sache ret = -1; 16382838Sache } else if (fp->_flags & __SOPT) { 16482838Sache fp->_flags |= __SOFF; 16582838Sache fp->_offset = ret; 16682838Sache } 16782838Sache return (ret); 16882838Sache} 169321074Skib 170321074Skibvoid 171321074Skib__stdio_cancel_cleanup(void * arg) 172321074Skib{ 173321074Skib 174321074Skib if (arg != NULL) 175321074Skib _funlockfile((FILE *)arg); 176321074Skib} 177