FreeBSD Bugzilla – Attachment 121653 Details for
Bug 164674
libc: vfprintf/vfwprintf return error (EOF) on success if __SERR flag is already set on file
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 6.37 KB, created by
Matthew Story
on 2012-01-31 23:10:09 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
Matthew Story
Created:
2012-01-31 23:10:09 UTC
Size:
6.37 KB
patch
obsolete
>diff -urN old/lib/libc/stdio/vfprintf.c new/lib/libc/stdio/vfprintf.c >--- old/lib/libc/stdio/vfprintf.c 2012-01-31 17:35:31.025336246 -0500 >+++ new/lib/libc/stdio/vfprintf.c 2012-01-31 17:44:50.078652303 -0500 >@@ -265,14 +265,24 @@ > > { > int ret; >+ short orig_err; > > FLOCKFILE(fp); >+ /* >+ * store flags, unset errors, success of printf is >+ * independent of previous errors on the fd >+ */ >+ orig_err = fp->_flags & __SERR; >+ fp->_flags &= ~__SERR; >+ > /* optimise fprintf(stderr) (and other unbuffered Unix files) */ > if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && > fp->_file >= 0) > ret = __sbprintf(fp, fmt0, ap); > else > ret = __vfprintf(fp, fmt0, ap); >+ >+ fp->_flags |= orig_err & __SERR; > FUNLOCKFILE(fp); > return (ret); > } >diff -urN old/lib/libc/stdio/vfwprintf.c new/lib/libc/stdio/vfwprintf.c >--- old/lib/libc/stdio/vfwprintf.c 2012-01-31 17:35:31.021336063 -0500 >+++ new/lib/libc/stdio/vfwprintf.c 2012-01-31 17:46:28.106128024 -0500 >@@ -347,14 +347,24 @@ > > { > int ret; >+ short orig_err; > > FLOCKFILE(fp); >+ /* >+ * store flags, unset errors, success of wprintf is >+ * independent of previous errors on the fd >+ */ >+ orig_err = fp->_flags & __SERR; >+ fp->_flags &= ~__SERR; >+ > /* optimise fprintf(stderr) (and other unbuffered Unix files) */ > if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && > fp->_file >= 0) > ret = __sbprintf(fp, fmt0, ap); > else > ret = __vfwprintf(fp, fmt0, ap); >+ >+ fp->_flags |= orig_err & __SERR; > FUNLOCKFILE(fp); > return (ret); > } >diff -urN old/tools/regression/lib/libc/stdio/Makefile new/tools/regression/lib/libc/stdio/Makefile >--- old/tools/regression/lib/libc/stdio/Makefile 2012-01-31 17:36:04.247820192 -0500 >+++ new/tools/regression/lib/libc/stdio/Makefile 2012-01-31 17:41:30.201758177 -0500 >@@ -1,6 +1,6 @@ > # $FreeBSD: stable/9/tools/regression/lib/libc/stdio/Makefile 189142 2009-02-28 06:39:39Z das $ > >-TESTS= test-getdelim test-perror test-print-positional test-printbasic test-printfloat test-scanfloat >+TESTS= test-getdelim test-perror test-print-positional test-printbasic test-printfloat test-scanfloat test-printreturn > CFLAGS+= -lm > > .PHONY: tests >diff -urN old/tools/regression/lib/libc/stdio/test-printreturn.c new/tools/regression/lib/libc/stdio/test-printreturn.c >--- old/tools/regression/lib/libc/stdio/test-printreturn.c 1969-12-31 19:00:00.000000000 -0500 >+++ new/tools/regression/lib/libc/stdio/test-printreturn.c 2012-01-31 17:41:30.200756664 -0500 >@@ -0,0 +1,148 @@ >+/*- >+ * Copyright (c) 2012 Matthew Story <matthewstory@gmail.com> >+ * All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND >+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE >+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE >+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL >+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS >+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) >+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT >+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY >+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF >+ * SUCH DAMAGE. >+ */ >+ >+/* >+ * Tests for correct return codes from f(w)printf >+ */ >+ >+#include <assert.h> >+#include <stdio.h> >+#include <stdlib.h> >+#include <stdint.h> >+#include <wchar.h> >+#include <errno.h> >+#include <string.h> >+ >+#define BATTERY_OK "ok %d - printreturn\n" >+ >+#define run_battery(void) \ >+ _run_battery(__LINE__) >+ >+void smash_stack(void); >+void _run_battery(int line); >+int battery = 1; >+ >+int >+main() { >+ /* >+ * All tests occur on stdout, this makes the tests quite noisy. >+ * but keeps them contained -- e.g. no reliance on external >+ * files, or on manipulating file struct internals. >+ */ >+ >+ printf("1..12\n"); >+ /* >+ * without errors >+ */ >+ clearerr(stdout); >+ >+ /* line-buffered */ >+ setvbuf(stdout, (char *)NULL, _IOLBF, 0); >+ run_battery(); >+ >+ /* unbuffered */ >+ setvbuf(stdout, (char *)NULL, _IONBF, 0); >+ run_battery(); >+ >+ /* fully-buffered */ >+ setvbuf(stdout, (char *)NULL, _IOFBF, 0); >+ run_battery(); >+ >+ /* >+ * success with errors, would rather not manipulate _flags * directly, but >+ * can't find another direct way to set error, without an actual error. >+ */ >+ stdout->_flags |= __SERR; >+ >+ /* line-buffered */ >+ setvbuf(stdout, (char *)NULL, _IOLBF, 0); >+ run_battery(); >+ >+ /* unbuffered */ >+ setvbuf(stdout, (char *)NULL, _IONBF, 0); >+ run_battery(); >+ >+ /* fully-buffered */ >+ setvbuf(stdout, (char *)NULL, _IOFBF, 0); >+ run_battery(); >+ >+ return 0; >+} >+ >+/* taken from test-printbasic.c */ >+void >+smash_stack(void) >+{ >+ static uint32_t junk = 0xdeadbeef; >+ uint32_t buf[512]; >+ int i; >+ >+ for (i = 0; i < sizeof(buf) / sizeof(buf[0]); i++) >+ buf[i] = junk; >+} >+ >+void >+_run_battery(int line) { >+#define BUF 100 >+ extern int battery; >+ wchar_t ws[BUF], wfmt[BUF]; >+ char s[BUF]; >+ >+ /* regular width tests, no replacement, and replacement */ >+ smash_stack(); >+ sprintf(s, BATTERY_OK, battery); >+ if (0 > fprintf(stdout, s)) { >+ fprintf(stderr, >+ "%d: failure in no replace printf (%d)\n", >+ line, errno); >+ abort(); >+ } >+ ++battery; >+ smash_stack(); >+ if (0 > fprintf(stdout, BATTERY_OK, battery)) { >+ fprintf(stderr, "%d: failure in replace printf (%d)\n", line, errno); >+ abort(); >+ } >+ ++battery; >+ >+ /* wide tests, no replacement, and replacement */ >+ smash_stack(); >+ mbstowcs(wfmt, BATTERY_OK, BUF - 1); >+ swprintf(ws, sizeof(ws) / sizeof(ws[0]), wfmt, battery); >+ if (0 > fwprintf(stdout, ws)) { >+ fprintf(stderr, >+ "%d: failure in no replace wprintf (%d)\n", >+ line, errno); >+ abort(); >+ } >+ ++battery; >+ smash_stack(); >+ if (0 > fwprintf(stdout, wfmt, battery)) { >+ fprintf(stderr, "%d: failure in replace wprintf (%d)\n", line, errno); >+ abort(); >+ } >+ ++battery; >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 164674
: 121653 |
121654