From patchwork Thu Aug 11 19:27:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Uros Bizjak X-Patchwork-Id: 658317 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3s9J2V23Qlz9sCp for ; Fri, 12 Aug 2016 05:28:01 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=RWZvhPMW; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=DknCULLayp09IcCxWK/srsVvlPnqPldrdkpLs+L7RWk taZ+IaNyJoUKAPyAqWPhyneNhkG1+Mbw+Jgx0hK1kL92yHsgrh10atPbtqHDkeVE tdVNv0aA5fL5HnoSE7/SD6vUk2NlQdHYWTyxPJxTHR5ykDb/3WQ8mwfLs+ue6woc = 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 :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=VqQo7NE6jMywAexKk8t558DT/Qg=; b=RWZvhPMWSMPFt28Ox FrhHERIhMLUITNdKgUgw+goGeyPI42CWUV/CbnlElZT8X0rdeHHgi7L1vJC2rE4u 7ohpViZE//wzKmN+hzIHXXJHvflGYPUuZnNx5NlVA/d/yz0nxSs8fo/qTDZfzpvL AQp/Qqj7t6bA8LiskUNeToMDUk= Received: (qmail 1612 invoked by alias); 11 Aug 2016 19:27:37 -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 1489 invoked by uid 89); 11 Aug 2016 19:27:36 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=4286, Hx-languages-length:3211, hello!, wish X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-ua0-f193.google.com Received: from mail-ua0-f193.google.com (HELO mail-ua0-f193.google.com) (209.85.217.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 11 Aug 2016 19:27:26 +0000 Received: by mail-ua0-f193.google.com with SMTP id u13so418156uau.0; Thu, 11 Aug 2016 12:27:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to:cc; bh=dK8tC6jGIF6IRg7pC3AQytqyD3MjT02N7JmcLJV/51M=; b=dCR4L2hmhP0BedJP/hfUWGkYGSrRoNoLtiQb73kBesD3hBmlgLGEpoWP7owR6SMzul 0Bn5Xf+CH64ZqyUHoX76m5RSkyocnsoth8QCRwElaTcsDbDHvoF8FVqXzlXJANaPnjn+ 2htLdGEZcAzRTmqNEMRHt0qUNV58jiUQqFkHNs9fZAok4UL4zIBmJmy/QdUwl17OjX0E jdXY+Cr/zp57Sj7UA0iUhxzunkONzTDNLNU4hi99gnmlyIBmJ5DaAzbQvzfYp0poELl/ PHxDa+j5ekrllHYX8lg3ZnnJx85zOx1ZOLWUOifNh+f6cJtbrwzkQc1eu9vOrjAsmton uafg== X-Gm-Message-State: AEkoousSdqi3jYlbXTKaMCY5pxIyDr9FmZsQSDEmARo3Ir8JZKTS5NLogIZJA3zuRRAXx+mN5qK42G8qCDvwsQ== X-Received: by 10.31.5.213 with SMTP id 204mr4879046vkf.60.1470943644542; Thu, 11 Aug 2016 12:27:24 -0700 (PDT) MIME-Version: 1.0 Received: by 10.103.20.193 with HTTP; Thu, 11 Aug 2016 12:27:24 -0700 (PDT) From: Uros Bizjak Date: Thu, 11 Aug 2016 21:27:24 +0200 Message-ID: Subject: [PATCH, libstdc++v3]: Fallback to read/write ops in case sendfile fails with ENOSYS or EINVAL. To: "gcc-patches@gcc.gnu.org" Cc: "libstdc++" , Jonathan Wakely Hello! Attached patch implements note from sendfile manpage: Applications may wish to fall back to read(2)/write(2) in the case where sendfile() fails with EINVAL or ENOSYS. Also, the patch fixes a small inconsistency in how _GLIBCXX_USE_FCHMODAT config flag is handled in do_copy_file function. 2016-08-11 Uros Bizjak * src/filesystem/ops.cc: Always include ostream and ext/stdio_filebuf.h. (do_copy_file): Check if _GLIBCXX_USE_FCHMODAT is defined. [_GLIBCXX_USE_SENDFILE]: Fallback to read/write operations in case sendfile fails with ENOSYS or EINVAL. Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32} on CentOS 5.11 (where sendfile returns EINVAL for file->file copy) and Fedora 24. In addition, the patch was bootstraped and regression tested with _GLIBCXX_USE_SENDFILE manually disabled after configure. OK for mainline? Uros. Index: src/filesystem/ops.cc =================================================================== --- src/filesystem/ops.cc (revision 239384) +++ src/filesystem/ops.cc (working copy) @@ -28,7 +28,9 @@ #include #include +#include #include +#include #include #include #include @@ -48,9 +50,6 @@ #endif #ifdef _GLIBCXX_USE_SENDFILE # include -#else -# include -# include #endif #if _GLIBCXX_HAVE_UTIME_H # include @@ -416,7 +415,7 @@ namespace #ifdef _GLIBCXX_USE_FCHMOD if (::fchmod(out.fd, from_st->st_mode)) -#elif _GLIBCXX_USE_FCHMODAT +#elif defined _GLIBCXX_USE_FCHMODAT if (::fchmodat(AT_FDCWD, to.c_str(), from_st->st_mode, 0)) #else if (::chmod(to.c_str(), from_st->st_mode)) @@ -428,6 +427,31 @@ namespace #ifdef _GLIBCXX_USE_SENDFILE const auto n = ::sendfile(out.fd, in.fd, nullptr, from_st->st_size); + if (n < 0 && (errno == ENOSYS || errno == EINVAL)) + { +#endif + __gnu_cxx::stdio_filebuf sbin(in.fd, std::ios::in); + __gnu_cxx::stdio_filebuf sbout(out.fd, std::ios::out); + if (sbin.is_open()) + in.fd = -1; + if (sbout.is_open()) + out.fd = -1; + if (from_st->st_size && !(std::ostream(&sbout) << &sbin)) + { + ec = std::make_error_code(std::errc::io_error); + return false; + } + if (!sbout.close() || !sbin.close()) + { + ec.assign(errno, std::generic_category()); + return false; + } + + ec.clear(); + return true; + +#ifdef _GLIBCXX_USE_SENDFILE + } if (n != from_st->st_size) { ec.assign(errno, std::generic_category()); @@ -438,27 +462,10 @@ namespace ec.assign(errno, std::generic_category()); return false; } -#else - __gnu_cxx::stdio_filebuf sbin(in.fd, std::ios::in); - __gnu_cxx::stdio_filebuf sbout(out.fd, std::ios::out); - if (sbin.is_open()) - in.fd = -1; - if (sbout.is_open()) - out.fd = -1; - if (from_st->st_size && !(std::ostream(&sbout) << &sbin)) - { - ec = std::make_error_code(std::errc::io_error); - return false; - } - if (!sbout.close() || !sbin.close()) - { - ec.assign(errno, std::generic_category()); - return false; - } -#endif ec.clear(); return true; +#endif } } #endif