summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libstdc++-v3/ChangeLog17
-rw-r--r--libstdc++-v3/acinclude.m419
-rw-r--r--libstdc++-v3/config.h.in6
-rwxr-xr-xlibstdc++-v3/configure67
-rw-r--r--libstdc++-v3/configure.ac2
-rw-r--r--libstdc++-v3/include/experimental/fs_path.h2
-rw-r--r--libstdc++-v3/src/filesystem/dir.cc35
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc29
8 files changed, 158 insertions, 19 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 8d559eb0975..7e070057105 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,22 @@
2015-05-01 Jonathan Wakely <jwakely@redhat.com>
+ * acinclude.m4 (GLIBCXX_ENABLE_FILESYSTEM_TS): Disable when <dirent.h>
+ 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 9d8d96d7465..07b5bd70ab3 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 <fcntl.h>
+ #include <sys/stat.h>
+ ],
+ [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 <sys/stat.h>.])
+ 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 d763d1bc326..88d56b5ad59 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 <utime.h> 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 <sys/stat.h>. */
+#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 5ecfdebbaaf..90a5192db80 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 <fcntl.h>
+ #include <sys/stat.h>
+
+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 <fcntl.h>
+ #include <sys/stat.h>
+
+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 4b39bfa0262..311baa5a4ab 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 e57a08bb35d..33a16dbee56 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<char, char_traits<char>, _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 4ed869ef783..016a78dc91b 100644
--- a/libstdc++-v3/src/filesystem/dir.cc
+++ b/libstdc++-v3/src/filesystem/dir.cc
@@ -25,7 +25,6 @@
#include <experimental/filesystem>
#include <utility>
#include <stack>
-#include <tuple>
#include <string.h>
#include <errno.h>
#ifdef _GLIBCXX_HAVE_DIRENT_H
@@ -34,17 +33,12 @@
# endif
# include <dirent.h>
#else
-// TODO: replace dummy definitions with suitable Win32 code
-#ifndef EACCES
-# define EACCES static_cast<int>(std::errc::permission_denied)
+# error "the <dirent.h> 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<int>(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<typename Bitmask>
- 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 091ca722fbb..c7e3960be86 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -47,6 +47,16 @@
# include <ext/stdio_filebuf.h>
# include <ostream>
#endif
+#if _GLIBCXX_HAVE_UTIME_H
+# include <utime.h>
+#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<typename Bitmask>
- 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<typename Accessor, typename T>
- 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(), &times))
+ 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<mode_t>(prms), 0))
+#else
+ if (int err = ::chmod(p.c_str(), static_cast<mode_t>(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");