summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2019-01-07 12:38:51 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2019-01-07 12:38:51 +0000
commitcf4b581f2e28368c01fe93792ebc6eefb2bc8116 (patch)
treee97aa3a3f62308d35f617bfdfd0d7cc819e035dd /libstdc++-v3/src
parentf4bf2aabe36633d75852313caafe7efab71d5ba7 (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.cc4
-rw-r--r--libstdc++-v3/src/filesystem/ops-common.h19
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; }