diff --git a/libc/Android.mk b/libc/Android.mk index ff21d6af9..9b71f6a57 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -223,7 +223,6 @@ libc_upstream_freebsd_src_files := \ upstream-freebsd/lib/libc/stdio/fclose.c \ upstream-freebsd/lib/libc/stdio/flags.c \ upstream-freebsd/lib/libc/stdio/fopen.c \ - upstream-freebsd/lib/libc/stdio/fwrite.c \ upstream-freebsd/lib/libc/stdio/makebuf.c \ upstream-freebsd/lib/libc/stdio/mktemp.c \ upstream-freebsd/lib/libc/stdio/setvbuf.c \ @@ -388,6 +387,7 @@ libc_upstream_openbsd_src_files := \ upstream-openbsd/lib/libc/stdio/fwalk.c \ upstream-openbsd/lib/libc/stdio/fwide.c \ upstream-openbsd/lib/libc/stdio/fwprintf.c \ + upstream-openbsd/lib/libc/stdio/fwrite.c \ upstream-openbsd/lib/libc/stdio/fwscanf.c \ upstream-openbsd/lib/libc/stdio/getc.c \ upstream-openbsd/lib/libc/stdio/getchar.c \ diff --git a/libc/stdio/fvwrite.h b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h similarity index 93% rename from libc/stdio/fvwrite.h rename to libc/upstream-openbsd/lib/libc/stdio/fvwrite.h index 96f65de13..d3a309b29 100644 --- a/libc/stdio/fvwrite.h +++ b/libc/upstream-openbsd/lib/libc/stdio/fvwrite.h @@ -1,4 +1,4 @@ -/* $OpenBSD: fvwrite.h,v 1.5 2003/06/02 20:18:37 millert Exp $ */ +/* $OpenBSD: fvwrite.h,v 1.6 2013/11/12 07:04:35 deraadt Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -36,7 +36,7 @@ * I/O descriptors for __sfvwrite(). */ struct __siov { - const void *iov_base; + void *iov_base; size_t iov_len; }; struct __suio { @@ -46,3 +46,4 @@ struct __suio { }; extern int __sfvwrite(FILE *, struct __suio *); +wint_t __fputwc_unlock(wchar_t wc, FILE *fp); diff --git a/libc/upstream-freebsd/lib/libc/stdio/fwrite.c b/libc/upstream-openbsd/lib/libc/stdio/fwrite.c similarity index 74% rename from libc/upstream-freebsd/lib/libc/stdio/fwrite.c rename to libc/upstream-openbsd/lib/libc/stdio/fwrite.c index 707d36279..f0a17bfb9 100644 --- a/libc/upstream-freebsd/lib/libc/stdio/fwrite.c +++ b/libc/upstream-openbsd/lib/libc/stdio/fwrite.c @@ -1,3 +1,4 @@ +/* $OpenBSD: fwrite.c,v 1.11 2014/05/01 16:40:36 deraadt Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -30,67 +31,58 @@ * SUCH DAMAGE. */ -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)fwrite.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ -#include -__FBSDID("$FreeBSD$"); - -#include "namespace.h" -#include -#include #include -#include "un-namespace.h" +#include +#include +#include #include "local.h" #include "fvwrite.h" -#include "libc_private.h" + +#define MUL_NO_OVERFLOW (1UL << (sizeof(size_t) * 4)) /* * Write `count' objects (each size `size') from memory to the given file. * Return the number of whole objects written. */ size_t -fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict fp) +fwrite(const void *buf, size_t size, size_t count, FILE *fp) { size_t n; struct __suio uio; struct __siov iov; + int ret; /* - * ANSI and SUSv2 require a return value of 0 if size or count are 0. + * Extension: Catch integer overflow */ - if ((count == 0) || (size == 0)) - return (0); - - /* - * Check for integer overflow. As an optimization, first check that - * at least one of {count, size} is at least 2^16, since if both - * values are less than that, their product can't possible overflow - * (size_t is always at least 32 bits on FreeBSD). - */ - if (((count | size) > 0xFFFF) && - (count > SIZE_MAX / size)) { - errno = EINVAL; + if ((size >= MUL_NO_OVERFLOW || count >= MUL_NO_OVERFLOW) && + size > 0 && SIZE_MAX / size < count) { + errno = EOVERFLOW; fp->_flags |= __SERR; return (0); } - n = count * size; + /* + * ANSI and SUSv2 require a return value of 0 if size or count are 0. + */ + if ((n = count * size) == 0) + return (0); iov.iov_base = (void *)buf; uio.uio_resid = iov.iov_len = n; uio.uio_iov = &iov; uio.uio_iovcnt = 1; - FLOCKFILE(fp); - ORIENT(fp, -1); /* * The usual case is success (__sfvwrite returns 0); * skip the divide if this happens, since divides are * generally slow and since this occurs whenever size==0. */ - if (__sfvwrite(fp, &uio) != 0) - count = (n - uio.uio_resid) / size; + FLOCKFILE(fp); + _SET_ORIENTATION(fp, -1); + ret = __sfvwrite(fp, &uio); FUNLOCKFILE(fp); - return (count); + if (ret == 0) + return (count); + return ((n - uio.uio_resid) / size); }