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
+}