diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2019-01-07 12:38:51 +0000 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2019-01-07 12:38:51 +0000 |
commit | cf4b581f2e28368c01fe93792ebc6eefb2bc8116 (patch) | |
tree | e97aa3a3f62308d35f617bfdfd0d7cc819e035dd /libstdc++-v3/src | |
parent | f4bf2aabe36633d75852313caafe7efab71d5ba7 (diff) |
Fix build for systems without POSIX truncate
Older versions of newlib do not provide truncate so add a configure
check for it, and provide a fallback definition.
There were also some missing exports in the linker script, which went
unnoticed because there are no tests for some functions. A new link-only
test checks that every filesystem operation function is defined by the
library.
* acinclude.m4 (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for truncate.
* config.h.in: Regenerate.
* config/abi/pre/gnu.ver: Order patterns for filesystem operations
alphabetically and add missing entries for copy_symlink,
hard_link_count, rename, and resize_file.
* configure: Regenerate.
* src/c++17/fs_ops.cc (resize_file): Remove #if so posix::truncate is
used unconditionally.
* src/filesystem/ops-common.h (__gnu_posix::truncate)
[!_GLIBCXX_HAVE_TRUNCATE]: Provide fallback definition that only
supports truncating to zero length.
* testsuite/27_io/filesystem/operations/all.cc: New test.
* testsuite/27_io/filesystem/operations/resize_file.cc: New test.
From-SVN: r267647
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r-- | libstdc++-v3/src/c++17/fs_ops.cc | 4 | ||||
-rw-r--r-- | libstdc++-v3/src/filesystem/ops-common.h | 19 |
2 files changed, 19 insertions, 4 deletions
diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc index fd8cf353ba2..edd9315980b 100644 --- a/libstdc++-v3/src/c++17/fs_ops.cc +++ b/libstdc++-v3/src/c++17/fs_ops.cc @@ -1268,16 +1268,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<uintmax_t>(std::numeric_limits<off_t>::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 } diff --git a/libstdc++-v3/src/filesystem/ops-common.h b/libstdc++-v3/src/filesystem/ops-common.h index f20867c217e..55e482ff8f2 100644 --- a/libstdc++-v3/src/filesystem/ops-common.h +++ b/libstdc++-v3/src/filesystem/ops-common.h @@ -29,6 +29,9 @@ #ifdef _GLIBCXX_HAVE_UNISTD_H # include <unistd.h> +# ifdef _GLIBCXX_HAVE_FCNTL_H +# include <fcntl.h> // AT_FDCWD, O_TRUNC etc. +# endif # if defined(_GLIBCXX_HAVE_SYS_STAT_H) && defined(_GLIBCXX_HAVE_SYS_TYPES_H) # include <sys/types.h> # include <sys/stat.h> @@ -139,7 +142,23 @@ namespace __gnu_posix using ::utime; # endif using ::rename; +# ifdef _GLIBCXX_HAVE_TRUNCATE using ::truncate; +# else + inline int truncate(const char* path, off_t length) + { + if (length == 0) + { + const int fd = ::open(path, O_WRONLY|O_TRUNC); + if (fd == -1) + return fd; + ::close(fd); + return 0; + } + errno = ENOTSUP; + return -1; + } +# endif using char_type = char; #else // ! _GLIBCXX_FILESYSTEM_IS_WINDOWS && ! _GLIBCXX_HAVE_UNISTD_H inline int open(const char*, int, ...) { errno = ENOTSUP; return -1; } |