From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 44E7B385842B; Fri, 1 Oct 2021 19:39:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 44E7B385842B MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r12-4071] libstdc++: Avoid unconditional use of errc::not_supported [PR 99327] X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/master X-Git-Oldrev: d71476c9df931f3ca674941f1942b03eabea010d X-Git-Newrev: 59ffa3e3dba5a7805585c61dd4387c5644249d52 Message-Id: <20211001193910.44E7B385842B@sourceware.org> Date: Fri, 1 Oct 2021 19:39:10 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Oct 2021 19:39:10 -0000 https://gcc.gnu.org/g:59ffa3e3dba5a7805585c61dd4387c5644249d52 commit r12-4071-g59ffa3e3dba5a7805585c61dd4387c5644249d52 Author: Jonathan Wakely Date: Tue May 11 18:47:18 2021 +0100 libstdc++: Avoid unconditional use of errc::not_supported [PR 99327] The errc::not_supported constant is only defined if ENOTSUP is defined, which is not true for all targets. Many uses of errc::not_supported in the filesystem library do not actually match the intended meaning of ENOTSUP described by POSIX. They should be using ENOSYS instead (i.e. errc::function_not_supported). This change ensures that appropriate error codes are used by the filesystem library. The remaining uses of errc::not_supported are replaced with a call to a new helper function so that an alternative value will be used on targets that don't support errc::not_supported. Signed-off-by: Jonathan Wakely libstdc++-v3/ChangeLog: PR libstdc++/99327 * src/filesystem/ops-common.h (__unsupported): New function to return a suitable error code for missing functionality. (posix::off_t): New typedef. (posix::*): Set errno to ENOSYS instead of ENOTSUP for no-op fallback implementations. (do_copy_file): Replace uses of errc::not_supported. * src/c++17/fs_ops.cc (fs::copy, fs::copy_file, create_dir) (fs::create_directory, fs::create_directory_symlink) (fs::create_hard_link, fs::create_symlink, fs::current_path) (fs::equivalent, do_stat, fs::file_size, fs::hard_link_count) (fs::last_write_time, fs::permissions, fs::read_symlink): Replace uses of errc::not_supported. (fs::resize_file): Qualify off_t. * src/filesystem/ops.cc (fs::copy, fs::copy_file, create_dir) (fs::create_directory, fs::create_directory_symlink) (fs::create_hard_link, fs::create_symlink, fs::current_path) (fs::equivalent, do_stat, fs::file_size, fs::last_write_time) (fs::permissions, fs::read_symlink, fs::system_complete): Replace uses of errc::not_supported. (fs::resize_file): Qualify off_t and enable unconditionally. * testsuite/19_diagnostics/system_error/cons-1.cc: Likewise. Diff: --- libstdc++-v3/src/c++17/fs_ops.cc | 42 +++++++++--------- libstdc++-v3/src/filesystem/ops-common.h | 51 +++++++++++++++++----- libstdc++-v3/src/filesystem/ops.cc | 40 ++++++++--------- .../19_diagnostics/system_error/cons-1.cc | 6 +-- 4 files changed, 81 insertions(+), 58 deletions(-) diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc index 4f3715bbbec..cb2dc2c617e 100644 --- a/libstdc++-v3/src/c++17/fs_ops.cc +++ b/libstdc++-v3/src/c++17/fs_ops.cc @@ -353,7 +353,7 @@ fs::copy(const path& from, const path& to, copy_options options, } if (is_other(f) || is_other(t)) { - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::invalid_argument); return; } if (is_directory(f) && is_regular_file(t)) @@ -412,7 +412,7 @@ fs::copy(const path& from, const path& to, copy_options options, else ec.clear(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -435,7 +435,7 @@ fs::copy_file(const path& from, const path& to, copy_options options, return do_copy_file(from.c_str(), to.c_str(), copy_file_options(options), nullptr, nullptr, ec); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); return false; #endif } @@ -583,7 +583,7 @@ namespace created = true; } #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return created; } @@ -631,7 +631,7 @@ fs::create_directory(const path& p, const path& attributes, } return create_dir(p, static_cast(st.st_mode), ec); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_function_not_supported); return false; #endif } @@ -652,7 +652,7 @@ fs::create_directory_symlink(const path& to, const path& new_symlink, error_code& ec) noexcept { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #else create_symlink(to, new_symlink, ec); #endif @@ -684,7 +684,7 @@ fs::create_hard_link(const path& to, const path& new_hard_link, else ec = __last_system_error(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -708,7 +708,7 @@ fs::create_symlink(const path& to, const path& new_symlink, else ec.clear(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -776,7 +776,7 @@ fs::current_path(error_code& ec) } #endif // __GLIBC__ #else // _GLIBCXX_HAVE_UNISTD_H - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return p; } @@ -799,7 +799,7 @@ fs::current_path(const path& p, error_code& ec) noexcept else ec.clear(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -839,7 +839,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept { if (is_other(s1) && is_other(s2)) { - ec = std::make_error_code(std::errc::not_supported); + ec = std::__unsupported(); return false; } ec.clear(); @@ -897,7 +897,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept ec.clear(); return false; #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return false; } @@ -928,7 +928,7 @@ namespace ec.clear(); return f(st); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); return deflt; #endif } @@ -953,10 +953,10 @@ fs::file_size(const path& p, error_code& ec) noexcept if (s.type == file_type::directory) ec = std::make_error_code(std::errc::is_a_directory); else - ec = std::make_error_code(std::errc::not_supported); + ec = std::__unsupported(); } #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return -1; } @@ -978,7 +978,7 @@ fs::hard_link_count(const path& p, error_code& ec) noexcept return do_stat(p, ec, std::mem_fn(&stat_type::st_nlink), static_cast(-1)); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); return static_cast(-1); #endif } @@ -1026,7 +1026,7 @@ fs::last_write_time(const path& p, error_code& ec) noexcept }, file_time_type::min()); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); return file_time_type::min(); #endif } @@ -1072,7 +1072,7 @@ fs::last_write_time(const path& p, else ec.clear(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -1121,7 +1121,7 @@ fs::permissions(const path& p, perms prms, perm_options opts, err = errno; #else if (nofollow && is_symlink(st)) - ec = std::make_error_code(std::errc::not_supported); + ec = std::__unsupported(); else if (posix::chmod(p.c_str(), static_cast(prms))) err = errno; #endif @@ -1206,7 +1206,7 @@ fs::path fs::read_symlink(const path& p, error_code& ec) } while (true); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return result; } @@ -1434,7 +1434,7 @@ fs::resize_file(const path& p, uintmax_t size) void fs::resize_file(const path& p, uintmax_t size, error_code& ec) noexcept { - if (size > static_cast(std::numeric_limits::max())) + if (size > static_cast(std::numeric_limits::max())) ec.assign(EINVAL, std::generic_category()); else if (posix::truncate(p.c_str(), size)) ec.assign(errno, std::generic_category()); diff --git a/libstdc++-v3/src/filesystem/ops-common.h b/libstdc++-v3/src/filesystem/ops-common.h index e999e11b422..90ebeba7f01 100644 --- a/libstdc++-v3/src/filesystem/ops-common.h +++ b/libstdc++-v3/src/filesystem/ops-common.h @@ -69,6 +69,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } + // Get an error code indicating unsupported functionality. + // + // This should be used when a function is unable to behave as specified + // due to an incomplete or partial implementation, e.g. + // filesystem::equivalent(a, b) if is_other(a) && is_other(b) is true. + // + // Use errc::function_not_supported for functions that are entirely + // unimplemented, e.g. create_symlink on Windows. + // + // Use errc::invalid_argument for requests to perform operations outside + // the spec, e.g. trying to copy a directory using filesystem::copy_file. + inline error_code + __unsupported() noexcept + { +#if defined ENOTSUP + return std::make_error_code(std::errc::not_supported); +#elif defined EOPNOTSUPP + // This is supposed to be for socket operations + return std::make_error_code(std::errc::operation_not_supported); +#else + return std::make_error_code(std::errc::invalid_argument); +#endif + } + namespace filesystem { namespace __gnu_posix @@ -128,6 +152,7 @@ namespace __gnu_posix return -1; } + using off_t = _off64_t; inline int truncate(const wchar_t* path, _off64_t length) { const int fd = ::_wopen(path, _O_BINARY|_O_RDWR); @@ -164,6 +189,7 @@ namespace __gnu_posix using ::utime; # endif using ::rename; + using ::off_t; # ifdef _GLIBCXX_HAVE_TRUNCATE using ::truncate; # else @@ -183,15 +209,16 @@ namespace __gnu_posix # endif using char_type = char; #else // ! _GLIBCXX_FILESYSTEM_IS_WINDOWS && ! _GLIBCXX_HAVE_UNISTD_H - inline int open(const char*, int, ...) { errno = ENOTSUP; return -1; } - inline int close(int) { errno = ENOTSUP; return -1; } + inline int open(const char*, int, ...) { errno = ENOSYS; return -1; } + inline int close(int) { errno = ENOSYS; return -1; } using mode_t = int; - inline int chmod(const char*, mode_t) { errno = ENOTSUP; return -1; } - inline int mkdir(const char*, mode_t) { errno = ENOTSUP; return -1; } - inline char* getcwd(char*, size_t) { errno = ENOTSUP; return nullptr; } - inline int chdir(const char*) { errno = ENOTSUP; return -1; } - inline int rename(const char*, const char*) { errno = ENOTSUP; return -1; } - inline int truncate(const char*, long) { errno = ENOTSUP; return -1; } + inline int chmod(const char*, mode_t) { errno = ENOSYS; return -1; } + inline int mkdir(const char*, mode_t) { errno = ENOSYS; return -1; } + inline char* getcwd(char*, size_t) { errno = ENOSYS; return nullptr; } + inline int chdir(const char*) { errno = ENOSYS; return -1; } + inline int rename(const char*, const char*) { errno = ENOSYS; return -1; } + using off_t = long; + inline int truncate(const char*, off_t) { errno = ENOSYS; return -1; } using char_type = char; #endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS } // namespace __gnu_posix @@ -374,7 +401,7 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM // 2712. copy_file() has a number of unspecified error conditions if (!is_regular_file(f)) { - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::invalid_argument); return false; } @@ -382,7 +409,7 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM { if (!is_regular_file(t)) { - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::invalid_argument); return false; } @@ -413,7 +440,7 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM } else if (!is_regular_file(t)) { - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::invalid_argument); return false; } } @@ -572,7 +599,7 @@ _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM else ec = std::last_system_error(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } #pragma GCC diagnostic pop diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index cc7117b0cd1..94b4123b878 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -293,7 +293,7 @@ fs::copy(const path& from, const path& to, copy_options options, } if (is_other(f) || is_other(t)) { - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::invalid_argument); return; } if (is_directory(f) && is_regular_file(t)) @@ -372,7 +372,7 @@ fs::copy_file(const path& from, const path& to, copy_options options, return do_copy_file(from.c_str(), to.c_str(), copy_file_options(options), nullptr, nullptr, ec); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); return false; #endif } @@ -491,7 +491,7 @@ namespace created = true; } #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return created; } @@ -539,7 +539,7 @@ fs::create_directory(const path& p, const path& attributes, } return create_dir(p, static_cast(st.st_mode), ec); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); return false; #endif } @@ -560,7 +560,7 @@ fs::create_directory_symlink(const path& to, const path& new_symlink, error_code& ec) noexcept { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #else create_symlink(to, new_symlink, ec); #endif @@ -592,7 +592,7 @@ fs::create_hard_link(const path& to, const path& new_hard_link, else ec = __last_system_error(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -616,7 +616,7 @@ fs::create_symlink(const path& to, const path& new_symlink, else ec.clear(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -683,7 +683,7 @@ fs::current_path(error_code& ec) } #endif // __GLIBC__ #else // _GLIBCXX_HAVE_UNISTD_H - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return p; } @@ -706,7 +706,7 @@ fs::current_path(const path& p, error_code& ec) noexcept else ec.clear(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -746,7 +746,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept { if (is_other(s1) && is_other(s2)) { - ec = std::make_error_code(std::errc::not_supported); + ec = std::__unsupported(); return false; } ec.clear(); @@ -762,7 +762,7 @@ fs::equivalent(const path& p1, const path& p2, error_code& ec) noexcept ec.clear(); return false; #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return false; } @@ -793,7 +793,7 @@ namespace ec.clear(); return f(st); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); return deflt; #endif } @@ -817,7 +817,7 @@ fs::file_size(const path& p, error_code& ec) noexcept if (s.type == file_type::directory) ec = std::make_error_code(std::errc::is_a_directory); else - ec = std::make_error_code(std::errc::not_supported); + ec = std::__unsupported(); } return -1; } @@ -920,7 +920,7 @@ fs::last_write_time(const path& p __attribute__((__unused__)), else ec.clear(); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif } @@ -967,7 +967,7 @@ fs::permissions(const path& p, perms prms, error_code& ec) noexcept err = errno; #else if (nofollow && is_symlink(st)) - ec = std::make_error_code(std::errc::operation_not_supported); + ec = std::__unsupported(); else if (posix::chmod(p.c_str(), static_cast(prms))) err = errno; #endif @@ -1032,7 +1032,7 @@ fs::path fs::read_symlink(const path& p [[gnu::unused]], error_code& ec) } while (true); #else - ec = std::make_error_code(std::errc::not_supported); + ec = std::make_error_code(std::errc::function_not_supported); #endif return result; } @@ -1153,16 +1153,12 @@ fs::resize_file(const path& p, uintmax_t size) void fs::resize_file(const path& p, uintmax_t size, error_code& ec) noexcept { -#ifdef _GLIBCXX_HAVE_UNISTD_H - if (size > static_cast(std::numeric_limits::max())) + if (size > static_cast(std::numeric_limits::max())) ec.assign(EINVAL, std::generic_category()); else if (posix::truncate(p.c_str(), size)) ec.assign(errno, std::generic_category()); else ec.clear(); -#else - ec = std::make_error_code(std::errc::not_supported); -#endif } @@ -1280,7 +1276,7 @@ fs::system_complete(const path& p, error_code& ec) || p.root_name() == base.root_name()) return absolute(p, base); // else TODO - ec = std::make_error_code(std::errc::not_supported); + ec = std::__unsupported(); return {}; #else if (ec.value()) diff --git a/libstdc++-v3/testsuite/19_diagnostics/system_error/cons-1.cc b/libstdc++-v3/testsuite/19_diagnostics/system_error/cons-1.cc index effb6709f8b..168a6fca2a9 100644 --- a/libstdc++-v3/testsuite/19_diagnostics/system_error/cons-1.cc +++ b/libstdc++-v3/testsuite/19_diagnostics/system_error/cons-1.cc @@ -26,19 +26,19 @@ int main() { const std::string s("too late: boulangerie out of pain au raisin"); const std::error_code - e(std::make_error_code(std::errc::operation_not_supported)); + e(std::make_error_code(std::errc::invalid_argument)); // 1 { std::system_error err1(e, s); - VERIFY( err1.code() == e ); + VERIFY( err1.code() == e ); VERIFY( std::string(err1.what()).find(s) != std::string::npos ); } // 2 { std::system_error err2(95, std::system_category(), s); - VERIFY( err2.code() == std::error_code(95, std::system_category()) ); + VERIFY( err2.code() == std::error_code(95, std::system_category()) ); VERIFY( std::string((err2.what(), s)).find(s) != std::string::npos ); }