From patchwork Sat Oct 22 11:47:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 78795 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1740156qge; Sat, 22 Oct 2016 04:47:55 -0700 (PDT) X-Received: by 10.98.22.23 with SMTP id 23mr10492702pfw.65.1477136875136; Sat, 22 Oct 2016 04:47:55 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id q24si6641999pfj.175.2016.10.22.04.47.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 22 Oct 2016 04:47:55 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-439313-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-439313-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-439313-patch=linaro.org@gcc.gnu.org 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:references:mime-version:content-type :in-reply-to; q=dns; s=default; b=OWo6RzLgZwlR2hu1qbqB6783Ys6FOO /U7wvB5fTfU+aX1JL88qrVbtrPDY7tqzVUJLARuuTb2cEqvpa698DbTVHvntgw8d yBhU6ltiAkPyLSzG9saExCJnx6UBO7RWFDrp3IBy1JS8JADwbbzUupdOMNlOeGJ4 n3UN5l9Qv5lRg= 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:references:mime-version:content-type :in-reply-to; s=default; bh=VtDyt/fnNpLotyz8S3xoJ0V+X+M=; b=e4X9 VYBFRqffoTNADYkCRFN9bUS64fg63J7vhM8+WbffaVRz7SJQg7deIutUcpHhUYWl f052IIOPTNw4oExXiRr4EkPQLWc+Y5gMM/woup3G4VyGRNAn1y8UkBA59XSwZ0C4 rNdeRcjmi3KPHacidOBfdtPUdkrBJpz154JDj5g= Received: (qmail 80960 invoked by alias); 22 Oct 2016 11:47:28 -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 80935 invoked by uid 89); 22 Oct 2016 11:47:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.2 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=1216, 10978 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; Sat, 22 Oct 2016 11:47:16 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 782963D962; Sat, 22 Oct 2016 11:47:15 +0000 (UTC) Received: from localhost (ovpn-116-70.ams2.redhat.com [10.36.116.70]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9MBlEJH014051; Sat, 22 Oct 2016 07:47:15 -0400 Date: Sat, 22 Oct 2016 12:47:14 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [PATCH] Three patches for std::experimental::filesystem Message-ID: <20161022114714.GD2922@redhat.com> References: <20161021170105.GY2922@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20161021170105.GY2922@redhat.com> X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.7.0 (2016-08-17) On 21/10/16 18:01 +0100, Jonathan Wakely wrote: > LWG2720 implement filesystem::perms::symlink_nofollow > > * include/experimental/bits/fs_fwd.h (perms::resolve_symlinks): > Replace with symlink_nofollow (LWG 2720). > * src/filesystem/ops.cc (permissions(const path&, perms, error_code&)): > Handle symlink_nofollow. > * testsuite/experimental/filesystem/operations/create_symlink.cc: New > test. > * testsuite/experimental/filesystem/operations/permissions.cc: Test > overload taking error_code. GNU libc doesn't implement AT_SYMLINK_NOFOLLOW so fchmodat always returns EOPNOTSUPP even if it's used for non-symlinks. This patch makes us ignore symlink_nofollow if the file isn't a symlink, so we don't get an error unless we're actually trying to change a symlink's permissions. Tested x86_64-linux, committed to trunk. commit 5002d3b814ff6f72ce4e110079f5f406d0ff9898 Author: Jonathan Wakely Date: Sat Oct 22 11:57:36 2016 +0100 Ignore perms::symlink_nofollow on non-symlinks * src/filesystem/ops.cc (permissions(const path&, perms, error_code&)): Ignore symlink_nofollow flag if file is not a symlink. * testsuite/experimental/filesystem/operations/permissions.cc: Test symlink_nofollow on non-symlinks. diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index 68343a9..2286e22 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -1097,7 +1097,8 @@ fs::permissions(const path& p, perms prms) _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot set permissions", p, ec)); } -void fs::permissions(const path& p, perms prms, error_code& ec) noexcept +void +fs::permissions(const path& p, perms prms, error_code& ec) noexcept { const bool add = is_set(prms, perms::add_perms); const bool remove = is_set(prms, perms::remove_perms); @@ -1110,27 +1111,33 @@ void fs::permissions(const path& p, perms prms, error_code& ec) noexcept prms &= perms::mask; - if (add || remove) + file_status st; + if (add || remove || nofollow) { - auto st = nofollow ? symlink_status(p, ec) : status(p, ec); + st = nofollow ? symlink_status(p, ec) : status(p, ec); if (ec) return; auto curr = st.permissions(); if (add) prms |= curr; - else + else if (remove) prms = curr & ~prms; } + int err = 0; #if _GLIBCXX_USE_FCHMODAT - const int flag = nofollow ? AT_SYMLINK_NOFOLLOW : 0; + const int flag = (nofollow && is_symlink(st)) ? AT_SYMLINK_NOFOLLOW : 0; if (::fchmodat(AT_FDCWD, p.c_str(), static_cast(prms), flag)) + err = errno; #else - if (nofollow) + if (nofollow && is_symlink(st)) ec = std::make_error_code(std::errc::operation_not_supported); else if (::chmod(p.c_str(), static_cast(prms))) + err = errno; #endif - ec.assign(errno, std::generic_category()); + + if (err) + ec.assign(err, std::generic_category()); else ec.clear(); } diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc index 839cfef..61471a3 100644 --- a/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc +++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/permissions.cc @@ -121,6 +121,26 @@ test04() remove(p); } +void +test05() +{ + using perms = std::experimental::filesystem::perms; + std::error_code ec; + + __gnu_test::scoped_file f; + auto p = perms::owner_write; + + // symlink_nofollow should not give an error for non-symlinks + permissions(f.path, p|perms::symlink_nofollow, ec); + VERIFY( !ec ); + auto st = status(f.path); + VERIFY( st.permissions() == p ); + p |= perms::owner_read; + permissions(f.path, p|perms::symlink_nofollow, ec); + st = status(f.path); + VERIFY( st.permissions() == p ); +} + int main() { @@ -128,4 +148,5 @@ main() test02(); test03(); test04(); + test05(); }