acinclude.m4 (GLIBCXX_ENABLE_FILESYSTEM_TS): Disable when <dirent.h> is not available.

* 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.

From-SVN: r222703
This commit is contained in:
Jonathan Wakely 2015-05-01 20:48:00 +01:00 committed by Jonathan Wakely
parent a00d74c490
commit bf53e6a9dd
8 changed files with 158 additions and 19 deletions

View File

@ -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.

View File

@ -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*)
@ -3992,6 +3995,22 @@ dnl
AC_DEFINE(_GLIBCXX_USE_ST_MTIM, 1, [Define if struct stat has timespec members.])
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

View File

@ -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

View File

@ -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'

View File

@ -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

View File

@ -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>;

View File

@ -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;
}
@ -157,6 +151,19 @@ namespace
}
#else
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
}
}
@ -165,8 +172,8 @@ 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(

View File

@ -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");