From patchwork Wed Aug 9 15:56:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 799853 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-460110-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="tKQK8Cgn"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xSG931hMVz9s65 for ; Thu, 10 Aug 2017 01:56:38 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=Qdt7kBvcFCzYZROYqgbSpNK1VWb/YT/EjAisMIOMVYm3Cu/fTg +nBudzdNANFHmtRj/4jaVvzDqiAwiGRFm5WL5M9yGFZoEDpJSF3S3BDrtcyjHq2a nsDVxw4ZP/oil98DWonQfaHPQZBImtAaq6p6mIpXh+Tyt9d363R0/o+lY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=7UcEz/X7pxQOxSG26C4tXP+vT1c=; b=tKQK8CgnK0+/o7EAPiNm ICaKkeP3ZWIPMroAc1EwfPAdrUSrkxuUIHWNq0MWDMzdzmDE5pl+7mP57u7EXBDu zFNKcUJlbfDTgGZv5DYkZKx/UJouDEKSZFc9HmpwL17zQWHtx/bA4ndKL8EVt57k nozzWQGHMXHXuDfyYARrVg0= Received: (qmail 119987 invoked by alias); 9 Aug 2017 15:56:24 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 119854 invoked by uid 89); 9 Aug 2017 15:56:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=secondly, firstly, HTo:U*libstdc X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 09 Aug 2017 15:56:11 +0000 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 87BD613871E; Wed, 9 Aug 2017 15:56:06 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 87BD613871E Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=jwakely@redhat.com Received: from localhost (unknown [10.33.36.71]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2BC8C776FB; Wed, 9 Aug 2017 15:56:05 +0000 (UTC) Date: Wed, 9 Aug 2017 16:56:05 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: Paolo Carlini Subject: [PATCH] PR libstdc++/81751 don't call fflush(NULL) Message-ID: <20170809155605.GL15340@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.8.0 (2017-02-23) This fixes a couple of problems in __gnu_cxx::stdio_filebuf, specifically in the __basic_file::sys_open(FILE*, openmode) function it uses when constructed from an existing FILE stream. Firstly, r86756 changed __basic_file::sys_open(FILE*, openmode) to put the call to sync() before the assignment that sets _M_cfile. This means the fflush(_M_cfile) call has a null argument, and flushes all open streams. I don't think that was intentional, and we only want to flush the FILE we're constructing the streambuf with. (I think this is a regression from 3.4.3, which just flushed the one stream). Secondly, we zero errno so that we can tell if fflush sets it. We need to restore the original value to meet the promise we make at https://gcc.gnu.org/onlinedocs/libstdc++/manual/errno.html Paolo, does the this->sync() to fflush(__file) change look right? PR libstdc++/79820 PR libstdc++/81751 * config/io/basic_file_stdio.cc (sys_open(FILE*, ios_base::openmode)): Call fflush on the stream instead of calling sync() while _M_cfile is null. Restore original value of errno. * testsuite/ext/stdio_filebuf/char/79820.cc: New. * testsuite/ext/stdio_filebuf/char/81751.cc: New. Tested powerpc64le-linux, not yet committed. commit 72565d197cc91a04882a398d9d242a0581d6cc09 Author: Jonathan Wakely Date: Tue Aug 8 23:20:40 2017 +0100 PR libstdc++/81751 don't call fflush(NULL) PR libstdc++/79820 PR libstdc++/81751 * config/io/basic_file_stdio.cc (sys_open(FILE*, ios_base::openmode)): Call fflush on the stream instead of calling sync() while _M_cfile is null. Restore original value of errno. * testsuite/ext/stdio_filebuf/char/79820.cc: New. * testsuite/ext/stdio_filebuf/char/81751.cc: New. diff --git a/libstdc++-v3/config/io/basic_file_stdio.cc b/libstdc++-v3/config/io/basic_file_stdio.cc index e736701..eeb1e5e 100644 --- a/libstdc++-v3/config/io/basic_file_stdio.cc +++ b/libstdc++-v3/config/io/basic_file_stdio.cc @@ -195,11 +195,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __basic_file* __ret = NULL; if (!this->is_open() && __file) { - int __err; + int __err, __save_errno = errno; + // POSIX guarantees that fflush sets errno on error, but C doesn't. errno = 0; do - __err = this->sync(); + __err = fflush(__file); while (__err && errno == EINTR); + errno = __save_errno; if (!__err) { _M_cfile = __file; diff --git a/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc new file mode 100644 index 0000000..ba566f8 --- /dev/null +++ b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc @@ -0,0 +1,39 @@ +// Copyright (C) 2017 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-require-fileio "" } + +#include +#include +#include +#include + +void +test01() +{ + FILE* f = std::fopen("79820.txt", "w"); + std::fclose(f); + errno = 127; + __gnu_cxx::stdio_filebuf b(f, std::ios::out, BUFSIZ); + VERIFY(errno == 127); // PR libstdc++/79820 +} + +int +main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/ext/stdio_filebuf/char/81751.cc b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/81751.cc new file mode 100644 index 0000000..22191dcb --- /dev/null +++ b/libstdc++-v3/testsuite/ext/stdio_filebuf/char/81751.cc @@ -0,0 +1,53 @@ +// Copyright (C) 2017 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This 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 General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-require-fileio "" } + +#include +#include +#include +#include + +void +test01() +{ + FILE* out = std::fopen("81751.txt", "w"); + std::fwrite("Some words.", 1, 10, out); + + FILE* in1 = std::fopen("81751.txt", "r"); + __gnu_cxx::stdio_filebuf buf1(in1, std::ios::in, BUFSIZ); + int c = buf1.sgetc(); + VERIFY( c == std::char_traits::eof() ); // PR libstdc++/81751 + + std::fflush(out); + FILE* in2 = std::fopen("81751.txt", "r"); + __gnu_cxx::stdio_filebuf buf2(in2, std::ios::in, BUFSIZ); + c = buf2.sgetc(); + VERIFY( c == 'S' ); + + buf1.close(); + buf2.close(); + std::fclose(in1); + std::fclose(in2); + std::fclose(out); +} + +int +main() +{ + test01(); +}