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 | |
parent | b88da06580a22d9a1ee5a1c573c49e89207bc71b (diff) | |
download | bionic-9d3c2dd11f5e796cd814cddc5b907494f859058e.zip bionic-9d3c2dd11f5e796cd814cddc5b907494f859058e.tar.gz bionic-9d3c2dd11f5e796cd814cddc5b907494f859058e.tar.bz2 |
Switch to upstream OpenBSD fread/fvwrite.
Change-Id: I3dc11083693bc8d99edc0cbcc6f70dc9e5dc6565
-rw-r--r-- | libc/Android.mk | 4 | ||||
-rw-r--r-- | libc/stdio/fread.c | 175 | ||||
-rw-r--r-- | libc/upstream-openbsd/lib/libc/stdio/fread.c | 74 | ||||
-rw-r--r-- | libc/upstream-openbsd/lib/libc/stdio/fvwrite.c (renamed from libc/stdio/fvwrite.c) | 34 |
4 files changed, 91 insertions, 196 deletions
diff --git a/libc/Android.mk b/libc/Android.mk index 605aee5..869bdd1 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -75,8 +75,6 @@ libc_common_src_files := \ bionic/time64.c \ bionic/unlockpt.c \ stdio/findfp.c \ - stdio/fread.c \ - stdio/fvwrite.c \ stdio/snprintf.c\ stdio/sprintf.c \ stdlib/atexit.c \ @@ -363,12 +361,14 @@ libc_upstream_openbsd_src_files := \ upstream-openbsd/lib/libc/stdio/fpurge.c \ upstream-openbsd/lib/libc/stdio/fputc.c \ upstream-openbsd/lib/libc/stdio/fputs.c \ + upstream-openbsd/lib/libc/stdio/fread.c \ upstream-openbsd/lib/libc/stdio/freopen.c \ upstream-openbsd/lib/libc/stdio/fscanf.c \ upstream-openbsd/lib/libc/stdio/fseek.c \ upstream-openbsd/lib/libc/stdio/fsetpos.c \ upstream-openbsd/lib/libc/stdio/ftell.c \ upstream-openbsd/lib/libc/stdio/funopen.c \ + upstream-openbsd/lib/libc/stdio/fvwrite.c \ upstream-openbsd/lib/libc/stdio/fwalk.c \ upstream-openbsd/lib/libc/stdio/getc.c \ upstream-openbsd/lib/libc/stdio/getchar.c \ 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/upstream-openbsd/lib/libc/stdio/fread.c b/libc/upstream-openbsd/lib/libc/stdio/fread.c new file mode 100644 index 0000000..430865d --- /dev/null +++ b/libc/upstream-openbsd/lib/libc/stdio/fread.c @@ -0,0 +1,74 @@ +/* $OpenBSD: fread.c,v 1.11 2009/11/21 09:53:44 guenther 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 "local.h" + +size_t +fread(void *buf, size_t size, size_t count, FILE *fp) +{ + size_t resid; + char *p; + int r; + size_t total; + + /* + * ANSI and SUSv2 require a return value of 0 if size or count are 0. + */ + if ((resid = count * size) == 0) + return (0); + FLOCKFILE(fp); + _SET_ORIENTATION(fp, -1); + if (fp->_r < 0) + fp->_r = 0; + total = resid; + p = buf; + while (resid > (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/upstream-openbsd/lib/libc/stdio/fvwrite.c index 39d0604..1088991 100644 --- a/libc/stdio/fvwrite.c +++ b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fvwrite.c,v 1.14 2005/08/08 08:05:36 espie Exp $ */ +/* $OpenBSD: fvwrite.c,v 1.17 2009/11/09 00:18:27 kurt Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -44,11 +44,11 @@ * 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 +int __sfvwrite(FILE *fp, struct __suio *uio) { size_t len; - const char *p; + char *p; struct __siov *iov; int w, s; char *nl; @@ -82,11 +82,7 @@ __sfvwrite(FILE *fp, struct __suio *uio) */ 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 + w = (*fp->_write)(fp->_cookie, p, MIN(len, BUFSIZ)); if (w <= 0) goto err; p += w; @@ -107,7 +103,7 @@ __sfvwrite(FILE *fp, struct __suio *uio) do { GETIOV(;); if ((fp->_flags & (__SALC | __SSTR)) == - (__SALC | __SSTR) && fp->_w < (int)len) { + (__SALC | __SSTR) && fp->_w < len) { size_t blen = fp->_p - fp->_bf._base; unsigned char *_base; int _size; @@ -116,7 +112,7 @@ __sfvwrite(FILE *fp, struct __suio *uio) _size = fp->_bf._size; do { _size = (_size << 1) + 1; - } while (_size < (int)(blen + len)); + } while (_size < blen + len); _base = realloc(fp->_bf._base, _size + 1); if (_base == NULL) goto err; @@ -127,20 +123,20 @@ __sfvwrite(FILE *fp, struct __suio *uio) } w = fp->_w; if (fp->_flags & __SSTR) { - if ((int)len < w) + if (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) { + } else if (fp->_p > fp->_bf._base && len > w) { /* fill and flush */ COPY(w); /* fp->_w -= w; */ /* unneeded */ fp->_p += w; - if (fflush(fp)) + if (__sflush(fp)) goto err; - } else if ((int)len >= (w = fp->_bf._size)) { + } else if (len >= (w = fp->_bf._size)) { /* write directly */ w = (*fp->_write)(fp->_cookie, p, w); if (w <= 0) @@ -169,21 +165,21 @@ __sfvwrite(FILE *fp, struct __suio *uio) GETIOV(nlknown = 0); if (!nlknown) { nl = memchr((void *)p, '\n', len); - nldist = nl ? nl + 1 - p : (int)len + 1; + nldist = nl ? nl + 1 - p : len + 1; nlknown = 1; } - s = MIN((int)len, nldist); + s = MIN(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)) + if (__sflush(fp)) goto err; } else if (s >= (w = fp->_bf._size)) { w = (*fp->_write)(fp->_cookie, p, w); if (w <= 0) - goto err; + goto err; } else { w = s; COPY(w); @@ -192,7 +188,7 @@ __sfvwrite(FILE *fp, struct __suio *uio) } if ((nldist -= w) == 0) { /* copied the newline: flush and forget */ - if (fflush(fp)) + if (__sflush(fp)) goto err; nlknown = 0; } |