mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-10 11:17:10 +08:00
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
This commit is contained in:
parent
f4bf2aabe3
commit
cf4b581f2e
@ -1,3 +1,19 @@
|
||||
2019-01-07 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-01-06 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/86756
|
||||
|
@ -4589,6 +4589,19 @@ dnl
|
||||
AC_DEFINE(HAVE_SYMLINK, 1, [Define if symlink is available in <unistd.h>.])
|
||||
fi
|
||||
AC_MSG_RESULT($glibcxx_cv_symlink)
|
||||
dnl
|
||||
AC_MSG_CHECKING([for truncate])
|
||||
AC_CACHE_VAL(glibcxx_cv_truncate, [dnl
|
||||
GCC_TRY_COMPILE_OR_LINK(
|
||||
[#include <unistd.h>],
|
||||
[truncate("", 99);],
|
||||
[glibcxx_cv_truncate=yes],
|
||||
[glibcxx_cv_truncate=no])
|
||||
])
|
||||
if test $glibcxx_cv_truncate = yes; then
|
||||
AC_DEFINE(HAVE_TRUNCATE, 1, [Define if truncate is available in <unistd.h>.])
|
||||
fi
|
||||
AC_MSG_RESULT($glibcxx_cv_truncate)
|
||||
dnl
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
AC_LANG_RESTORE
|
||||
|
@ -511,6 +511,9 @@
|
||||
/* Define to 1 if the target supports thread-local storage. */
|
||||
#undef HAVE_TLS
|
||||
|
||||
/* Define if truncate is available in <unistd.h>. */
|
||||
#undef HAVE_TRUNCATE
|
||||
|
||||
/* Define to 1 if you have the <uchar.h> header file. */
|
||||
#undef HAVE_UCHAR_H
|
||||
|
||||
|
@ -2167,31 +2167,35 @@ GLIBCXX_3.4.26 {
|
||||
_ZNSt10filesystem7__cxx114pathpLERKS1_;
|
||||
_ZT[IV]NSt10filesystem7__cxx1116filesystem_errorE;
|
||||
|
||||
_ZNSt10filesystem10equivalent*;
|
||||
_ZNSt10filesystem10remove_all*;
|
||||
_ZNSt10filesystem11permissions*;
|
||||
_ZNSt10filesystem12current_path*;
|
||||
_ZNSt10filesystem12read_symlink*;
|
||||
_ZNSt10filesystem14create_symlink*;
|
||||
_ZNSt10filesystem14symlink_status*;
|
||||
_ZNSt10filesystem15last_write_time*;
|
||||
_ZNSt10filesystem16create_directory*;
|
||||
_ZNSt10filesystem16create_hard_link*;
|
||||
_ZNSt10filesystem16weakly_canonical*;
|
||||
_ZNSt10filesystem18create_directories*;
|
||||
_ZNSt10filesystem19temp_directory_path*;
|
||||
_ZNSt10filesystem24create_directory_symlink*;
|
||||
_ZNSt10filesystem4copy*;
|
||||
_ZNSt10filesystem5space*;
|
||||
_ZNSt10filesystem6remove*;
|
||||
_ZNSt10filesystem6status*;
|
||||
_ZNSt10filesystem8absolute*;
|
||||
_ZNSt10filesystem8is_empty*;
|
||||
_ZNSt10filesystem8relative*;
|
||||
_ZNSt10filesystem9canonical*;
|
||||
_ZNSt10filesystem4copy*;
|
||||
_ZNSt10filesystem9copy_file*;
|
||||
_ZNSt10filesystem12copy_symlink*;
|
||||
_ZNSt10filesystem18create_directories*;
|
||||
_ZNSt10filesystem16create_directory*;
|
||||
_ZNSt10filesystem24create_directory_symlink*;
|
||||
_ZNSt10filesystem16create_hard_link*;
|
||||
_ZNSt10filesystem14create_symlink*;
|
||||
_ZNSt10filesystem12current_path*;
|
||||
_ZNSt10filesystem10equivalent*;
|
||||
_ZNSt10filesystem9file_size*;
|
||||
_ZNSt10filesystem15hard_link_count*;
|
||||
_ZNSt10filesystem8is_empty*;
|
||||
_ZNSt10filesystem15last_write_time*;
|
||||
_ZNSt10filesystem11permissions*;
|
||||
_ZNSt10filesystem9proximate*;
|
||||
_ZNSt10filesystem12read_symlink*;
|
||||
_ZNSt10filesystem8relative*;
|
||||
_ZNSt10filesystem6remove*;
|
||||
_ZNSt10filesystem10remove_all*;
|
||||
_ZNSt10filesystem6rename*;
|
||||
_ZNSt10filesystem11resize_file*;
|
||||
_ZNSt10filesystem5space*;
|
||||
_ZNSt10filesystem6status*;
|
||||
_ZNSt10filesystem14symlink_status*;
|
||||
_ZNSt10filesystem19temp_directory_path*;
|
||||
_ZNSt10filesystem16weakly_canonical*;
|
||||
|
||||
_ZNKSt10filesystem18directory_iteratordeEv;
|
||||
_ZNKSt10filesystem28recursive_directory_iterator5depthEv;
|
||||
|
56
libstdc++-v3/configure
vendored
56
libstdc++-v3/configure
vendored
@ -81038,6 +81038,62 @@ $as_echo "#define HAVE_SYMLINK 1" >>confdefs.h
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_symlink" >&5
|
||||
$as_echo "$glibcxx_cv_symlink" >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for truncate" >&5
|
||||
$as_echo_n "checking for truncate... " >&6; }
|
||||
if ${glibcxx_cv_truncate+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
if test x$gcc_no_link = xyes; then
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <unistd.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
truncate("", 99);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
glibcxx_cv_truncate=yes
|
||||
else
|
||||
glibcxx_cv_truncate=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
else
|
||||
if test x$gcc_no_link = xyes; then
|
||||
as_fn_error $? "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
|
||||
fi
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <unistd.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
truncate("", 99);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_link "$LINENO"; then :
|
||||
glibcxx_cv_truncate=yes
|
||||
else
|
||||
glibcxx_cv_truncate=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if test $glibcxx_cv_truncate = yes; then
|
||||
|
||||
$as_echo "#define HAVE_TRUNCATE 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_truncate" >&5
|
||||
$as_echo "$glibcxx_cv_truncate" >&6; }
|
||||
CXXFLAGS="$ac_save_CXXFLAGS"
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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; }
|
||||
|
188
libstdc++-v3/testsuite/27_io/filesystem/operations/all.cc
Normal file
188
libstdc++-v3/testsuite/27_io/filesystem/operations/all.cc
Normal file
@ -0,0 +1,188 @@
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
// Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++17 -fno-inline" }
|
||||
// { dg-do link { target c++17 } }
|
||||
|
||||
// C++17 30.10.15 Filesystem operation functions [fs.op.funcs]
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
// Link-only test to ensure all operation functions are exported from the lib.
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
const std::filesystem::path p;
|
||||
std::filesystem::path p2;
|
||||
const std::filesystem::copy_options copyopts{};
|
||||
const std::filesystem::file_status st{};
|
||||
std::filesystem::file_status st2;
|
||||
const std::filesystem::file_time_type t;
|
||||
std::filesystem::file_time_type t2;
|
||||
const std::filesystem::perms perms{};
|
||||
const std::filesystem::perm_options permopts{};
|
||||
std::filesystem::space_info sp;
|
||||
std::error_code ec;
|
||||
bool b;
|
||||
std::uintmax_t size;
|
||||
|
||||
std::filesystem::absolute(p);
|
||||
std::filesystem::absolute(p, ec);
|
||||
|
||||
std::filesystem::canonical(p);
|
||||
std::filesystem::canonical(p, ec);
|
||||
|
||||
std::filesystem::copy(p, p);
|
||||
std::filesystem::copy(p, p, ec);
|
||||
std::filesystem::copy(p, p, copyopts);
|
||||
std::filesystem::copy(p, p, copyopts, ec);
|
||||
|
||||
std::filesystem::copy_file(p, p);
|
||||
std::filesystem::copy_file(p, p, ec);
|
||||
std::filesystem::copy_file(p, p, copyopts);
|
||||
std::filesystem::copy_file(p, p, copyopts, ec);
|
||||
|
||||
std::filesystem::copy_symlink(p, p);
|
||||
std::filesystem::copy_symlink(p, p, ec);
|
||||
|
||||
std::filesystem::create_directories(p);
|
||||
std::filesystem::create_directories(p, ec);
|
||||
|
||||
std::filesystem::create_directory(p);
|
||||
std::filesystem::create_directory(p, ec);
|
||||
|
||||
std::filesystem::create_directory(p, p);
|
||||
std::filesystem::create_directory(p, p, ec);
|
||||
|
||||
std::filesystem::create_directory_symlink(p, p);
|
||||
std::filesystem::create_directory_symlink(p, p, ec);
|
||||
|
||||
std::filesystem::create_hard_link(p, p);
|
||||
std::filesystem::create_hard_link(p, p, ec);
|
||||
|
||||
std::filesystem::create_symlink(p, p);
|
||||
std::filesystem::create_symlink(p, p, ec);
|
||||
|
||||
p2 = std::filesystem::current_path();
|
||||
p2 = std::filesystem::current_path(ec);
|
||||
std::filesystem::current_path(p);
|
||||
std::filesystem::current_path(p, ec);
|
||||
|
||||
b = std::filesystem::equivalent(p, p);
|
||||
b = std::filesystem::equivalent(p, p, ec);
|
||||
|
||||
b = std::filesystem::exists(st);
|
||||
b = std::filesystem::exists(p);
|
||||
b = std::filesystem::exists(p, ec);
|
||||
|
||||
size = std::filesystem::file_size(p);
|
||||
size = std::filesystem::file_size(p, ec);
|
||||
|
||||
size = std::filesystem::hard_link_count(p);
|
||||
size = std::filesystem::hard_link_count(p, ec);
|
||||
|
||||
b = std::filesystem::is_block_file(st);
|
||||
b = std::filesystem::is_block_file(p);
|
||||
b = std::filesystem::is_block_file(p, ec);
|
||||
|
||||
b = std::filesystem::is_character_file(st);
|
||||
b = std::filesystem::is_character_file(p);
|
||||
b = std::filesystem::is_character_file(p, ec);
|
||||
|
||||
b = std::filesystem::is_directory(st);
|
||||
b = std::filesystem::is_directory(p);
|
||||
b = std::filesystem::is_directory(p, ec);
|
||||
|
||||
b = std::filesystem::is_empty(p);
|
||||
b = std::filesystem::is_empty(p, ec);
|
||||
|
||||
b = std::filesystem::is_fifo(st);
|
||||
b = std::filesystem::is_fifo(p);
|
||||
b = std::filesystem::is_fifo(p, ec);
|
||||
|
||||
b = std::filesystem::is_other(st);
|
||||
b = std::filesystem::is_other(p);
|
||||
b = std::filesystem::is_other(p, ec);
|
||||
|
||||
b = std::filesystem::is_regular_file(st);
|
||||
b = std::filesystem::is_regular_file(p);
|
||||
b = std::filesystem::is_regular_file(p, ec);
|
||||
|
||||
b = std::filesystem::is_socket(st);
|
||||
b = std::filesystem::is_socket(p);
|
||||
b = std::filesystem::is_socket(p, ec);
|
||||
|
||||
b = std::filesystem::is_symlink(st);
|
||||
b = std::filesystem::is_symlink(p);
|
||||
b = std::filesystem::is_symlink(p, ec);
|
||||
|
||||
t2 = std::filesystem::last_write_time(p);
|
||||
t2 = std::filesystem::last_write_time(p, ec);
|
||||
std::filesystem::last_write_time(p, t);
|
||||
std::filesystem::last_write_time(p, t, ec);
|
||||
|
||||
std::filesystem::permissions(p, perms);
|
||||
std::filesystem::permissions(p, perms, permopts);
|
||||
std::filesystem::permissions(p, perms, ec);
|
||||
std::filesystem::permissions(p, perms, permopts, ec);
|
||||
|
||||
p2 = std::filesystem::proximate(p, ec);
|
||||
p2 = std::filesystem::proximate(p);
|
||||
p2 = std::filesystem::proximate(p, p);
|
||||
p2 = std::filesystem::proximate(p, p, ec);
|
||||
|
||||
p2 = std::filesystem::read_symlink(p);
|
||||
p2 = std::filesystem::read_symlink(p, ec);
|
||||
|
||||
p2 = std::filesystem::relative(p, ec);
|
||||
p2 = std::filesystem::relative(p);
|
||||
p2 = std::filesystem::relative(p, p);
|
||||
p2 = std::filesystem::relative(p, p, ec);
|
||||
|
||||
b = std::filesystem::remove(p);
|
||||
b = std::filesystem::remove(p, ec);
|
||||
|
||||
size = std::filesystem::remove_all(p);
|
||||
size = std::filesystem::remove_all(p, ec);
|
||||
|
||||
std::filesystem::rename(p, p);
|
||||
std::filesystem::rename(p, p, ec);
|
||||
|
||||
std::filesystem::resize_file(p, size);
|
||||
std::filesystem::resize_file(p, size, ec);
|
||||
|
||||
sp = std::filesystem::space(p);
|
||||
sp = std::filesystem::space(p, ec);
|
||||
|
||||
st2 = std::filesystem::status(p);
|
||||
st2 = std::filesystem::status(p, ec);
|
||||
|
||||
b = std::filesystem::status_known(st);
|
||||
|
||||
st2 = std::filesystem::symlink_status(p);
|
||||
st2 = std::filesystem::symlink_status(p, ec);
|
||||
|
||||
p2 = std::filesystem::temp_directory_path();
|
||||
p2 = std::filesystem::temp_directory_path(ec);
|
||||
|
||||
p2 = std::filesystem::weakly_canonical(p);
|
||||
p2 = std::filesystem::weakly_canonical(p, ec);
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
// Copyright (C) 2019 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++17" }
|
||||
// { dg-do run { target c++17 } }
|
||||
|
||||
// C++17 30.10.15.33 Resize file [fs.op.resize_file]
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <testsuite_fs.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
auto p = __gnu_test::nonexistent_path();
|
||||
std::error_code ec;
|
||||
resize_file(p, 0, ec);
|
||||
VERIFY( ec );
|
||||
ec = {};
|
||||
resize_file(p, 1, ec);
|
||||
VERIFY( ec );
|
||||
|
||||
__gnu_test::scoped_file f(p);
|
||||
std::ofstream{p} << "some text";
|
||||
std::ifstream fin;
|
||||
std::string input;
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_TRUNCATE
|
||||
resize_file(p, 4, ec);
|
||||
VERIFY( !ec );
|
||||
fin.open(p);
|
||||
getline(fin, input);
|
||||
VERIFY( input.length() == 4 );
|
||||
fin.close();
|
||||
|
||||
resize_file(p, 2);
|
||||
fin.open(p);
|
||||
getline(fin, input);
|
||||
VERIFY( input.length() == 2 );
|
||||
fin.close();
|
||||
#endif
|
||||
|
||||
resize_file(p, 0, ec);
|
||||
VERIFY( !ec );
|
||||
fin.open(p);
|
||||
getline(fin, input);
|
||||
VERIFY( input.length() == 0 );
|
||||
fin.close();
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
}
|
Loading…
Reference in New Issue
Block a user