Switch to current upstream OpenBSD wsetup.c.

Change-Id: I2c1123f3e1d3c4af7fd7bf354e763934a39b78c0
diff --git a/libc/Android.mk b/libc/Android.mk
index ff21d6a..9f8476b 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -227,7 +227,6 @@
     upstream-freebsd/lib/libc/stdio/makebuf.c \
     upstream-freebsd/lib/libc/stdio/mktemp.c \
     upstream-freebsd/lib/libc/stdio/setvbuf.c \
-    upstream-freebsd/lib/libc/stdio/wsetup.c \
     upstream-freebsd/lib/libc/stdlib/abs.c \
     upstream-freebsd/lib/libc/stdlib/getopt_long.c \
     upstream-freebsd/lib/libc/stdlib/imaxabs.c \
@@ -436,6 +435,7 @@
     upstream-openbsd/lib/libc/stdio/wbuf.c \
     upstream-openbsd/lib/libc/stdio/wprintf.c \
     upstream-openbsd/lib/libc/stdio/wscanf.c \
+    upstream-openbsd/lib/libc/stdio/wsetup.c \
     upstream-openbsd/lib/libc/stdlib/atoi.c \
     upstream-openbsd/lib/libc/stdlib/atol.c \
     upstream-openbsd/lib/libc/stdlib/atoll.c \
diff --git a/libc/upstream-freebsd/lib/libc/stdio/wsetup.c b/libc/upstream-openbsd/lib/libc/stdio/wsetup.c
similarity index 87%
rename from libc/upstream-freebsd/lib/libc/stdio/wsetup.c
rename to libc/upstream-openbsd/lib/libc/stdio/wsetup.c
index 70f8247..0834223 100644
--- a/libc/upstream-freebsd/lib/libc/stdio/wsetup.c
+++ b/libc/upstream-openbsd/lib/libc/stdio/wsetup.c
@@ -1,3 +1,4 @@
+/*	$OpenBSD: wsetup.c,v 1.7 2005/08/08 08:05:36 espie Exp $ */
 /*-
  * Copyright (c) 1990, 1993
  *	The Regents of the University of California.  All rights reserved.
@@ -30,13 +31,6 @@
  * SUCH DAMAGE.
  */
 
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)wsetup.c	8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "local.h"
@@ -44,7 +38,7 @@
 /*
  * Various output routines call wsetup to be sure it is safe to write,
  * because either _flags does not include __SWR, or _buf is NULL.
- * _wsetup returns 0 if OK to write; otherwise, it returns EOF and sets errno.
+ * _wsetup returns 0 if OK to write, nonzero otherwise.
  */
 int
 __swsetup(FILE *fp)
@@ -57,11 +51,8 @@
 	 * If we are not writing, we had better be reading and writing.
 	 */
 	if ((fp->_flags & __SWR) == 0) {
-		if ((fp->_flags & __SRW) == 0) {
-			errno = EBADF;
-			fp->_flags |= __SERR;
+		if ((fp->_flags & __SRW) == 0)
 			return (EOF);
-		}
 		if (fp->_flags & __SRD) {
 			/* clobber any ungetc data */
 			if (HASUB(fp))
@@ -76,8 +67,11 @@
 	/*
 	 * Make a buffer if necessary, then set _w.
 	 */
-	if (fp->_bf._base == NULL)
+	if (fp->_bf._base == NULL) {
+		if ((fp->_flags & (__SSTR | __SALC)) == __SSTR)
+			return (EOF);
 		__smakebuf(fp);
+	}
 	if (fp->_flags & __SLBF) {
 		/*
 		 * It is line buffered, so make _lbfsize be -_bufsize
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index d825c14..ebb27d4 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -436,3 +436,45 @@
   ASSERT_EQ(123, i1);
   ASSERT_DOUBLE_EQ(1.23, d1);
 }
+
+TEST(stdio, cantwrite_EBADF) {
+  // If we open a file read-only...
+  FILE* fp = fopen("/proc/version", "r");
+
+  // ...all attempts to write to that file should return failure.
+
+  // They should also set errno to EBADF. This isn't POSIX, but it's traditional.
+  // glibc gets the wide-character functions wrong.
+
+  errno = 0;
+  EXPECT_EQ(EOF, putc('x', fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(EOF, fprintf(fp, "hello"));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(EOF, fwprintf(fp, L"hello"));
+#if !defined(__GLIBC__)
+  EXPECT_EQ(EBADF, errno);
+#endif
+
+  errno = 0;
+  EXPECT_EQ(EOF, putw(1234, fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(0U, fwrite("hello", 1, 2, fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(EOF, fputs("hello", fp));
+  EXPECT_EQ(EBADF, errno);
+
+  errno = 0;
+  EXPECT_EQ(WEOF, fputwc(L'x', fp));
+#if !defined(__GLIBC__)
+  EXPECT_EQ(EBADF, errno);
+#endif
+}