From patchwork Wed Jan 2 20:34:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 30945 Received: (qmail 47094 invoked by alias); 2 Jan 2019 20:35:25 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 47083 invoked by uid 89); 2 Jan 2019 20:35:24 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-34.9 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS, USER_IN_DEF_SPF_WL autolearn=ham version=3.3.2 spammy=lf, Le, lab X-HELO: mail-ua1-f43.google.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=dIf9+9kT/xIk5/mi75PGy+opNaJRlppwal8hfjv5ZJw=; b=u9NHk5WVSiUs3v2FKLJVb+sFzyZm3gwpX6mnqsha1FB2cy6oLHG/9zcQkN44cKpptp Cqla84FfxNxd7tjGHpMOSFnVQoX9Gp52NP1zcvFWGVYMyJ4ildxiaAUqd+n2sakq163w 2S30v3nfcV8PJc2gzXhwqlJxkEDPMGIon61ya6IERO9UFiMERDOPMzOdNUjkAgI7ruIy eTsmOrkvF2Q3eRBsyLcXoOj3xQskZAEbd9K5PHbXspmOvNL/hZxQ0laCh2UOC0IgabVY IKq3jyDSVhuap+VdPfSt4yyjHJBc1m58I1PoLOWxn1A5Dys7N6BzOY/9dAWIUpCrvR1S mcJA== MIME-Version: 1.0 From: Paul Pluzhnikov Date: Wed, 2 Jan 2019 12:34:52 -0800 Message-ID: Subject: [PATCH] libio: use stdout in puts and putchar, etc [BZ #24051]. To: GLIBC Devel Cc: Florian Weimer Greetings, This fixes the output part of BZ #24051 for narrow and wide streams. The test is slightly asymmetric: as far as I can tell a wide equivalent to puts() doesn't exist. I'll work on fixing the similar stdin problem in a follow-up. Thanks, diff --git a/ChangeLog b/ChangeLog index 75c80e6f02..70c6176f6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2019-01-02 Paul Pluzhnikov + + [BZ #24051] + * libio/ioputs.c (_IO_puts): Use stdout instead of _IO_stdout. + * libio/fileops.c (_IO_new_file_underflow): Likewise + * libio/wfileops.c (_IO_wfile_underflow): Likewise + * libio/putchar.c (putchar): Likewise. + * libio/putchar_u.c (putchar_unlocked): Likewise. + * libio/putwchar.c (putchar): Likewise. + * libio/putwchar_u.c (putwchar_unlocked): Likewise. + * libio/tst-bz24051.c: New test. + * libio/Makefile (tests): Add tst-bz24051 + 2019-01-02 Joseph Myers * sysdeps/unix/sysv/linux/tst-mman-consts.py (main): Expect diff --git a/libio/Makefile b/libio/Makefile index 5bee83e55c..dbeba88fc0 100644 --- a/libio/Makefile +++ b/libio/Makefile @@ -65,7 +65,7 @@ tests = tst_swprintf tst_wprintf tst_swscanf tst_wscanf tst_getwc tst_putwc \ tst-setvbuf1 tst-popen1 tst-fgetwc bug-wsetpos tst-fseek \ tst-fwrite-error tst-ftell-partial-wide tst-ftell-active-handler \ tst-ftell-append tst-fputws tst-bz22415 tst-fgetc-after-eof \ - tst-sprintf-ub tst-sprintf-chk-ub + tst-sprintf-ub tst-sprintf-chk-ub tst-bz24051 tests-internal = tst-vtables tst-vtables-interposed tst-readline diff --git a/libio/fileops.c b/libio/fileops.c index 43e33820e3..d2070a856e 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -501,13 +501,13 @@ _IO_new_file_underflow (FILE *fp) traditional Unix systems did this for stdout. stderr better not be line buffered. So we do just that here explicitly. --drepper */ - _IO_acquire_lock (_IO_stdout); + _IO_acquire_lock (stdout); - if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + if ((stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) == (_IO_LINKED | _IO_LINE_BUF)) - _IO_OVERFLOW (_IO_stdout, EOF); + _IO_OVERFLOW (stdout, EOF); - _IO_release_lock (_IO_stdout); + _IO_release_lock (stdout); } _IO_switch_to_get_mode (fp); diff --git a/libio/ioputs.c b/libio/ioputs.c index 04ae323c6d..319e551de5 100644 --- a/libio/ioputs.c +++ b/libio/ioputs.c @@ -33,15 +33,15 @@ _IO_puts (const char *str) { int result = EOF; size_t len = strlen (str); - _IO_acquire_lock (_IO_stdout); + _IO_acquire_lock (stdout); - if ((_IO_vtable_offset (_IO_stdout) != 0 - || _IO_fwide (_IO_stdout, -1) == -1) - && _IO_sputn (_IO_stdout, str, len) == len - && _IO_putc_unlocked ('\n', _IO_stdout) != EOF) + if ((_IO_vtable_offset (stdout) != 0 + || _IO_fwide (stdout, -1) == -1) + && _IO_sputn (stdout, str, len) == len + && _IO_putc_unlocked ('\n', stdout) != EOF) result = MIN (INT_MAX, len + 1); - _IO_release_lock (_IO_stdout); + _IO_release_lock (stdout); return result; } diff --git a/libio/putchar.c b/libio/putchar.c index 665f46685a..a3f4200cdb 100644 --- a/libio/putchar.c +++ b/libio/putchar.c @@ -24,9 +24,9 @@ int putchar (int c) { int result; - _IO_acquire_lock (_IO_stdout); - result = _IO_putc_unlocked (c, _IO_stdout); - _IO_release_lock (_IO_stdout); + _IO_acquire_lock (stdout); + result = _IO_putc_unlocked (c, stdout); + _IO_release_lock (stdout); return result; } diff --git a/libio/putchar_u.c b/libio/putchar_u.c index 37d03ad364..1eebf0fc8f 100644 --- a/libio/putchar_u.c +++ b/libio/putchar_u.c @@ -23,6 +23,6 @@ int putchar_unlocked (int c) { - CHECK_FILE (_IO_stdout, EOF); - return _IO_putc_unlocked (c, _IO_stdout); + CHECK_FILE (stdout, EOF); + return _IO_putc_unlocked (c, stdout); } diff --git a/libio/putwchar.c b/libio/putwchar.c index 8d6b6a4df0..1f5c4176f8 100644 --- a/libio/putwchar.c +++ b/libio/putwchar.c @@ -22,8 +22,8 @@ wint_t putwchar (wchar_t wc) { wint_t result; - _IO_acquire_lock (_IO_stdout); - result = _IO_putwc_unlocked (wc, _IO_stdout); - _IO_release_lock (_IO_stdout); + _IO_acquire_lock (stdout); + result = _IO_putwc_unlocked (wc, stdout); + _IO_release_lock (stdout); return result; } diff --git a/libio/putwchar_u.c b/libio/putwchar_u.c index cfb46fc253..d943220031 100644 --- a/libio/putwchar_u.c +++ b/libio/putwchar_u.c @@ -21,6 +21,6 @@ wint_t putwchar_unlocked (wchar_t wc) { - CHECK_FILE (_IO_stdout, WEOF); - return _IO_putwc_unlocked (wc, _IO_stdout); + CHECK_FILE (stdout, WEOF); + return _IO_putwc_unlocked (wc, stdout); } diff --git a/libio/tst-bz24051.c b/libio/tst-bz24051.c new file mode 100644 index 0000000000..52c7a64b5b --- /dev/null +++ b/libio/tst-bz24051.c @@ -0,0 +1,79 @@ +/* Test that assigning to stdout redirects puts, putchar, etc (BZ#24051) + Copyright (C) 2019 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + + +/* Prevent putchar -> _IO_putc inline expansion. */ +#define __NO_INLINE__ + +#include +#include +#include + +#include +#include +#include + +#undef putchar +#undef putwchar + +static int +do_test_narrow (void) +{ + char buf[100]; + int fd = create_temp_file ("tst-bz24051", NULL); + stdout = fdopen (fd, "w+"); + TEST_VERIFY_EXIT (stdout != NULL); + + printf ("ab%s", "cd"); + putchar ('e'); + putchar_unlocked ('f'); + puts ("ghi"); + + rewind (stdout); + TEST_VERIFY_EXIT (fgets (buf, sizeof (buf), stdout) != NULL); + TEST_VERIFY (strcmp (buf, "abcdefghi\n") == 0); + + return 0; +} + +static int +do_test_wide (void) +{ + wchar_t buf[100]; + int fd = create_temp_file ("tst-bz24051w", NULL); + stdout = fdopen (fd, "w+"); + TEST_VERIFY_EXIT (stdout != NULL); + + wprintf (L"ab%ls", L"cd"); + putwchar (L'e'); + putwchar_unlocked (L'f'); + + rewind (stdout); + TEST_VERIFY_EXIT (fgetws (buf, sizeof (buf), stdout) != NULL); + TEST_VERIFY (wcscmp (buf, L"abcdef") == 0); + + return 0; +} + +static int +do_test (void) +{ + return do_test_narrow () + do_test_wide (); +} + +#include diff --git a/libio/wfileops.c b/libio/wfileops.c index 78f20486e5..0367643703 100644 --- a/libio/wfileops.c +++ b/libio/wfileops.c @@ -208,13 +208,13 @@ _IO_wfile_underflow (FILE *fp) traditional Unix systems did this for stdout. stderr better not be line buffered. So we do just that here explicitly. --drepper */ - _IO_acquire_lock (_IO_stdout); + _IO_acquire_lock (stdout); - if ((_IO_stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) + if ((stdout->_flags & (_IO_LINKED | _IO_NO_WRITES | _IO_LINE_BUF)) == (_IO_LINKED | _IO_LINE_BUF)) - _IO_OVERFLOW (_IO_stdout, EOF); + _IO_OVERFLOW (stdout, EOF); - _IO_release_lock (_IO_stdout); + _IO_release_lock (stdout); } _IO_switch_to_get_mode (fp);