From 53b24382f5299931af5d08c933a765334a092c56 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 2 May 2014 18:29:25 -0700 Subject: [PATCH] Switch to current upstream OpenBSD wsetup.c. Change-Id: I2c1123f3e1d3c4af7fd7bf354e763934a39b78c0 --- libc/Android.mk | 2 +- .../lib/libc/stdio/wsetup.c | 20 ++++----- tests/stdio_test.cpp | 42 +++++++++++++++++++ 3 files changed, 50 insertions(+), 14 deletions(-) rename libc/{upstream-freebsd => upstream-openbsd}/lib/libc/stdio/wsetup.c (87%) diff --git a/libc/Android.mk b/libc/Android.mk index ff21d6af9..9f8476b44 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -227,7 +227,6 @@ libc_upstream_freebsd_src_files := \ 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 @@ libc_upstream_openbsd_src_files := \ 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 70f8247c0..083422365 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 -__FBSDID("$FreeBSD$"); - -#include #include #include #include "local.h" @@ -44,7 +38,7 @@ __FBSDID("$FreeBSD$"); /* * 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 @@ __swsetup(FILE *fp) * 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 @@ __swsetup(FILE *fp) /* * 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 d825c14ec..ebb27d4a5 100644 --- a/tests/stdio_test.cpp +++ b/tests/stdio_test.cpp @@ -436,3 +436,45 @@ TEST(stdio, sscanf) { 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 +}