2015-04-30 20:11:52 +01:00
|
|
|
// -*- C++ -*-
|
|
|
|
// Filesystem utils for the C++ library testsuite.
|
|
|
|
//
|
2024-01-03 12:19:35 +01:00
|
|
|
// Copyright (C) 2014-2024 Free Software Foundation, Inc.
|
2015-04-30 20:11:52 +01:00
|
|
|
//
|
|
|
|
// 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/>.
|
|
|
|
//
|
|
|
|
|
|
|
|
#ifndef _TESTSUITE_FS_H
|
|
|
|
#define _TESTSUITE_FS_H 1
|
|
|
|
|
2017-10-23 13:11:22 +01:00
|
|
|
// Assume we want std::filesystem in C++17, unless USE_FILESYSTEM_TS defined:
|
|
|
|
#if __cplusplus >= 201703L && ! defined USE_FILESYSTEM_TS
|
|
|
|
#include <filesystem>
|
|
|
|
namespace test_fs = std::filesystem;
|
|
|
|
#else
|
2015-04-30 20:11:52 +01:00
|
|
|
#include <experimental/filesystem>
|
2017-10-23 13:11:22 +01:00
|
|
|
namespace test_fs = std::experimental::filesystem;
|
|
|
|
#endif
|
2019-05-22 23:14:34 +01:00
|
|
|
#include <algorithm>
|
2016-09-28 19:02:25 +01:00
|
|
|
#include <fstream>
|
2022-06-23 13:12:12 +01:00
|
|
|
#include <random> // std::random_device
|
2015-04-30 20:11:52 +01:00
|
|
|
#include <string>
|
2022-06-23 13:12:12 +01:00
|
|
|
#include <system_error>
|
2015-05-15 19:37:25 +01:00
|
|
|
#include <cstdio>
|
2021-08-20 14:51:06 +01:00
|
|
|
#include <unistd.h> // unlink, close, getpid, geteuid
|
2021-02-12 15:13:02 +00:00
|
|
|
|
|
|
|
#if defined(_GNU_SOURCE) || _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
|
|
|
|
#include <stdlib.h> // mkstemp
|
|
|
|
#endif
|
2015-04-30 20:11:52 +01:00
|
|
|
|
2022-06-23 23:20:50 -03:00
|
|
|
#ifndef _GLIBCXX_HAVE_SYMLINK
|
|
|
|
#define NO_SYMLINKS
|
|
|
|
#endif
|
|
|
|
|
2022-06-23 23:20:51 -03:00
|
|
|
#if !defined (_GLIBCXX_HAVE_SYS_STATVFS_H) \
|
|
|
|
&& !defined (_GLIBCXX_FILESYSTEM_IS_WINDOWS)
|
|
|
|
#define NO_SPACE
|
|
|
|
#endif
|
|
|
|
|
2022-06-23 23:20:51 -03:00
|
|
|
#if !(_GLIBCXX_HAVE_SYS_STAT_H \
|
|
|
|
&& (_GLIBCXX_USE_UTIMENSAT || _GLIBCXX_USE_UTIME))
|
|
|
|
#define NO_LAST_WRITE_TIME 1
|
|
|
|
#endif
|
|
|
|
|
2015-04-30 20:11:52 +01:00
|
|
|
namespace __gnu_test
|
|
|
|
{
|
|
|
|
#define PATH_CHK(p1, p2, fn) \
|
|
|
|
if ( p1.fn() != p2.fn() ) \
|
2017-11-01 17:09:14 +00:00
|
|
|
throw test_fs::filesystem_error("comparing '" #fn "' failed", p1, p2, \
|
2015-04-30 20:11:52 +01:00
|
|
|
std::make_error_code(std::errc::invalid_argument) )
|
|
|
|
|
|
|
|
void
|
2017-10-23 13:11:22 +01:00
|
|
|
compare_paths(const test_fs::path& p1,
|
|
|
|
const test_fs::path& p2)
|
2015-04-30 20:11:52 +01:00
|
|
|
{
|
2017-10-25 13:42:53 +01:00
|
|
|
PATH_CHK( p1, p2, native );
|
2015-04-30 20:11:52 +01:00
|
|
|
PATH_CHK( p1, p2, string );
|
|
|
|
PATH_CHK( p1, p2, empty );
|
|
|
|
PATH_CHK( p1, p2, has_root_path );
|
|
|
|
PATH_CHK( p1, p2, has_root_name );
|
|
|
|
PATH_CHK( p1, p2, has_root_directory );
|
|
|
|
PATH_CHK( p1, p2, has_relative_path );
|
|
|
|
PATH_CHK( p1, p2, has_parent_path );
|
|
|
|
PATH_CHK( p1, p2, has_filename );
|
|
|
|
PATH_CHK( p1, p2, has_stem );
|
|
|
|
PATH_CHK( p1, p2, has_extension );
|
|
|
|
PATH_CHK( p1, p2, is_absolute );
|
|
|
|
PATH_CHK( p1, p2, is_relative );
|
|
|
|
auto d1 = std::distance(p1.begin(), p1.end());
|
|
|
|
auto d2 = std::distance(p2.begin(), p2.end());
|
2019-05-22 23:14:34 +01:00
|
|
|
if (d1 != d2)
|
2017-10-23 13:11:22 +01:00
|
|
|
throw test_fs::filesystem_error(
|
2019-05-22 23:14:34 +01:00
|
|
|
"distance(begin1, end1) != distance(begin2, end2)", p1, p2,
|
2015-04-30 20:11:52 +01:00
|
|
|
std::make_error_code(std::errc::invalid_argument) );
|
2019-05-28 20:39:41 +01:00
|
|
|
if (!std::equal(p1.begin(), p1.end(), p2.begin()))
|
2019-05-22 23:14:34 +01:00
|
|
|
throw test_fs::filesystem_error(
|
2019-05-28 20:39:41 +01:00
|
|
|
"!equal(begin1, end1, begin2)", p1, p2,
|
2019-05-22 23:14:34 +01:00
|
|
|
std::make_error_code(std::errc::invalid_argument) );
|
|
|
|
|
2015-04-30 20:11:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const std::string test_paths[] = {
|
|
|
|
"", "/", "//", "/.", "/./", "/a", "/a/", "/a//", "/a/b/c/d", "/a//b",
|
|
|
|
"a", "a/b", "a/b/", "a/b/c", "a/b/c.d", "a/b/..", "a/b/c.", "a/b/.c"
|
|
|
|
};
|
|
|
|
|
PR libstdc++/78870 support std::filesystem on Windows
PR libstdc++/78870 support std::filesystem on Windows
* config.h.in: Regenerate.
* configure: Regenerate.
* configure.ac: Check for link, readlink and symlink.
* include/bits/fs_path.h (path::operator/=(const path&)): Move
definition out of class body.
(path::is_absolute(), path::_M_append(path)): Likewise.
(operator<<(basic_ostream, const path&)): Use std::quoted directly.
(operator>>(basic_istream, path&)): Likewise.
(u8path): Reorder definitions and fix Windows implementation.
(path::is_absolute()): Define inline and fix for Windows.
[!_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define POSIX version inline.
(path::_M_append(path)): Define inline.
* include/experimental/bits/fs_path.h (path::is_absolute()): Move
definition out of class body.
(operator<<(basic_ostream, const path&)): Fix type of delimiter and
escape characters.
(operator>>(basic_istream, path&)): Likewise.
(path::is_absolute()): Define inline and fix for Windows.
* src/filesystem/dir-common.h (__gnu_posix): New namespace.
(__gnu_posix::char_type, __gnu_posix::DIR, __gnu_posix::dirent)
(__gnu_posix::opendir, __gnu_posix::readdir, __gnu_posix::closedir):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(_Dir_base, get_file_type): Qualify names to use declarations from
__gnu_posix namespace.
(_Dir_base::is_dor_or_dotdot): New helper functions.
* src/filesystem/dir.cc (_Dir, recursive_directory_iterator): Qualify
names to use declarations from __gnu_posix namespace.
* src/filesystem/ops-common.h (__gnu_posix): New nested namespace.
(__gnu_posix::open, __gnu_posix::close, __gnu_posix::stat_type)
(__gnu_posix::stat, __gnu_posix::lstat, __gnu_posix::mode_t)
(__gnu_posix::chmod, __gnu_posix::mkdir, __gnu_posix::getcwd)
(__gnu_posix::chdir, __gnu_posix::utimbuf, __gnu_posix::utime)
(__gnu_posix::rename, __gnu_posix::truncate, __gnu_posix::char_type):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(stat_type, do_copy_file): Qualify names to use declarations from
__gnu_posix namespace.
(do_space): Declare new function.
(make_file_type): Only use S_ISLNK if defined.
* src/filesystem/ops.cc (char_ptr, filesystem::canonical): Use
path::value_type not char.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(filesystem::space): Use do_space.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Get absolute path to directory.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/path.cc (dot): Define constant.
(path::replace_extension): Use dot.
(path::_M_find_extension): Likewise. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* src/filesystem/std-dir.cc (_Dir, recursive_directory_iterator):
Qualify names to use declarations from __gnu_posix namespace.
* src/filesystem/std-ops.cc (filesystem::absolute(const path&)): Use
correct error_code.
(filesystem::absolute(const path&, error_code&)): Add implementation
for Windows.
(char_ptr, filesystem::canonical): Use path::value_type not char.
(do_copy_file): Use names from __gnu_posix.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Do not use fchmod, fchmodat or
sendfile.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(do_space): Define.
(filesystem::space): Use do_space.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/std-path.cc
[_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define for Windows.
(dot): Define constant.
(path::replace_extension, is_dot): Use dot.
(path::lexically_normal): Check _M_type instead of calling
non-existent function.
(path::_M_find_extension): Use dot. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* testsuite/27_io/filesystem/iterators/directory_iterator.cc: Do not
use symlinks.
* testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc:
Likewise.
* testsuite/27_io/filesystem/operations/absolute.cc: Use
__gnu_test::root_path() instead of "/" and add Windows-specific tests.
* testsuite/27_io/filesystem/operations/canonical.cc: Use
path::string() to get narrow string, not path::native().
* testsuite/27_io/filesystem/operations/copy.cc: Construct fstreams
with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/copy_file.cc: Likewise.
* testsuite/27_io/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/27_io/filesystem/operations/is_empty.cc: Construct
fstreams with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/last_write_time.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/operations/space.cc: Check results for
errors, expect sensible values otherwise.
* testsuite/27_io/filesystem/operations/temp_directory_path.cc: Add
helpers for adjusting the environment on Windows.
* testsuite/27_io/filesystem/path/append/path.cc: Test
Windows-specific behaviour.
* testsuite/27_io/filesystem/path/construct/format.cc: Fix creation
of path::string_type objects.
* testsuite/27_io/filesystem/path/construct/locale.cc: Compare native
string to wide string on Windows.
* testsuite/27_io/filesystem/path/decompose/root_directory.cc: Allow
for backslash as root-directory.
* testsuite/27_io/filesystem/path/decompose/stem.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/path/itr/traversal.cc: Test Windows-style
paths.
* testsuite/27_io/filesystem/path/native/string.cc: Use string_type
not std::string.
* testsuite/27_io/filesystem/path/query/is_absolute.cc: Adjust for
different definintion of absolute paths on Windows.
* testsuite/experimental/filesystem/iterators/directory_iterator.cc:
Do not use symlinks.
* testsuite/experimental/filesystem/operations/absolute.cc: Test
Windows behaviour.
* testsuite/experimental/filesystem/operations/copy.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/copy_file.cc: Likewise.
* testsuite/experimental/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/is_empty.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/last_write_time.cc:
Use path::string() to get narrow string.
* testsuite/experimental/filesystem/operations/space.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
Add helpers for adjusting the environment on Windows.
* testsuite/experimental/filesystem/path/append/path.cc: Use
path::string() to get narrow strings for comparisons.
* testsuite/experimental/filesystem/path/concat/path.cc: Likewise.
* testsuite/experimental/filesystem/path/decompose/root_directory.cc:
Likewise.
* testsuite/experimental/filesystem/path/decompose/stem.cc: Likewise.
* testsuite/experimental/filesystem/path/native/string.cc: Use
string_type not std::string.
* testsuite/experimental/filesystem/path/query/is_absolute.cc:
Adjust for different definintion of absolute paths on Windows.
* testsuite/util/testsuite_fs.h (__gnu_test::root_path()): New
function.
(__gnu_test::scoped_file): Construct fstreams with NTCTS not
std::basic_string.
From-SVN: r261034
2018-05-31 20:20:24 +01:00
|
|
|
test_fs::path
|
|
|
|
root_path()
|
|
|
|
{
|
2021-02-10 16:37:39 +00:00
|
|
|
#if defined(__MINGW32__) || defined(__MINGW64__)
|
PR libstdc++/78870 support std::filesystem on Windows
PR libstdc++/78870 support std::filesystem on Windows
* config.h.in: Regenerate.
* configure: Regenerate.
* configure.ac: Check for link, readlink and symlink.
* include/bits/fs_path.h (path::operator/=(const path&)): Move
definition out of class body.
(path::is_absolute(), path::_M_append(path)): Likewise.
(operator<<(basic_ostream, const path&)): Use std::quoted directly.
(operator>>(basic_istream, path&)): Likewise.
(u8path): Reorder definitions and fix Windows implementation.
(path::is_absolute()): Define inline and fix for Windows.
[!_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define POSIX version inline.
(path::_M_append(path)): Define inline.
* include/experimental/bits/fs_path.h (path::is_absolute()): Move
definition out of class body.
(operator<<(basic_ostream, const path&)): Fix type of delimiter and
escape characters.
(operator>>(basic_istream, path&)): Likewise.
(path::is_absolute()): Define inline and fix for Windows.
* src/filesystem/dir-common.h (__gnu_posix): New namespace.
(__gnu_posix::char_type, __gnu_posix::DIR, __gnu_posix::dirent)
(__gnu_posix::opendir, __gnu_posix::readdir, __gnu_posix::closedir):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(_Dir_base, get_file_type): Qualify names to use declarations from
__gnu_posix namespace.
(_Dir_base::is_dor_or_dotdot): New helper functions.
* src/filesystem/dir.cc (_Dir, recursive_directory_iterator): Qualify
names to use declarations from __gnu_posix namespace.
* src/filesystem/ops-common.h (__gnu_posix): New nested namespace.
(__gnu_posix::open, __gnu_posix::close, __gnu_posix::stat_type)
(__gnu_posix::stat, __gnu_posix::lstat, __gnu_posix::mode_t)
(__gnu_posix::chmod, __gnu_posix::mkdir, __gnu_posix::getcwd)
(__gnu_posix::chdir, __gnu_posix::utimbuf, __gnu_posix::utime)
(__gnu_posix::rename, __gnu_posix::truncate, __gnu_posix::char_type):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(stat_type, do_copy_file): Qualify names to use declarations from
__gnu_posix namespace.
(do_space): Declare new function.
(make_file_type): Only use S_ISLNK if defined.
* src/filesystem/ops.cc (char_ptr, filesystem::canonical): Use
path::value_type not char.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(filesystem::space): Use do_space.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Get absolute path to directory.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/path.cc (dot): Define constant.
(path::replace_extension): Use dot.
(path::_M_find_extension): Likewise. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* src/filesystem/std-dir.cc (_Dir, recursive_directory_iterator):
Qualify names to use declarations from __gnu_posix namespace.
* src/filesystem/std-ops.cc (filesystem::absolute(const path&)): Use
correct error_code.
(filesystem::absolute(const path&, error_code&)): Add implementation
for Windows.
(char_ptr, filesystem::canonical): Use path::value_type not char.
(do_copy_file): Use names from __gnu_posix.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Do not use fchmod, fchmodat or
sendfile.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(do_space): Define.
(filesystem::space): Use do_space.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/std-path.cc
[_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define for Windows.
(dot): Define constant.
(path::replace_extension, is_dot): Use dot.
(path::lexically_normal): Check _M_type instead of calling
non-existent function.
(path::_M_find_extension): Use dot. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* testsuite/27_io/filesystem/iterators/directory_iterator.cc: Do not
use symlinks.
* testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc:
Likewise.
* testsuite/27_io/filesystem/operations/absolute.cc: Use
__gnu_test::root_path() instead of "/" and add Windows-specific tests.
* testsuite/27_io/filesystem/operations/canonical.cc: Use
path::string() to get narrow string, not path::native().
* testsuite/27_io/filesystem/operations/copy.cc: Construct fstreams
with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/copy_file.cc: Likewise.
* testsuite/27_io/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/27_io/filesystem/operations/is_empty.cc: Construct
fstreams with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/last_write_time.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/operations/space.cc: Check results for
errors, expect sensible values otherwise.
* testsuite/27_io/filesystem/operations/temp_directory_path.cc: Add
helpers for adjusting the environment on Windows.
* testsuite/27_io/filesystem/path/append/path.cc: Test
Windows-specific behaviour.
* testsuite/27_io/filesystem/path/construct/format.cc: Fix creation
of path::string_type objects.
* testsuite/27_io/filesystem/path/construct/locale.cc: Compare native
string to wide string on Windows.
* testsuite/27_io/filesystem/path/decompose/root_directory.cc: Allow
for backslash as root-directory.
* testsuite/27_io/filesystem/path/decompose/stem.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/path/itr/traversal.cc: Test Windows-style
paths.
* testsuite/27_io/filesystem/path/native/string.cc: Use string_type
not std::string.
* testsuite/27_io/filesystem/path/query/is_absolute.cc: Adjust for
different definintion of absolute paths on Windows.
* testsuite/experimental/filesystem/iterators/directory_iterator.cc:
Do not use symlinks.
* testsuite/experimental/filesystem/operations/absolute.cc: Test
Windows behaviour.
* testsuite/experimental/filesystem/operations/copy.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/copy_file.cc: Likewise.
* testsuite/experimental/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/is_empty.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/last_write_time.cc:
Use path::string() to get narrow string.
* testsuite/experimental/filesystem/operations/space.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
Add helpers for adjusting the environment on Windows.
* testsuite/experimental/filesystem/path/append/path.cc: Use
path::string() to get narrow strings for comparisons.
* testsuite/experimental/filesystem/path/concat/path.cc: Likewise.
* testsuite/experimental/filesystem/path/decompose/root_directory.cc:
Likewise.
* testsuite/experimental/filesystem/path/decompose/stem.cc: Likewise.
* testsuite/experimental/filesystem/path/native/string.cc: Use
string_type not std::string.
* testsuite/experimental/filesystem/path/query/is_absolute.cc:
Adjust for different definintion of absolute paths on Windows.
* testsuite/util/testsuite_fs.h (__gnu_test::root_path()): New
function.
(__gnu_test::scoped_file): Construct fstreams with NTCTS not
std::basic_string.
From-SVN: r261034
2018-05-31 20:20:24 +01:00
|
|
|
return L"c:/";
|
|
|
|
#else
|
|
|
|
return "/";
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-05-15 19:37:25 +01:00
|
|
|
// This is NOT supposed to be a secure way to get a unique name!
|
|
|
|
// We just need a path that doesn't exist for testing purposes.
|
2017-10-23 13:11:22 +01:00
|
|
|
test_fs::path
|
2019-01-10 11:12:00 +00:00
|
|
|
nonexistent_path(std::string file = __builtin_FILE())
|
2015-05-15 19:37:25 +01:00
|
|
|
{
|
2019-01-10 11:12:00 +00:00
|
|
|
// Include the caller's filename to help identify tests that fail to
|
|
|
|
// clean up the files they create.
|
|
|
|
// Remove .cc extension:
|
|
|
|
if (file.length() > 3 && file.compare(file.length() - 3, 3, ".cc") == 0)
|
|
|
|
file.resize(file.length() - 3);
|
|
|
|
// And directory:
|
|
|
|
auto pos = file.find_last_of("/\\");
|
|
|
|
if (pos != file.npos)
|
|
|
|
file.erase(0, pos+1);
|
|
|
|
|
2022-06-23 13:12:12 +01:00
|
|
|
file.reserve(file.size() + 40);
|
|
|
|
file.insert(0, "filesystem-test.");
|
|
|
|
|
|
|
|
// A counter, starting from a random value, to be included as part
|
|
|
|
// of the filename being returned, and incremented each time
|
|
|
|
// this function is used. It allows us to ensure that two calls
|
|
|
|
// to this function can never return the same filename, something
|
|
|
|
// testcases do when they need multiple non-existent filenames
|
|
|
|
// for their purposes.
|
|
|
|
static unsigned counter = std::random_device{}();
|
|
|
|
file += '.';
|
|
|
|
file += std::to_string(counter++);
|
|
|
|
file += '.';
|
|
|
|
|
2017-10-23 13:11:22 +01:00
|
|
|
test_fs::path p;
|
2015-05-15 19:37:25 +01:00
|
|
|
#if defined(_GNU_SOURCE) || _XOPEN_SOURCE >= 500 || _POSIX_C_SOURCE >= 200112L
|
2022-06-23 13:12:12 +01:00
|
|
|
|
|
|
|
// Use mkstemp to determine the name of a file which does not exist yet.
|
|
|
|
//
|
|
|
|
// Note that we have seen on some systems (such as RTEMS, for instance)
|
|
|
|
// that mkstemp behaves very predictably, causing it to always try
|
|
|
|
// the same sequence of file names. In other words, if we call mkstemp
|
|
|
|
// with a pattern, delete the file it created (which is what we do, here),
|
|
|
|
// and call mkstemp with the same pattern again, it returns the same
|
|
|
|
// filename once more. While most implementations introduce a degree
|
|
|
|
// of randomness, it is not mandated by the standard, and this is why
|
|
|
|
// we also include a counter in the template passed to mkstemp.
|
|
|
|
file += "XXXXXX";
|
|
|
|
int fd = ::mkstemp(&file[0]);
|
2015-05-15 19:37:25 +01:00
|
|
|
if (fd == -1)
|
2017-10-23 13:11:22 +01:00
|
|
|
throw test_fs::filesystem_error("mkstemp failed",
|
2015-05-15 19:37:25 +01:00
|
|
|
std::error_code(errno, std::generic_category()));
|
2022-06-23 13:12:12 +01:00
|
|
|
::unlink(file.c_str());
|
2015-05-15 19:37:25 +01:00
|
|
|
::close(fd);
|
2022-06-23 13:12:12 +01:00
|
|
|
p = std::move(file);
|
2015-05-15 19:37:25 +01:00
|
|
|
#else
|
2019-01-10 11:12:00 +00:00
|
|
|
if (file.length() > 64)
|
|
|
|
file.resize(64);
|
2022-06-23 13:12:12 +01:00
|
|
|
// The combination of random counter and PID should be unique for a given
|
2022-07-05 19:07:32 -03:00
|
|
|
// run of the testsuite. N.B. getpid() returns a pointer type on vxworks
|
|
|
|
// in kernel mode.
|
2022-07-05 06:12:27 -03:00
|
|
|
file += std::to_string((unsigned long) ::getpid());
|
2022-06-23 13:12:12 +01:00
|
|
|
p = std::move(file);
|
|
|
|
if (test_fs::exists(p))
|
|
|
|
throw test_fs::filesystem_error("Failed to generate unique pathname", p,
|
|
|
|
std::make_error_code(std::errc::file_exists));
|
2015-05-15 19:37:25 +01:00
|
|
|
#endif
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2016-09-28 19:02:25 +01:00
|
|
|
// RAII helper to remove a file on scope exit.
|
|
|
|
struct scoped_file
|
|
|
|
{
|
2017-10-23 13:11:22 +01:00
|
|
|
using path_type = test_fs::path;
|
2016-09-28 19:02:25 +01:00
|
|
|
|
|
|
|
enum adopt_file_t { adopt_file };
|
|
|
|
|
|
|
|
explicit
|
|
|
|
scoped_file(const path_type& p = nonexistent_path()) : path(p)
|
PR libstdc++/78870 support std::filesystem on Windows
PR libstdc++/78870 support std::filesystem on Windows
* config.h.in: Regenerate.
* configure: Regenerate.
* configure.ac: Check for link, readlink and symlink.
* include/bits/fs_path.h (path::operator/=(const path&)): Move
definition out of class body.
(path::is_absolute(), path::_M_append(path)): Likewise.
(operator<<(basic_ostream, const path&)): Use std::quoted directly.
(operator>>(basic_istream, path&)): Likewise.
(u8path): Reorder definitions and fix Windows implementation.
(path::is_absolute()): Define inline and fix for Windows.
[!_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define POSIX version inline.
(path::_M_append(path)): Define inline.
* include/experimental/bits/fs_path.h (path::is_absolute()): Move
definition out of class body.
(operator<<(basic_ostream, const path&)): Fix type of delimiter and
escape characters.
(operator>>(basic_istream, path&)): Likewise.
(path::is_absolute()): Define inline and fix for Windows.
* src/filesystem/dir-common.h (__gnu_posix): New namespace.
(__gnu_posix::char_type, __gnu_posix::DIR, __gnu_posix::dirent)
(__gnu_posix::opendir, __gnu_posix::readdir, __gnu_posix::closedir):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(_Dir_base, get_file_type): Qualify names to use declarations from
__gnu_posix namespace.
(_Dir_base::is_dor_or_dotdot): New helper functions.
* src/filesystem/dir.cc (_Dir, recursive_directory_iterator): Qualify
names to use declarations from __gnu_posix namespace.
* src/filesystem/ops-common.h (__gnu_posix): New nested namespace.
(__gnu_posix::open, __gnu_posix::close, __gnu_posix::stat_type)
(__gnu_posix::stat, __gnu_posix::lstat, __gnu_posix::mode_t)
(__gnu_posix::chmod, __gnu_posix::mkdir, __gnu_posix::getcwd)
(__gnu_posix::chdir, __gnu_posix::utimbuf, __gnu_posix::utime)
(__gnu_posix::rename, __gnu_posix::truncate, __gnu_posix::char_type):
Define as adaptors for Windows functions/types or as
using-declarations for POSIX functions/types.
(stat_type, do_copy_file): Qualify names to use declarations from
__gnu_posix namespace.
(do_space): Declare new function.
(make_file_type): Only use S_ISLNK if defined.
* src/filesystem/ops.cc (char_ptr, filesystem::canonical): Use
path::value_type not char.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(filesystem::space): Use do_space.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Get absolute path to directory.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/path.cc (dot): Define constant.
(path::replace_extension): Use dot.
(path::_M_find_extension): Likewise. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* src/filesystem/std-dir.cc (_Dir, recursive_directory_iterator):
Qualify names to use declarations from __gnu_posix namespace.
* src/filesystem/std-ops.cc (filesystem::absolute(const path&)): Use
correct error_code.
(filesystem::absolute(const path&, error_code&)): Add implementation
for Windows.
(char_ptr, filesystem::canonical): Use path::value_type not char.
(do_copy_file): Use names from __gnu_posix.
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Do not use fchmod, fchmodat or
sendfile.
(filesystem::copy, create_dir, filesystem::create_directory): Qualify
names to use declarations from __gnu_posix namespace.
(filesystem::create_hard_link): Check HAVE_LINK autoconf macro and
add implementation for Windows.
(filesystem::create_symlink): Check HAVE_SYMLINK autoconf macro.
(filesystem::current_path(error_code&)): Use __gnu_posix::getcwd.
[!_PC_PATH_MAX]: Don't use pathconf.
[PATH_MAX]: Use if defined.
(filesystem::current_path(const path&, error_code&))
(filesystem::equivalent, do_stat, filesystem::hard_link_count)
(filesystem::last_write_time, filesystem::permissions): Use names
from __gnu_posix.
(filesystem::read_symlink): Check HAVE_READLINK autoconf macro.
(filesystem::remove) [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Add
implementation for Windows.
(filesystem::rename, filesystem::resize_file): Use names from
__gnu_posix.
(do_space): Define.
(filesystem::space): Use do_space.
(filesystem::status, filesystem::symlink_status): Use names from
__gnu_posix.
(filesystem::temp_directory_path): Add implementation for Windows.
* src/filesystem/std-path.cc
[_GLIBCXX_FILESYSTEM_IS_WINDOWS] (path::operator/=(const path&)):
Define for Windows.
(dot): Define constant.
(path::replace_extension, is_dot): Use dot.
(path::lexically_normal): Check _M_type instead of calling
non-existent function.
(path::_M_find_extension): Use dot. Use path::string_type not
std::string.
(path::_M_split_cmpts): Use dot.
(filesystem_error::_M_get_what): Use u8string() not native().
* testsuite/27_io/filesystem/iterators/directory_iterator.cc: Do not
use symlinks.
* testsuite/27_io/filesystem/iterators/recursive_directory_iterator.cc:
Likewise.
* testsuite/27_io/filesystem/operations/absolute.cc: Use
__gnu_test::root_path() instead of "/" and add Windows-specific tests.
* testsuite/27_io/filesystem/operations/canonical.cc: Use
path::string() to get narrow string, not path::native().
* testsuite/27_io/filesystem/operations/copy.cc: Construct fstreams
with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/copy_file.cc: Likewise.
* testsuite/27_io/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/27_io/filesystem/operations/is_empty.cc: Construct
fstreams with std::filesystem::path not std::basic_string.
* testsuite/27_io/filesystem/operations/last_write_time.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/operations/space.cc: Check results for
errors, expect sensible values otherwise.
* testsuite/27_io/filesystem/operations/temp_directory_path.cc: Add
helpers for adjusting the environment on Windows.
* testsuite/27_io/filesystem/path/append/path.cc: Test
Windows-specific behaviour.
* testsuite/27_io/filesystem/path/construct/format.cc: Fix creation
of path::string_type objects.
* testsuite/27_io/filesystem/path/construct/locale.cc: Compare native
string to wide string on Windows.
* testsuite/27_io/filesystem/path/decompose/root_directory.cc: Allow
for backslash as root-directory.
* testsuite/27_io/filesystem/path/decompose/stem.cc: Use
path::string() to get narrow string.
* testsuite/27_io/filesystem/path/itr/traversal.cc: Test Windows-style
paths.
* testsuite/27_io/filesystem/path/native/string.cc: Use string_type
not std::string.
* testsuite/27_io/filesystem/path/query/is_absolute.cc: Adjust for
different definintion of absolute paths on Windows.
* testsuite/experimental/filesystem/iterators/directory_iterator.cc:
Do not use symlinks.
* testsuite/experimental/filesystem/operations/absolute.cc: Test
Windows behaviour.
* testsuite/experimental/filesystem/operations/copy.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/copy_file.cc: Likewise.
* testsuite/experimental/filesystem/operations/exists.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/is_empty.cc: Construct
fstreams with NTCTS not std::basic_string.
* testsuite/experimental/filesystem/operations/last_write_time.cc:
Use path::string() to get narrow string.
* testsuite/experimental/filesystem/operations/space.cc: Use
__gnu_test::root_path() instead of "/".
* testsuite/experimental/filesystem/operations/temp_directory_path.cc:
Add helpers for adjusting the environment on Windows.
* testsuite/experimental/filesystem/path/append/path.cc: Use
path::string() to get narrow strings for comparisons.
* testsuite/experimental/filesystem/path/concat/path.cc: Likewise.
* testsuite/experimental/filesystem/path/decompose/root_directory.cc:
Likewise.
* testsuite/experimental/filesystem/path/decompose/stem.cc: Likewise.
* testsuite/experimental/filesystem/path/native/string.cc: Use
string_type not std::string.
* testsuite/experimental/filesystem/path/query/is_absolute.cc:
Adjust for different definintion of absolute paths on Windows.
* testsuite/util/testsuite_fs.h (__gnu_test::root_path()): New
function.
(__gnu_test::scoped_file): Construct fstreams with NTCTS not
std::basic_string.
From-SVN: r261034
2018-05-31 20:20:24 +01:00
|
|
|
{ std::ofstream{p.c_str()}; }
|
2016-09-28 19:02:25 +01:00
|
|
|
|
|
|
|
scoped_file(path_type p, adopt_file_t) : path(p) { }
|
|
|
|
|
2016-10-25 16:32:37 +01:00
|
|
|
~scoped_file() { if (!path.empty()) remove(path); }
|
2016-09-28 19:02:25 +01:00
|
|
|
|
2019-04-05 17:56:23 +01:00
|
|
|
scoped_file(scoped_file&&) = default;
|
|
|
|
scoped_file& operator=(scoped_file&&) = default;
|
|
|
|
|
2016-09-28 19:02:25 +01:00
|
|
|
path_type path;
|
|
|
|
};
|
|
|
|
|
2021-08-23 13:05:25 +01:00
|
|
|
inline bool
|
2021-08-20 14:51:06 +01:00
|
|
|
permissions_are_testable(bool print_msg = true)
|
|
|
|
{
|
|
|
|
bool testable = false;
|
|
|
|
#if !(defined __MINGW32__ || defined __MINGW64__)
|
|
|
|
if (geteuid() != 0)
|
|
|
|
testable = true;
|
|
|
|
// XXX on Linux the CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH capabilities
|
|
|
|
// can give normal users extra permissions for files and directories.
|
|
|
|
// We ignore that possibility here.
|
|
|
|
#endif
|
|
|
|
if (print_msg && !testable)
|
|
|
|
std::puts("Skipping tests that depend on filesystem permissions");
|
|
|
|
return testable;
|
|
|
|
}
|
|
|
|
|
2015-04-30 20:11:52 +01:00
|
|
|
} // namespace __gnu_test
|
|
|
|
#endif
|