From bf53e6a9dd3739538841c4f8f141b1fdedc1eddf Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Fri, 1 May 2015 20:48:00 +0100 Subject: [PATCH] acinclude.m4 (GLIBCXX_ENABLE_FILESYSTEM_TS): Disable when is not available. * acinclude.m4 (GLIBCXX_ENABLE_FILESYSTEM_TS): Disable when is not available. (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for fchmodat. * configure: Regenerate. * config.h.in: Regenerate. * configure.ac: Check for utime.h * include/experimental/fs_path.h (path::string<>) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Remove stray typename keyword. * src/filesystem/dir.cc [!_GLIBCXX_HAVE_DIRENT_H] (DIR, opendir, closedir, dirent, readdir_r): Replace dummy functions with #error. (native_readdir, _Dir::advance): Use readdir when readdir_r is missing. * src/filesystem/ops.cc (do_stat, is_set): Make inline. (last_write_time) [!_GLIBCXX_USE_UTIMENSAT]: Use utime. (permissions) [!_GLIBCXX_USE_FCHMODAT]: Use chmod. (space, temp_directory_path) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Set error_code. From-SVN: r222703 --- libstdc++-v3/ChangeLog | 17 ++++++++ libstdc++-v3/acinclude.m4 | 19 ++++++++ libstdc++-v3/config.h.in | 6 +++ libstdc++-v3/configure | 67 ++++++++++++++++++++++++++++- libstdc++-v3/configure.ac | 2 +- libstdc++-v3/include/experimental/fs_path.h | 2 +- libstdc++-v3/src/filesystem/dir.cc | 35 +++++++++------ libstdc++-v3/src/filesystem/ops.cc | 29 ++++++++++++- 8 files changed, 158 insertions(+), 19 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8d559eb..7e07005 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,22 @@ 2015-05-01 Jonathan Wakely + * acinclude.m4 (GLIBCXX_ENABLE_FILESYSTEM_TS): Disable when + is not available. + (GLIBCXX_CHECK_FILESYSTEM_DEPS): Check for fchmodat. + * configure: Regenerate. + * config.h.in: Regenerate. + * configure.ac: Check for utime.h + * include/experimental/fs_path.h (path::string<>) + [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Remove stray typename keyword. + * src/filesystem/dir.cc [!_GLIBCXX_HAVE_DIRENT_H] (DIR, opendir, + closedir, dirent, readdir_r): Replace dummy functions with #error. + (native_readdir, _Dir::advance): Use readdir when readdir_r is missing. + * src/filesystem/ops.cc (do_stat, is_set): Make inline. + (last_write_time) [!_GLIBCXX_USE_UTIMENSAT]: Use utime. + (permissions) [!_GLIBCXX_USE_FCHMODAT]: Use chmod. + (space, temp_directory_path) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Set + error_code. + * include/experimental/fs_path.h (path::_List): Use vector instead of list. * python/libstdcxx/v6/printers.py (StdExpPathPrinter): Adapt. diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4 index 9d8d96d..07b5bd7 100644 --- a/libstdc++-v3/acinclude.m4 +++ b/libstdc++-v3/acinclude.m4 @@ -3914,6 +3914,9 @@ AC_DEFUN([GLIBCXX_ENABLE_FILESYSTEM_TS], [ [permit yes|no|auto]) AC_MSG_CHECKING([whether to build Filesystem TS support]) + if test x"$ac_cv_header_dirent_h" != x"yes"; then + enable_libstdcxx_filesystem_ts=no + fi if test x"$enable_libstdcxx_filesystem_ts" = x"auto"; then case "${target_os}" in freebsd*|netbsd*|openbsd*|dragonfly*|darwin*) @@ -3993,6 +3996,22 @@ dnl fi AC_MSG_RESULT($glibcxx_cv_st_mtim) dnl + AC_MSG_CHECKING([for fchmodat]) + AC_CACHE_VAL(glibcxx_cv_fchmodat, [dnl + GCC_TRY_COMPILE_OR_LINK( + [ + #include + #include + ], + [fchmodat(AT_FDCWD, "", 0, AT_SYMLINK_NOFOLLOW);], + [glibcxx_cv_fchmodat=yes], + [glibcxx_cv_fchmodat=no]) + ]) + if test $glibcxx_cv_fchmodat = yes; then + AC_DEFINE(_GLIBCXX_USE_FCHMODAT, 1, [Define if fchmodat is available in .]) + fi + AC_MSG_RESULT($glibcxx_cv_fchmodat) +dnl CXXFLAGS="$ac_save_CXXFLAGS" AC_LANG_RESTORE ]) diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index d763d1b..88d56b5 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -475,6 +475,9 @@ /* Defined if usleep exists. */ #undef HAVE_USLEEP +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIME_H + /* Defined if vfwscanf exists. */ #undef HAVE_VFWSCANF @@ -848,6 +851,9 @@ this host. */ #undef _GLIBCXX_USE_DECIMAL_FLOAT +/* Define if fchmodat is available in . */ +#undef _GLIBCXX_USE_FCHMODAT + /* Define if __float128 is supported on this host. */ #undef _GLIBCXX_USE_FLOAT128 diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 5ecfdeb..90a5192 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -78928,7 +78928,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # For Filesystem TS. -for ac_header in fcntl.h dirent.h sys/statvfs.h +for ac_header in fcntl.h dirent.h sys/statvfs.h utime.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -79154,6 +79154,9 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build Filesystem TS support" >&5 $as_echo_n "checking whether to build Filesystem TS support... " >&6; } + if test x"$ac_cv_header_dirent_h" != x"yes"; then + enable_libstdcxx_filesystem_ts=no + fi if test x"$enable_libstdcxx_filesystem_ts" = x"auto"; then case "${target_os}" in freebsd*|netbsd*|openbsd*|dragonfly*|darwin*) @@ -79369,6 +79372,68 @@ $as_echo "#define _GLIBCXX_USE_ST_MTIM 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_st_mtim" >&5 $as_echo "$glibcxx_cv_st_mtim" >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fchmodat" >&5 +$as_echo_n "checking for fchmodat... " >&6; } + if test "${glibcxx_cv_fchmodat+set}" = set; 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 + #include + +int +main () +{ +fchmodat(AT_FDCWD, "", 0, AT_SYMLINK_NOFOLLOW); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + glibcxx_cv_fchmodat=yes +else + glibcxx_cv_fchmodat=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 + #include + +int +main () +{ +fchmodat(AT_FDCWD, "", 0, AT_SYMLINK_NOFOLLOW); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_link "$LINENO"; then : + glibcxx_cv_fchmodat=yes +else + glibcxx_cv_fchmodat=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi + +fi + + if test $glibcxx_cv_fchmodat = yes; then + +$as_echo "#define _GLIBCXX_USE_FCHMODAT 1" >>confdefs.h + + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $glibcxx_cv_fchmodat" >&5 +$as_echo "$glibcxx_cv_fchmodat" >&6; } CXXFLAGS="$ac_save_CXXFLAGS" ac_ext=c ac_cpp='$CPP $CPPFLAGS' diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index 4b39bfa..311baa5 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -403,7 +403,7 @@ GLIBCXX_CONFIGURE_TESTSUITE GLIBCXX_CHECK_GTHREADS # For Filesystem TS. -AC_CHECK_HEADERS([fcntl.h dirent.h sys/statvfs.h]) +AC_CHECK_HEADERS([fcntl.h dirent.h sys/statvfs.h utime.h]) AC_STRUCT_DIRENT_D_TYPE GLIBCXX_ENABLE_FILESYSTEM_TS GLIBCXX_CHECK_FILESYSTEM_DEPS diff --git a/libstdc++-v3/include/experimental/fs_path.h b/libstdc++-v3/include/experimental/fs_path.h index e57a08b..33a16db 100644 --- a/libstdc++-v3/include/experimental/fs_path.h +++ b/libstdc++-v3/include/experimental/fs_path.h @@ -781,7 +781,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 const value_type* __last = __first + _M_pathname.size(); #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - using _CharAlloc = typename __alloc_rebind<_Allocator, char>; + using _CharAlloc = __alloc_rebind<_Allocator, char>; using _String = basic_string, _CharAlloc>; using _WString = basic_string<_CharT, _Traits, _Allocator>; diff --git a/libstdc++-v3/src/filesystem/dir.cc b/libstdc++-v3/src/filesystem/dir.cc index 4ed869e..016a78d 100644 --- a/libstdc++-v3/src/filesystem/dir.cc +++ b/libstdc++-v3/src/filesystem/dir.cc @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #ifdef _GLIBCXX_HAVE_DIRENT_H @@ -34,17 +33,12 @@ # endif # include #else -// TODO: replace dummy definitions with suitable Win32 code -#ifndef EACCES -# define EACCES static_cast(std::errc::permission_denied) +# error "the header is needed to build the Filesystem TS" #endif -using DIR = void; -using P = std::experimental::filesystem::path; -static DIR* opendir(const P::value_type*) { return nullptr; } -static void closedir(DIR*) { } -struct dirent { const char* d_name; }; -static inline int readdir_r(DIR*, dirent*, dirent**) -{ return static_cast(std::errc::not_supported); } + +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS +# undef opendir +# define opendir _wopendir #endif namespace fs = std::experimental::filesystem; @@ -97,7 +91,7 @@ struct fs::_Dir namespace { template - bool is_set(Bitmask obj, Bitmask bits) + inline bool is_set(Bitmask obj, Bitmask bits) { return (obj & bits) != Bitmask::none; } @@ -159,14 +153,27 @@ namespace return fs::file_type::none; #endif } + + int + native_readdir(DIR* dirp, ::dirent*& entryp) + { +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + errno = 0; + if ((entryp = ::readdir(dirp))) + return 0; + return errno; +#else + return ::readdir_r(dirp, entryp, &entryp); +#endif + } } bool fs::_Dir::advance(ErrorCode ec) { ::dirent ent; - ::dirent* result; - if (int err = readdir_r(dirp, &ent, &result)) + ::dirent* result = &ent; + if (int err = native_readdir(dirp, result)) { if (!ec) _GLIBCXX_THROW_OR_ABORT(filesystem_error( diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc index 091ca72..c7e3960 100644 --- a/libstdc++-v3/src/filesystem/ops.cc +++ b/libstdc++-v3/src/filesystem/ops.cc @@ -47,6 +47,16 @@ # include # include #endif +#if _GLIBCXX_HAVE_UTIME_H +# include +#endif + +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS +# undef utime +# define utime _wutime +# undef chmod +# define chmod _wchmod +#endif namespace fs = std::experimental::filesystem; @@ -131,7 +141,7 @@ fs::copy(const path& from, const path& to, copy_options options) namespace { template - bool is_set(Bitmask obj, Bitmask bits) + inline bool is_set(Bitmask obj, Bitmask bits) { return (obj & bits) != Bitmask::none; } @@ -767,7 +777,7 @@ fs::file_size(const path& p) namespace { template - T + inline T do_stat(const fs::path& p, std::error_code& ec, Accessor f, T deflt) { #ifdef _GLIBCXX_HAVE_SYS_STAT_H @@ -871,6 +881,14 @@ fs::last_write_time(const path& p __attribute__((__unused__)), ec.assign(errno, std::generic_category()); else ec.clear(); +#elif _GLIBCXX_HAVE_UTIME_H + ::utimbuf times; + times.modtime = s.count(); + times.actime = do_stat(p, ec, std::mem_fn(&stat::st_atime), times.modtime); + if (::utime(p.c_str(), ×)) + ec.assign(errno, std::generic_category()); + else + ec.clear(); #else ec = std::make_error_code(std::errc::not_supported); #endif @@ -887,7 +905,11 @@ fs::permissions(const path& p, perms prms) void fs::permissions(const path& p, perms prms, error_code& ec) noexcept { +#if _GLIBCXX_USE_FCHMODAT if (int err = ::fchmodat(AT_FDCWD, p.c_str(), static_cast(prms), 0)) +#else + if (int err = ::chmod(p.c_str(), static_cast(prms))) +#endif ec.assign(err, std::generic_category()); else ec.clear(); @@ -1051,6 +1073,8 @@ fs::space(const path& p, error_code& ec) noexcept }; ec.clear(); } +#else + ec = std::make_error_code(std::errc::not_supported); #endif return info; } @@ -1157,6 +1181,7 @@ fs::path fs::temp_directory_path() fs::path fs::temp_directory_path(error_code& ec) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + ec = std::make_error_code(std::errc::not_supported); return {}; // TODO #else const char* tmpdir = ::getenv("TMPDIR"); -- 2.7.4