16e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier//===--------------------- filesystem/ops.cpp -----------------------------===// 26e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// 36e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// The LLVM Compiler Infrastructure 46e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// 56e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open 66e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// Source Licenses. See LICENSE.TXT for details. 76e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// 86e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier//===----------------------------------------------------------------------===// 96e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include "experimental/filesystem" 116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include "iterator" 126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include "fstream" 136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include "type_traits" 146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include "random" /* for unique_path */ 156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include "cstdlib" 166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include "climits" 176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 18b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselier#include "filesystem_time_helper.h" 19b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselier 206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <unistd.h> 216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <sys/stat.h> 226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <sys/statvfs.h> 236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <fcntl.h> /* values for fchmodat */ 2468b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber 2568b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if (__APPLE__) 2668b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) 2768b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 101300 2868b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#define _LIBCXX_USE_UTIMENSAT 2968b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#endif 3068b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) 3168b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 110000 3268b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#define _LIBCXX_USE_UTIMENSAT 3368b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#endif 3468b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#elif defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) 3568b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ >= 110000 3668b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#define _LIBCXX_USE_UTIMENSAT 3768b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#endif 3868b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#elif defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) 3968b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ >= 40000 4068b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#define _LIBCXX_USE_UTIMENSAT 4168b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#endif 4268b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#endif // __ENVIRONMENT_.*_VERSION_MIN_REQUIRED__ 4368b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#else 4468b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber// We can use the presence of UTIME_OMIT to detect platforms that provide 4568b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber// utimensat. 4668b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if defined(UTIME_OMIT) 4768b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#define _LIBCXX_USE_UTIMENSAT 4868b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#endif 4968b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#endif // __APPLE__ 5068b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber 5168b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if !defined(_LIBCXX_USE_UTIMENSAT) 526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#include <sys/time.h> // for ::utimes as used in __last_write_time 536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#endif 546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier_LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL_FILESYSTEM 566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfilesystem_error::~filesystem_error() {} 586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// POSIX HELPERS 616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliernamespace detail { namespace { 636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierusing value_type = path::value_type; 656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierusing string_type = path::string_type; 666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierinline std::error_code capture_errno() { 68166d27ed3133af1deb0c1b73ab142847e1942644Saleem Abdulrasool _LIBCPP_ASSERT(errno, "Expected errno to be non-zero"); 69166d27ed3133af1deb0c1b73ab142847e1942644Saleem Abdulrasool return std::error_code(errno, std::generic_category()); 706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid set_or_throw(std::error_code const& m_ec, std::error_code* ec, 736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const char* msg, path const& p = {}, path const& p2 = {}) 746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) { 766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier *ec = m_ec; 776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } else { 786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier string msg_s("std::experimental::filesystem::"); 796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier msg_s += msg; 80e7acb0e5be91c8e6ded934184f4053757c5f5360Marshall Clow __throw_filesystem_error(msg_s, p, p2, m_ec); 816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid set_or_throw(std::error_code* ec, const char* msg, 856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier path const& p = {}, path const& p2 = {}) 866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return set_or_throw(capture_errno(), ec, msg, p, p2); 886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierperms posix_get_perms(const struct ::stat & st) noexcept { 916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return static_cast<perms>(st.st_mode) & perms::mask; 926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier::mode_t posix_convert_perms(perms prms) { 956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return static_cast< ::mode_t>(prms & perms::mask); 966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_status create_file_status(std::error_code& m_ec, path const& p, 996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat& path_stat, 1006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code* ec) 1016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 1026e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) *ec = m_ec; 1036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (m_ec && (m_ec.value() == ENOENT || m_ec.value() == ENOTDIR)) { 1046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return file_status(file_type::not_found); 1056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (m_ec) { 1076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "posix_stat", p); 1086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return file_status(file_type::none); 1096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // else 1116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier file_status fs_tmp; 1136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto const mode = path_stat.st_mode; 1146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (S_ISLNK(mode)) fs_tmp.type(file_type::symlink); 1156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (S_ISREG(mode)) fs_tmp.type(file_type::regular); 1166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (S_ISDIR(mode)) fs_tmp.type(file_type::directory); 1176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (S_ISBLK(mode)) fs_tmp.type(file_type::block); 1186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (S_ISCHR(mode)) fs_tmp.type(file_type::character); 1196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (S_ISFIFO(mode)) fs_tmp.type(file_type::fifo); 1206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (S_ISSOCK(mode)) fs_tmp.type(file_type::socket); 1216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else fs_tmp.type(file_type::unknown); 1226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier fs_tmp.permissions(detail::posix_get_perms(path_stat)); 1246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return fs_tmp; 1256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 1266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_status posix_stat(path const & p, struct ::stat& path_stat, 1286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code* ec) 1296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 1306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 1316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::stat(p.c_str(), &path_stat) == -1) 1326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier m_ec = detail::capture_errno(); 1336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return create_file_status(m_ec, p, path_stat, ec); 1346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 1356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_status posix_stat(path const & p, std::error_code* ec) { 1376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat path_stat; 1386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return posix_stat(p, path_stat, ec); 1396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 1406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1416e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_status posix_lstat(path const & p, struct ::stat & path_stat, 1426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code* ec) 1436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 1446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 1456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::lstat(p.c_str(), &path_stat) == -1) 1466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier m_ec = detail::capture_errno(); 1476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return create_file_status(m_ec, p, path_stat, ec); 1486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 1496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_status posix_lstat(path const & p, std::error_code* ec) { 1516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat path_stat; 1526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return posix_lstat(p, path_stat, ec); 1536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 1546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool stat_equivalent(struct ::stat& st1, struct ::stat& st2) { 1566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); 1576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 1586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// DETAIL::MISC 1606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool copy_file_impl(const path& from, const path& to, perms from_perms, 1636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code *ec) 1646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 1656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::ifstream in(from.c_str(), std::ios::binary); 1666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::ofstream out(to.c_str(), std::ios::binary); 1676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1686e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (in.good() && out.good()) { 1696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier using InIt = std::istreambuf_iterator<char>; 1706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier using OutIt = std::ostreambuf_iterator<char>; 1716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier InIt bin(in); 1726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier InIt ein; 1736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier OutIt bout(out); 1746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::copy(bin, ein, bout); 1756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (out.fail() || in.fail()) { 1776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(make_error_code(errc::operation_not_permitted), 1786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec, "copy_file", from, to); 1796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 1806e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __permissions(to, from_perms, ec); 1826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // TODO what if permissions fails? 1836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return true; 1846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 1856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier}} // end namespace detail 1876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierusing detail::set_or_throw; 1896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 1906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierpath __canonical(path const & orig_p, const path& base, std::error_code *ec) 1916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 1926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier path p = absolute(orig_p, base); 1936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier char buff[PATH_MAX + 1]; 1946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier char *ret; 1956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if ((ret = ::realpath(p.c_str(), buff)) == nullptr) { 1966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "canonical", orig_p, base); 1976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return {}; 1986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 1996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 2006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return {ret}; 2016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 2026e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __copy(const path& from, const path& to, copy_options options, 2046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code *ec) 2056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 2066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const bool sym_status = bool(options & 2076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier (copy_options::create_symlinks | copy_options::skip_symlinks)); 2086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const bool sym_status2 = bool(options & 2106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier copy_options::copy_symlinks); 2116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2124aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow std::error_code m_ec1; 2136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat f_st = {}; 2146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const file_status f = sym_status || sym_status2 2154aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow ? detail::posix_lstat(from, f_st, &m_ec1) 2164aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow : detail::posix_stat(from, f_st, &m_ec1); 2174aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow if (m_ec1) 2184aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow return set_or_throw(m_ec1, ec, "copy", from, to); 2196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat t_st = {}; 2214aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow const file_status t = sym_status ? detail::posix_lstat(to, t_st, &m_ec1) 2224aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow : detail::posix_stat(to, t_st, &m_ec1); 2236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (not status_known(t)) 2254aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow return set_or_throw(m_ec1, ec, "copy", from, to); 2266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!exists(f) || is_other(f) || is_other(t) 2286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier || (is_directory(f) && is_regular_file(t)) 2296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier || detail::stat_equivalent(f_st, t_st)) 2306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier { 2316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return set_or_throw(make_error_code(errc::function_not_supported), 2326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec, "copy", from, to); 2336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 2366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (is_symlink(f)) { 2386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (bool(copy_options::skip_symlinks & options)) { 2396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // do nothing 2406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } else if (not exists(t)) { 2416e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __copy_symlink(from, to, ec); 2426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } else { 2436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(make_error_code(errc::file_exists), 2446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec, "copy", from, to); 2456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return; 2476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (is_regular_file(f)) { 2496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (bool(copy_options::directories_only & options)) { 2506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // do nothing 2516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (bool(copy_options::create_symlinks & options)) { 2536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __create_symlink(from, to, ec); 2546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (bool(copy_options::create_hard_links & options)) { 2566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __create_hard_link(from, to, ec); 2576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (is_directory(t)) { 2596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __copy_file(from, to / from.filename(), options, ec); 2606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } else { 2616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __copy_file(from, to, options, ec); 2626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return; 2646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 265451f34db162fddec235736bc0ee0c670ad452e2aEric Fiselier else if (is_directory(f) && bool(copy_options::create_symlinks & options)) { 266451f34db162fddec235736bc0ee0c670ad452e2aEric Fiselier return set_or_throw(make_error_code(errc::is_a_directory), ec, "copy"); 267451f34db162fddec235736bc0ee0c670ad452e2aEric Fiselier } 268508f208ae9fe8afa4cccea0763ffc99662433886Eric Fiselier else if (is_directory(f) && (bool(copy_options::recursive & options) || 269508f208ae9fe8afa4cccea0763ffc99662433886Eric Fiselier copy_options::none == options)) { 2706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!exists(t)) { 2726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // create directory to with attributes from 'from'. 2736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __create_directory(to, from, ec); 2746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec && *ec) { return; } 2756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier directory_iterator it = ec ? directory_iterator(from, *ec) 2776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier : directory_iterator(from); 2786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec && *ec) { return; } 2794aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow std::error_code m_ec2; 2804aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow for (; it != directory_iterator(); it.increment(m_ec2)) { 2814aee06b818ed7ee73a7be11997fc8b9afb442bbeMarshall Clow if (m_ec2) return set_or_throw(m_ec2, ec, "copy", from, to); 2826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __copy(it->path(), to / it->path().filename(), 2836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier options | copy_options::__in_recursive_copy, ec); 2846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec && *ec) { return; } 2856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 2876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 2886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool __copy_file(const path& from, const path& to, copy_options options, 2916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code *ec) 2926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 293af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier using StatT = struct ::stat; 294af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier if (ec) 295af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier ec->clear(); 2966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 2976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 298af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier StatT from_stat; 299af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier auto from_st = detail::posix_stat(from, from_stat, &m_ec); 3006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (not is_regular_file(from_st)) { 301af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier if (not m_ec) 302af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier m_ec = make_error_code(errc::not_supported); 303af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier set_or_throw(m_ec, ec, "copy_file", from, to); 304af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier return false; 3056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 307af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier StatT to_stat; 308af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier auto to_st = detail::posix_stat(to, to_stat, &m_ec); 3096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!status_known(to_st)) { 3106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "copy_file", from, to); 3116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const bool to_exists = exists(to_st); 3151e1bbc7437f4679ce8b6ed5984f2cc72a96f3349Eric Fiselier if (to_exists && !is_regular_file(to_st)) { 3161e1bbc7437f4679ce8b6ed5984f2cc72a96f3349Eric Fiselier set_or_throw(make_error_code(errc::not_supported), ec, "copy_file", from, to); 3171e1bbc7437f4679ce8b6ed5984f2cc72a96f3349Eric Fiselier return false; 3181e1bbc7437f4679ce8b6ed5984f2cc72a96f3349Eric Fiselier } 319af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier if (to_exists && detail::stat_equivalent(from_stat, to_stat)) { 320af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from, 321af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier to); 322af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier return false; 323af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier } 3246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (to_exists && bool(copy_options::skip_existing & options)) { 3256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (to_exists && bool(copy_options::update_existing & options)) { 3286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto from_time = __last_write_time(from, ec); 3296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec && *ec) { return false; } 3306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto to_time = __last_write_time(to, ec); 3316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec && *ec) { return false; } 3326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (from_time <= to_time) { 3336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return detail::copy_file_impl(from, to, from_st.permissions(), ec); 3366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (!to_exists || bool(copy_options::overwrite_existing & options)) { 3386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return detail::copy_file_impl(from, to, from_st.permissions(), ec); 3396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else { 341af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from, 342af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier to); 343af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier return false; 3446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3451e1bbc7437f4679ce8b6ed5984f2cc72a96f3349Eric Fiselier 3461e1bbc7437f4679ce8b6ed5984f2cc72a96f3349Eric Fiselier _LIBCPP_UNREACHABLE(); 3476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __copy_symlink(const path& existing_symlink, const path& new_symlink, 3506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code *ec) 3516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 3526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const path real_path(__read_symlink(existing_symlink, ec)); 3536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec && *ec) { return; } 3546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // NOTE: proposal says you should detect if you should call 3556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // create_symlink or create_directory_symlink. I don't think this 3566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // is needed with POSIX 3576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __create_symlink(real_path, new_symlink, ec); 3586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool __create_directories(const path& p, std::error_code *ec) 3626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 3636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 3646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto const st = detail::posix_stat(p, &m_ec); 3656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!status_known(st)) { 3666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "create_directories", p); 3676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3686e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (is_directory(st)) { 3706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 3716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (exists(st)) { 3746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(make_error_code(errc::file_exists), 3756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec, "create_directories", p); 3766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const path parent = p.parent_path(); 3806e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!parent.empty()) { 3816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const file_status parent_st = status(parent, m_ec); 3826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (not status_known(parent_st)) { 3836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "create_directories", p); 3846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 3856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (not exists(parent_st)) { 3876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier __create_directories(parent, ec); 3886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec && *ec) { return false; } 3896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 3916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return __create_directory(p, ec); 3926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 3936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 3946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool __create_directory(const path& p, std::error_code *ec) 3956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 3966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 3976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::mkdir(p.c_str(), static_cast<int>(perms::all)) == 0) 3986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return true; 3996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (errno != EEXIST || !is_directory(p)) 4006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "create_directory", p); 4016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 4026e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool __create_directory(path const & p, path const & attributes, 4056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code *ec) 4066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 4076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat attr_stat; 4086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code mec; 4096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto st = detail::posix_stat(attributes, attr_stat, &mec); 4106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!status_known(st)) { 4116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(mec, ec, "create_directory", p, attributes); 4126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 4136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 4146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 4156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::mkdir(p.c_str(), attr_stat.st_mode) == 0) 4166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return true; 4176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (errno != EEXIST || !is_directory(p)) 4186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "create_directory", p, attributes); 4196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 4206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __create_directory_symlink(path const & from, path const & to, 4236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code *ec){ 4246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::symlink(from.c_str(), to.c_str()) != 0) 4256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "create_directory_symlink", from, to); 4266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (ec) 4276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec->clear(); 4286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __create_hard_link(const path& from, const path& to, std::error_code *ec){ 4316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::link(from.c_str(), to.c_str()) == -1) 4326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "create_hard_link", from, to); 4336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (ec) 4346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec->clear(); 4356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __create_symlink(path const & from, path const & to, std::error_code *ec) { 4386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::symlink(from.c_str(), to.c_str()) == -1) 4406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "create_symlink", from, to); 4416e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (ec) 4426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec->clear(); 4436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierpath __current_path(std::error_code *ec) { 4466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto size = ::pathconf(".", _PC_PATH_MAX); 4476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier _LIBCPP_ASSERT(size >= 0, "pathconf returned a 0 as max size"); 4486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto buff = std::unique_ptr<char[]>(new char[size + 1]); 4506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier char* ret; 4516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if ((ret = ::getcwd(buff.get(), static_cast<size_t>(size))) == nullptr) { 4526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "current_path"); 4536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return {}; 4546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 4556e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 4566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return {buff.get()}; 4576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __current_path(const path& p, std::error_code *ec) { 4606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::chdir(p.c_str()) == -1) 4616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "current_path", p); 4626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (ec) 4636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec->clear(); 4646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool __equivalent(const path& p1, const path& p2, std::error_code *ec) 4676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 4683288eac67369acd35e37ee70d140af2836957f0bEric Fiselier auto make_unsupported_error = [&]() { 4693288eac67369acd35e37ee70d140af2836957f0bEric Fiselier set_or_throw(make_error_code(errc::not_supported), ec, 4703288eac67369acd35e37ee70d140af2836957f0bEric Fiselier "equivalent", p1, p2); 4713288eac67369acd35e37ee70d140af2836957f0bEric Fiselier return false; 4723288eac67369acd35e37ee70d140af2836957f0bEric Fiselier }; 4736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code ec1, ec2; 4746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat st1 = {}; 4756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat st2 = {}; 4766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto s1 = detail::posix_stat(p1.native(), st1, &ec1); 4773288eac67369acd35e37ee70d140af2836957f0bEric Fiselier if (!exists(s1)) 4783288eac67369acd35e37ee70d140af2836957f0bEric Fiselier return make_unsupported_error(); 4796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto s2 = detail::posix_stat(p2.native(), st2, &ec2); 4803288eac67369acd35e37ee70d140af2836957f0bEric Fiselier if (!exists(s2)) 4813288eac67369acd35e37ee70d140af2836957f0bEric Fiselier return make_unsupported_error(); 4826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 483af1fd7c75f5cb2a19c11339d60b4fa2da31fd901Eric Fiselier return detail::stat_equivalent(st1, st2); 4846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 4856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 4876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstd::uintmax_t __file_size(const path& p, std::error_code *ec) 4886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 4896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 4906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat st; 4916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier file_status fst = detail::posix_stat(p, st, &m_ec); 4926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!exists(fst) || !is_regular_file(fst)) { 4936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!m_ec) 4946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier m_ec = make_error_code(errc::not_supported); 4956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "file_size", p); 4966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return static_cast<uintmax_t>(-1); 4976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 4986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // is_regular_file(p) == true 4996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 5006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return static_cast<std::uintmax_t>(st.st_size); 5016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 5026e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 5036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstd::uintmax_t __hard_link_count(const path& p, std::error_code *ec) 5046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 5056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 5066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat st; 5076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier detail::posix_stat(p, st, &m_ec); 5086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (m_ec) { 5096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "hard_link_count", p); 5106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return static_cast<std::uintmax_t>(-1); 5116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 5126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 5136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return static_cast<std::uintmax_t>(st.st_nlink); 5146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 5156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 5166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 5176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool __fs_is_empty(const path& p, std::error_code *ec) 5186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 5196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 5206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 5216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat pst; 5226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto st = detail::posix_stat(p, pst, &m_ec); 52325dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier if (m_ec) { 52425dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier set_or_throw(m_ec, ec, "is_empty", p); 52525dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier return false; 52625dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier } 52725dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier else if (!is_directory(st) && !is_regular_file(st)) { 52825dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier m_ec = make_error_code(errc::not_supported); 52925dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier set_or_throw(m_ec, ec, "is_empty"); 53025dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier return false; 53125dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier } 53225dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier else if (is_directory(st)) { 53325dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier auto it = ec ? directory_iterator(p, *ec) : directory_iterator(p); 53425dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier if (ec && *ec) 53525dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier return false; 53625dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier return it == directory_iterator{}; 53725dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier } 5386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (is_regular_file(st)) 5396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return static_cast<std::uintmax_t>(pst.st_size) == 0; 54025dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier 54125dc5bdb887e80a232f86e5b54b298427392e1c7Eric Fiselier _LIBCPP_UNREACHABLE(); 5426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 5436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 5446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 54570f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiseliernamespace detail { namespace { 54670f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier 54750ca6f720fca3ef95813d1366bea47cd081814b6Eric Fiselierusing TimeSpec = struct timespec; 54850ca6f720fca3ef95813d1366bea47cd081814b6Eric Fiselierusing StatT = struct stat; 549fd0e7614738ac855b28f24631cff8e4d8986d100Eric Fiselier 550fd0e7614738ac855b28f24631cff8e4d8986d100Eric Fiselier#if defined(__APPLE__) 551fd0e7614738ac855b28f24631cff8e4d8986d100Eric FiselierTimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } 55214d7b698bfd65044583ae34ab136bd84016cc16eDon Hinton__attribute__((unused)) // Suppress warning 553fd0e7614738ac855b28f24631cff8e4d8986d100Eric FiselierTimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } 554fd0e7614738ac855b28f24631cff8e4d8986d100Eric Fiselier#else 555fd0e7614738ac855b28f24631cff8e4d8986d100Eric FiselierTimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } 556fd0e7614738ac855b28f24631cff8e4d8986d100Eric Fiselier__attribute__((unused)) // Suppress warning 557fd0e7614738ac855b28f24631cff8e4d8986d100Eric FiselierTimeSpec extract_atime(StatT const& st) { return st.st_atim; } 558fd0e7614738ac855b28f24631cff8e4d8986d100Eric Fiselier#endif 559fd0e7614738ac855b28f24631cff8e4d8986d100Eric Fiselier 56070f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier}} // end namespace detail 56170f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier 562b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselierusing FSTime = fs_time_util<file_time_type, time_t, struct timespec>; 563b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselier 5646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_time_type __last_write_time(const path& p, std::error_code *ec) 5656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 566d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier using namespace ::std::chrono; 5676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 5686e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat st; 5696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier detail::posix_stat(p, st, &m_ec); 5706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (m_ec) { 5716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "last_write_time", p); 5726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return file_time_type::min(); 5736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 574c0f860c9460cf084f9fbd3bd3635c06e839bcabbEric Fiselier if (ec) ec->clear(); 575c0f860c9460cf084f9fbd3bd3635c06e839bcabbEric Fiselier auto ts = detail::extract_mtime(st); 576b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselier if (!FSTime::is_representable(ts)) { 577d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier set_or_throw(error_code(EOVERFLOW, generic_category()), ec, 578d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier "last_write_time", p); 579d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier return file_time_type::min(); 580d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier } 581b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselier return FSTime::convert_timespec(ts); 5826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 5836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 5846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __last_write_time(const path& p, file_time_type new_time, 5856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code *ec) 5866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 5876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier using namespace std::chrono; 5886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 5896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 59068b20ca4d9c4bee2c2ad5a9240599b3e4b78d0baNico Weber#if !defined(_LIBCXX_USE_UTIMENSAT) 5916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // This implementation has a race condition between determining the 5926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // last access time and attempting to set it to the same value using 5936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // ::utimes 5946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::stat st; 5956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier file_status fst = detail::posix_stat(p, st, &m_ec); 5966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (m_ec && !status_known(fst)) { 5976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "last_write_time", p); 5986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return; 5996e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 600d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier auto atime = detail::extract_atime(st); 6016e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::timeval tbuf[2]; 602d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier tbuf[0].tv_sec = atime.tv_sec; 603d5fc5ca37f673f47938d3a36f6f762eee58a3a7aEric Fiselier tbuf[0].tv_usec = duration_cast<microseconds>(nanoseconds(atime.tv_nsec)).count(); 604b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselier const bool overflowed = !FSTime::set_times_checked<microseconds>( 60570f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier &tbuf[1].tv_sec, &tbuf[1].tv_usec, new_time); 60670f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier 60770f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier if (overflowed) { 60870f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier set_or_throw(make_error_code(errc::invalid_argument), ec, 60970f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier "last_write_time", p); 61070f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier return; 61170f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier } 6126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::utimes(p.c_str(), tbuf) == -1) { 6136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier m_ec = detail::capture_errno(); 6146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 6156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#else 6166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier struct ::timespec tbuf[2]; 6176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier tbuf[0].tv_sec = 0; 6186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier tbuf[0].tv_nsec = UTIME_OMIT; 61970f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier 620b2e9337b06425b4af554651d5f2fa65615eb009fEric Fiselier const bool overflowed = !FSTime::set_times_checked<nanoseconds>( 62170f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier &tbuf[1].tv_sec, &tbuf[1].tv_nsec, new_time); 62270f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier if (overflowed) { 62370f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier set_or_throw(make_error_code(errc::invalid_argument), 62470f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier ec, "last_write_time", p); 62570f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier return; 62670f7afec38f9b2064d9aa22440fde30234a58af2Eric Fiselier } 6276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::utimensat(AT_FDCWD, p.c_str(), tbuf, 0) == -1) { 6286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier m_ec = detail::capture_errno(); 6296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 6306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier#endif 6316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (m_ec) 6326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "last_write_time", p); 6336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (ec) 6346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec->clear(); 6356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 6366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __permissions(const path& p, perms prms, std::error_code *ec) 6396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 6406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6417c96ddb5639078164a3fe8bcfbf7a11d7f502afbEric Fiselier const bool resolve_symlinks = !bool(perms::symlink_nofollow & prms); 6426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const bool add_perms = bool(perms::add_perms & prms); 6436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const bool remove_perms = bool(perms::remove_perms & prms); 6446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier _LIBCPP_ASSERT(!(add_perms && remove_perms), 6456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier "Both add_perms and remove_perms are set"); 6466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 64755e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier bool set_sym_perms = false; 64855e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier prms &= perms::mask; 64955e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier if (!resolve_symlinks || (add_perms || remove_perms)) { 65055e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier std::error_code m_ec; 65155e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier file_status st = resolve_symlinks ? detail::posix_stat(p, &m_ec) 65255e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier : detail::posix_lstat(p, &m_ec); 65355e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier set_sym_perms = is_symlink(st); 6546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (m_ec) return set_or_throw(m_ec, ec, "permissions", p); 65555e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier _LIBCPP_ASSERT(st.permissions() != perms::unknown, 65655e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier "Permissions unexpectedly unknown"); 65755e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier if (add_perms) 65855e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier prms |= st.permissions(); 65955e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier else if (remove_perms) 66055e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier prms = st.permissions() & ~prms; 66155e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier } 66255e084dd4de60d5a80c1295653f1e41d45ce1c1bEric Fiselier const auto real_perms = detail::posix_convert_perms(prms); 6636e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier# if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD) 6656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const int flags = set_sym_perms ? AT_SYMLINK_NOFOLLOW : 0; 6666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::fchmodat(AT_FDCWD, p.c_str(), real_perms, flags) == -1) { 6677c96ddb5639078164a3fe8bcfbf7a11d7f502afbEric Fiselier return set_or_throw(ec, "permissions", p); 6687c96ddb5639078164a3fe8bcfbf7a11d7f502afbEric Fiselier } 6696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier# else 6706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (set_sym_perms) 6716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return set_or_throw(make_error_code(errc::operation_not_supported), 6726e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec, "permissions", p); 6736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::chmod(p.c_str(), real_perms) == -1) { 6746e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return set_or_throw(ec, "permissions", p); 6756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 6767c96ddb5639078164a3fe8bcfbf7a11d7f502afbEric Fiselier# endif 6776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 6786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 6796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6806e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierpath __read_symlink(const path& p, std::error_code *ec) { 6826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier char buff[PATH_MAX + 1]; 6836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code m_ec; 6846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ::ssize_t ret; 6856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if ((ret = ::readlink(p.c_str(), buff, PATH_MAX)) == -1) { 6866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "read_symlink", p); 6876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return {}; 6886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 6896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier _LIBCPP_ASSERT(ret <= PATH_MAX, "TODO"); 6906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier _LIBCPP_ASSERT(ret > 0, "TODO"); 6916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 6926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier buff[ret] = 0; 6936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return {buff}; 6946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 6956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6966e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 6976e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierbool __remove(const path& p, std::error_code *ec) { 6986e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 69945d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis 7006e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::remove(p.c_str()) == -1) { 70145d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis if (errno != ENOENT) 70245d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis set_or_throw(ec, "remove", p); 7036e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return false; 7046e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 7056e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return true; 7066e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7076e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7086e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliernamespace { 7096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7106e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstd::uintmax_t remove_all_impl(path const & p, std::error_code& ec) 7116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier{ 7126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const auto npos = static_cast<std::uintmax_t>(-1); 7136e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier const file_status st = __symlink_status(p, &ec); 7146e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) return npos; 7156e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::uintmax_t count = 1; 7166e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (is_directory(st)) { 7176e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier for (directory_iterator it(p, ec); !ec && it != directory_iterator(); 7186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier it.increment(ec)) { 7196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto other_count = remove_all_impl(it->path(), ec); 7206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) return npos; 7216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier count += other_count; 7226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 7236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) return npos; 7246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 7256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!__remove(p, &ec)) return npos; 7266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return count; 7276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} // end namespace 7306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierstd::uintmax_t __remove_all(const path& p, std::error_code *ec) { 73245d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis if (ec) ec->clear(); 73345d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis 7346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier std::error_code mec; 7356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto count = remove_all_impl(p, mec); 7366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (mec) { 73745d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis if (mec == errc::no_such_file_or_directory) { 73845d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis return 0; 73945d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis } else { 74045d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis set_or_throw(mec, ec, "remove_all", p); 74145d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis return static_cast<std::uintmax_t>(-1); 74245d5893943f0099a4ef827d699708cda005a37f5Ekaterina Vaartis } 7436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 7446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return count; 7456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __rename(const path& from, const path& to, std::error_code *ec) { 7486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::rename(from.c_str(), to.c_str()) == -1) 7496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "rename", from, to); 7506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (ec) 7516e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec->clear(); 7526e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7536e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7546e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiseliervoid __resize_file(const path& p, std::uintmax_t size, std::error_code *ec) { 7554b1c560ca313f8fdd268d93586b175b60124b738Eric Fiselier if (::truncate(p.c_str(), static_cast<::off_t>(size)) == -1) 7566e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "resize_file", p); 7576e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (ec) 7586e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier ec->clear(); 7596e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7606e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7616e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierspace_info __space(const path& p, std::error_code *ec) { 7626e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier space_info si; 763591e18f6aaa7f8a8ae1ed0e239708b5e752173bdEric Fiselier struct statvfs m_svfs = {}; 7646e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (::statvfs(p.c_str(), &m_svfs) == -1) { 7656e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(ec, "space", p); 7666e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier si.capacity = si.free = si.available = 7676e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier static_cast<std::uintmax_t>(-1); 7686e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return si; 7696e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 7706e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 7716e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // Multiply with overflow checking. 772591e18f6aaa7f8a8ae1ed0e239708b5e752173bdEric Fiselier auto do_mult = [&](std::uintmax_t& out, std::uintmax_t other) { 7736e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier out = other * m_svfs.f_frsize; 774fbdbb36015dc4695e07d00da213705f57b87f78dEric Fiselier if (other == 0 || out / other != m_svfs.f_frsize) 7756e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier out = static_cast<std::uintmax_t>(-1); 7766e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier }; 7776e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier do_mult(si.capacity, m_svfs.f_blocks); 7786e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier do_mult(si.free, m_svfs.f_bfree); 7796e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier do_mult(si.available, m_svfs.f_bavail); 7806e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return si; 7816e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7826e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7836e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_status __status(const path& p, std::error_code *ec) { 7846e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return detail::posix_stat(p, ec); 7856e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7866e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7876e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierfile_status __symlink_status(const path& p, std::error_code *ec) { 7886e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return detail::posix_lstat(p, ec); 7896e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7906e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7916e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierpath __system_complete(const path& p, std::error_code *ec) { 7926e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (ec) ec->clear(); 7936e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return absolute(p, current_path()); 7946e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 7956e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 7967566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasoolpath __temp_directory_path(std::error_code* ec) { 7977566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool const char* env_paths[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; 7987566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool const char* ret = nullptr; 7997566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool 8007566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool for (auto& ep : env_paths) 8017566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool if ((ret = std::getenv(ep))) 8027566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool break; 8037566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool if (ret == nullptr) 8047566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool ret = "/tmp"; 8057566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool 8067566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool path p(ret); 8077566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool std::error_code m_ec; 8087566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool if (!exists(p, m_ec) || !is_directory(p, m_ec)) { 8096e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!m_ec || m_ec == make_error_code(errc::no_such_file_or_directory)) 8107566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool m_ec = make_error_code(errc::not_a_directory); 8116e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier set_or_throw(m_ec, ec, "temp_directory_path"); 8126e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return {}; 8137566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool } 8147566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool 8157566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool if (ec) 8167566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool ec->clear(); 8177566869dabd82699f26c8c95f18de331ec3950ceSaleem Abdulrasool return p; 8186e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 8196e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 8206e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier// An absolute path is composed according to the table in [fs.op.absolute]. 8216e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselierpath absolute(const path& p, const path& base) { 8226e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto root_name = p.root_name(); 8236e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto root_dir = p.root_directory(); 8246e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 8256e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (!root_name.empty() && !root_dir.empty()) 8266e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return p; 8276e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 8286e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier auto abs_base = base.is_absolute() ? base : absolute(base); 8296e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 8306e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier /* !has_root_name && !has_root_dir */ 8316e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (root_name.empty() && root_dir.empty()) 8326e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier { 8336e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return abs_base / p; 8346e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 8356e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else if (!root_name.empty()) /* has_root_name && !has_root_dir */ 8366e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier { 8376e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return root_name / abs_base.root_directory() 8386e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier / 8396e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier abs_base.relative_path() / p.relative_path(); 8406e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 8416e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier else /* !has_root_name && has_root_dir */ 8426e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier { 8436e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier if (abs_base.has_root_name()) 8446e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return abs_base.root_name() / p; 8456e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier // else p is absolute, return outside of block 8466e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier } 8476e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier return p; 8486e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier} 8496e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier 8506e9a694dce70319e60dbdfb09cf055bacb4c948eEric Fiselier_LIBCPP_END_NAMESPACE_EXPERIMENTAL_FILESYSTEM 851