Switch to current upstream OpenBSD fwrite.c.
Change-Id: Ife527aafc1e5438f477d711902efe6e6f59f3f8e
diff --git a/libc/Android.mk b/libc/Android.mk
index ff21d6a..9b71f6a 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -223,7 +223,6 @@
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 @@
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 96f65de..d3a309b 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 @@
};
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 707d362..f0a17bf 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 <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include "namespace.h"
-#include <errno.h>
-#include <stdint.h>
#include <stdio.h>
-#include "un-namespace.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <errno.h>
#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);
}