summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-01 19:48:00 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2015-05-01 19:48:00 +0000
commite16e2d2c4f222095f5b9daeae1d97858ec425165 (patch)
tree0bc46ce80de16433e21de47fde04f7ea8d6ff0b4 /libstdc++-v3/src
parentd1eff9deca0ca0dfd0f1482ff1dab5970c49d9d7 (diff)
downloadgcc-e16e2d2c4f222095f5b9daeae1d97858ec425165.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@222703 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/src')
-rw-r--r--libstdc++-v3/src/filesystem/dir.cc35
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc29
2 files changed, 48 insertions, 16 deletions
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");