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