diff options
author | Elliott Hughes <enh@google.com> | 2014-04-18 13:13:04 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2014-04-18 13:13:04 -0700 |
commit | 9d3c2dd11f5e796cd814cddc5b907494f859058e (patch) | |
tree | d125563b7dcadf16b9768c1cc88c8b5bf21b3489 /libc/stdio | |
parent | b88da06580a22d9a1ee5a1c573c49e89207bc71b (diff) | |
download | bionic-9d3c2dd11f5e796cd814cddc5b907494f859058e.zip bionic-9d3c2dd11f5e796cd814cddc5b907494f859058e.tar.gz bionic-9d3c2dd11f5e796cd814cddc5b907494f859058e.tar.bz2 |
Switch to upstream OpenBSD fread/fvwrite.
Change-Id: I3dc11083693bc8d99edc0cbcc6f70dc9e5dc6565
Diffstat (limited to 'libc/stdio')
-rw-r--r-- | libc/stdio/fread.c | 175 | ||||
-rw-r--r-- | libc/stdio/fvwrite.c | 208 |
2 files changed, 0 insertions, 383 deletions
diff --git a/libc/stdio/fread.c b/libc/stdio/fread.c deleted file mode 100644 index 649db17..0000000 --- a/libc/stdio/fread.c +++ /dev/null @@ -1,175 +0,0 @@ -/* $OpenBSD: fread.c,v 1.6 2005/08/08 08:05:36 espie Exp $ */ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include "local.h" - -static int -lflush(FILE *fp) -{ - if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) - return (__sflush_locked(fp)); - return (0); -} - -size_t -fread(void *buf, size_t size, size_t count, FILE *fp) -{ - size_t resid; - char *p; - int r; - size_t total; - - /* - * The ANSI standard requires a return value of 0 for a count - * or a size of 0. Peculiarily, it imposes no such requirements - * on fwrite; it only requires fread to be broken. - */ - if ((resid = count * size) == 0) - return (0); - FLOCKFILE(fp); - if (fp->_r < 0) - fp->_r = 0; - total = resid; - p = buf; - -#if 1 /* BIONIC: optimize unbuffered reads */ - if (fp->_flags & __SNBF && fp->_ur == 0) - { - /* the following comes mainly from __srefill(), with slight - * modifications - */ - - /* make sure stdio is set up */ - if (!__sdidinit) - __sinit(); - - fp->_r = 0; /* largely a convenience for callers */ - - /* SysV does not make this test; take it out for compatibility */ - if (fp->_flags & __SEOF) { - FUNLOCKFILE(fp); - return (EOF); - } - - /* if not already reading, have to be reading and writing */ - if ((fp->_flags & __SRD) == 0) { - if ((fp->_flags & __SRW) == 0) { - fp->_flags |= __SERR; - FUNLOCKFILE(fp); - errno = EBADF; - return (EOF); - } - /* switch to reading */ - if (fp->_flags & __SWR) { - if (__sflush(fp)) { - FUNLOCKFILE(fp); - return (EOF); - } - fp->_flags &= ~__SWR; - fp->_w = 0; - fp->_lbfsize = 0; - } - fp->_flags |= __SRD; - } else { - /* - * We were reading. If there is an ungetc buffer, - * we must have been reading from that. Drop it, - * restoring the previous buffer (if any). If there - * is anything in that buffer, return. - */ - if (HASUB(fp)) { - FREEUB(fp); - } - } - - /* - * Before reading from a line buffered or unbuffered file, - * flush all line buffered output files, per the ANSI C - * standard. - */ - - if (fp->_flags & (__SLBF|__SNBF)) { - /* Ignore this file in _fwalk to deadlock. */ - fp->_flags |= __SIGN; - (void) _fwalk(lflush); - fp->_flags &= ~__SIGN; - - /* Now flush this file without locking it. */ - if ((fp->_flags & (__SLBF|__SWR)) == (__SLBF|__SWR)) - __sflush(fp); - } - - while (resid > 0) { - int len = (*fp->_read)(fp->_cookie, p, resid ); - fp->_flags &= ~__SMOD; - if (len <= 0) { - if (len == 0) - fp->_flags |= __SEOF; - else { - fp->_flags |= __SERR; - } - FUNLOCKFILE(fp); - return ((total - resid) / size); - } - p += len; - resid -= len; - } - FUNLOCKFILE(fp); - return (count); - } - else -#endif - { - while (resid > (size_t)(r = fp->_r)) { - (void)memcpy((void *)p, (void *)fp->_p, (size_t)r); - fp->_p += r; - /* fp->_r = 0 ... done in __srefill */ - p += r; - resid -= r; - if (__srefill(fp)) { - /* no more input: return partial result */ - FUNLOCKFILE(fp); - return ((total - resid) / size); - } - } - } - - (void)memcpy((void *)p, (void *)fp->_p, resid); - fp->_r -= resid; - fp->_p += resid; - FUNLOCKFILE(fp); - return (count); -} diff --git a/libc/stdio/fvwrite.c b/libc/stdio/fvwrite.c deleted file mode 100644 index 39d0604..0000000 --- a/libc/stdio/fvwrite.c +++ /dev/null @@ -1,208 +0,0 @@ -/* $OpenBSD: fvwrite.c,v 1.14 2005/08/08 08:05:36 espie Exp $ */ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include "local.h" -#include "fvwrite.h" - -/* - * Write some memory regions. Return zero on success, EOF on error. - * - * This routine is large and unsightly, but most of the ugliness due - * to the three different kinds of output buffering is handled here. - */ -__LIBC_HIDDEN__ int -__sfvwrite(FILE *fp, struct __suio *uio) -{ - size_t len; - const char *p; - struct __siov *iov; - int w, s; - char *nl; - int nlknown, nldist; - - if ((len = uio->uio_resid) == 0) - return (0); - /* make sure we can write */ - if (cantwrite(fp)) { - errno = EBADF; - return (EOF); - } - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n)) - - iov = uio->uio_iov; - p = iov->iov_base; - len = iov->iov_len; - iov++; -#define GETIOV(extra_work) \ - while (len == 0) { \ - extra_work; \ - p = iov->iov_base; \ - len = iov->iov_len; \ - iov++; \ - } - if (fp->_flags & __SNBF) { - /* - * Unbuffered: write up to BUFSIZ bytes at a time. - */ - do { - GETIOV(;); -#if 1 /* BIONIC: don't limit to 1KB writes */ - w = (*fp->_write)(fp->_cookie, p, len); -#else - w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ2)); -#endif - if (w <= 0) - goto err; - p += w; - len -= w; - } while ((uio->uio_resid -= w) != 0); - } else if ((fp->_flags & __SLBF) == 0) { - /* - * Fully buffered: fill partially full buffer, if any, - * and then flush. If there is no partial buffer, write - * one _bf._size byte chunk directly (without copying). - * - * String output is a special case: write as many bytes - * as fit, but pretend we wrote everything. This makes - * snprintf() return the number of bytes needed, rather - * than the number used, and avoids its write function - * (so that the write function can be invalid). - */ - do { - GETIOV(;); - if ((fp->_flags & (__SALC | __SSTR)) == - (__SALC | __SSTR) && fp->_w < (int)len) { - size_t blen = fp->_p - fp->_bf._base; - unsigned char *_base; - int _size; - - /* Allocate space exponentially. */ - _size = fp->_bf._size; - do { - _size = (_size << 1) + 1; - } while (_size < (int)(blen + len)); - _base = realloc(fp->_bf._base, _size + 1); - if (_base == NULL) - goto err; - fp->_w += _size - fp->_bf._size; - fp->_bf._base = _base; - fp->_bf._size = _size; - fp->_p = _base + blen; - } - w = fp->_w; - if (fp->_flags & __SSTR) { - if ((int)len < w) - w = len; - COPY(w); /* copy MIN(fp->_w,len), */ - fp->_w -= w; - fp->_p += w; - w = len; /* but pretend copied all */ - } else if (fp->_p > fp->_bf._base && (int)len > w) { - /* fill and flush */ - COPY(w); - /* fp->_w -= w; */ /* unneeded */ - fp->_p += w; - if (fflush(fp)) - goto err; - } else if ((int)len >= (w = fp->_bf._size)) { - /* write directly */ - w = (*fp->_write)(fp->_cookie, p, w); - if (w <= 0) - goto err; - } else { - /* fill and done */ - w = len; - COPY(w); - fp->_w -= w; - fp->_p += w; - } - p += w; - len -= w; - } while ((uio->uio_resid -= w) != 0); - } else { - /* - * Line buffered: like fully buffered, but we - * must check for newlines. Compute the distance - * to the first newline (including the newline), - * or `infinity' if there is none, then pretend - * that the amount to write is MIN(len,nldist). - */ - nlknown = 0; - nldist = 0; /* XXX just to keep gcc happy */ - do { - GETIOV(nlknown = 0); - if (!nlknown) { - nl = memchr((void *)p, '\n', len); - nldist = nl ? nl + 1 - p : (int)len + 1; - nlknown = 1; - } - s = MIN((int)len, nldist); - w = fp->_w + fp->_bf._size; - if (fp->_p > fp->_bf._base && s > w) { - COPY(w); - /* fp->_w -= w; */ - fp->_p += w; - if (fflush(fp)) - goto err; - } else if (s >= (w = fp->_bf._size)) { - w = (*fp->_write)(fp->_cookie, p, w); - if (w <= 0) - goto err; - } else { - w = s; - COPY(w); - fp->_w -= w; - fp->_p += w; - } - if ((nldist -= w) == 0) { - /* copied the newline: flush and forget */ - if (fflush(fp)) - goto err; - nlknown = 0; - } - p += w; - len -= w; - } while ((uio->uio_resid -= w) != 0); - } - return (0); - -err: - fp->_flags |= __SERR; - return (EOF); -} |