From patchwork Thu Jan 17 15:32:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1026752 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-494248-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="S9y/GEwT"; 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 43gSlY3Smhz9sCh for ; Fri, 18 Jan 2019 02:33:29 +1100 (AEDT) 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:subject:message-id:mime-version:content-type; q=dns; s= default; b=RGEzULIvN1KrbiXXf9/SilyURk7vAjUlzynMzG/pZtv6d55Vt5Uo5 BiDFYjc7eVebo2GzxcstFf9n1mLdz2rpBRSyUsrsu4nZ530gwI4lLVYsRtFX+Vkh e2rIqWbjnLUz28coZm0LoNgubcrDopAxWxyCxsEZ6xqaI1njlGQNXE= 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:subject:message-id:mime-version:content-type; s= default; bh=OFTQS3PapjJRP7f6CDotqp0YpwU=; b=S9y/GEwT0Ze6V/WolwUH IKTNp8+NHWlUVC/BwefjtR6k2S8YtpRaWl/E2Ix/ksOd064DfvYj9rycl7CeyR6z ReAdZaBGGFBLtNyYuxhtZsPfleMJ68tGa6Ykjqer9CpoOaQE2ile73ewFcRfPZcd pU3ttGxUkr9mSwh6vjgt2Mk= Received: (qmail 11546 invoked by alias); 17 Jan 2019 15:32:59 -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 10895 invoked by uid 89); 17 Jan 2019 15:32:54 -0000 Authentication-Results: sourceware.org; auth=none 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, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=h2, relying 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; Thu, 17 Jan 2019 15:32:52 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 307E8C0CD17B; Thu, 17 Jan 2019 15:32:51 +0000 (UTC) Received: from localhost (unknown [10.33.36.22]) by smtp.corp.redhat.com (Postfix) with ESMTP id C59921835A; Thu, 17 Jan 2019 15:32:50 +0000 (UTC) Date: Thu, 17 Jan 2019 15:32:50 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [PATCH] Fix filesystem::equivalent for mingw Message-ID: <20190117153250.GA27124@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.10.1 (2018-07-13) * src/c++17/fs_ops.cc (equivalent(const path&, const path&, error_code&)) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Use GetFileInformationByHandle to compare files instead of relying on incomplete info returned by stat. Tested x86_64-linux and x86_64-w64-mingw32, committed to trunk. commit 6c860ebca6e0b486e9b95231e175fb4084ca3f0a Author: Jonathan Wakely Date: Thu Jan 17 14:18:38 2019 +0000 Fix filesystem::equivalent for mingw * src/c++17/fs_ops.cc (equivalent(const path&, const path&, error_code&)) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Use GetFileInformationByHandle to compare files instead of relying on incomplete info returned by stat. diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc index c4b99fb36ce..3ff0ded1c66 100644 --- a/libstdc++-v3/src/c++17/fs_ops.cc +++ b/libstdc++-v3/src/c++17/fs_ops.cc @@ -851,7 +851,49 @@ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept ec.clear(); if (is_other(s1) || is_other(s2)) return false; +#if _GLIBCXX_FILESYSTEM_IS_WINDOWS + // st_ino is not set, so can't be used to distinguish files + if (st1.st_mode != st2.st_mode || st1.st_dev != st2.st_dev) + return false; + + struct auto_handle { + explicit auto_handle(const path& p_) + : handle(CreateFileW(p_.c_str(), 0, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0)) + { } + + ~auto_handle() + { if (*this) CloseHandle(handle); } + + explicit operator bool() const + { return handle != INVALID_HANDLE_VALUE; } + + bool get_info() + { return GetFileInformationByHandle(handle, &info); } + + HANDLE handle; + BY_HANDLE_FILE_INFORMATION info; + }; + auto_handle h1(p1); + auto_handle h2(p2); + if (!h1 || !h2) + { + if (!h1 && !h2) + ec.assign((int)GetLastError(), generic_category()); + return false; + } + if (!h1.get_info() || !h2.get_info()) + { + ec.assign((int)GetLastError(), generic_category()); + return false; + } + return h1.info.dwVolumeSerialNumber == h2.info.dwVolumeSerialNumber + && h1.info.nFileIndexHigh == h2.info.nFileIndexHigh + && h1.info.nFileIndexLow == h2.info.nFileIndexLow; +#else return st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino; +#endif } else if (!exists(s1) && !exists(s2)) ec = std::make_error_code(std::errc::no_such_file_or_directory);