1 // Filesystem operation utilities -*- C++ -*- 2 3 // Copyright (C) 2014-2018 Free Software Foundation, Inc. 4 // 5 // This file is part of the GNU ISO C++ Library. This library is free 6 // software; you can redistribute it and/or modify it under the 7 // terms of the GNU General Public License as published by the 8 // Free Software Foundation; either version 3, or (at your option) 9 // any later version. 10 11 // This library is distributed in the hope that it will be useful, 12 // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 // GNU General Public License for more details. 15 16 // Under Section 7 of GPL version 3, you are granted additional 17 // permissions described in the GCC Runtime Library Exception, version 18 // 3.1, as published by the Free Software Foundation. 19 20 // You should have received a copy of the GNU General Public License and 21 // a copy of the GCC Runtime Library Exception along with this program; 22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 // <http://www.gnu.org/licenses/>. 24 25 #ifndef _GLIBCXX_OPS_COMMON_H 26 #define _GLIBCXX_OPS_COMMON_H 1 27 28 #include <chrono> 29 30 #ifdef _GLIBCXX_HAVE_UNISTD_H 31 # include <unistd.h> 32 # if defined(_GLIBCXX_HAVE_SYS_STAT_H) && defined(_GLIBCXX_HAVE_SYS_TYPES_H) 33 # include <sys/types.h> 34 # include <sys/stat.h> 35 # endif 36 #endif 37 38 namespace std _GLIBCXX_VISIBILITY(default) 39 { 40 _GLIBCXX_BEGIN_NAMESPACE_VERSION 41 namespace filesystem 42 { 43 template<typename Bitmask> 44 inline bool is_set(Bitmask obj, Bitmask bits) 45 { 46 return (obj & bits) != Bitmask::none; 47 } 48 49 inline bool 50 is_not_found_errno(int err) noexcept 51 { 52 return err == ENOENT || err == ENOTDIR; 53 } 54 55 #ifdef _GLIBCXX_HAVE_SYS_STAT_H 56 typedef struct ::stat stat_type; 57 58 inline std::chrono::system_clock::time_point 59 file_time(const stat_type& st, std::error_code& ec) noexcept 60 { 61 using namespace std::chrono; 62 #ifdef _GLIBCXX_USE_ST_MTIM 63 time_t s = st.st_mtim.tv_sec; 64 nanoseconds ns{st.st_mtim.tv_nsec}; 65 #else 66 time_t s = st.st_mtime; 67 nanoseconds ns{}; 68 #endif 69 70 if (s >= (nanoseconds::max().count() / 1e9)) 71 { 72 ec = std::make_error_code(std::errc::value_too_large); // EOVERFLOW 73 return system_clock::time_point::min(); 74 } 75 ec.clear(); 76 return system_clock::time_point{seconds{s} + ns}; 77 } 78 79 struct copy_options_existing_file 80 { 81 bool skip, update, overwrite; 82 }; 83 84 bool 85 do_copy_file(const char* from, const char* to, 86 copy_options_existing_file options, 87 stat_type* from_st, stat_type* to_st, 88 std::error_code& ec) noexcept; 89 90 #endif // _GLIBCXX_HAVE_SYS_STAT_H 91 92 } // namespace filesystem 93 94 // BEGIN/END macros must be defined before including this file. 95 _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM 96 97 #ifdef _GLIBCXX_HAVE_SYS_STAT_H 98 typedef struct ::stat stat_type; 99 100 inline file_type 101 make_file_type(const stat_type& st) noexcept 102 { 103 #ifdef _GLIBCXX_HAVE_S_ISREG 104 if (S_ISREG(st.st_mode)) 105 return file_type::regular; 106 else if (S_ISDIR(st.st_mode)) 107 return file_type::directory; 108 else if (S_ISCHR(st.st_mode)) 109 return file_type::character; 110 else if (S_ISBLK(st.st_mode)) 111 return file_type::block; 112 else if (S_ISFIFO(st.st_mode)) 113 return file_type::fifo; 114 else if (S_ISLNK(st.st_mode)) 115 return file_type::symlink; 116 #ifdef S_ISSOCK // not present until POSIX:2001 117 else if (S_ISSOCK(st.st_mode)) 118 return file_type::socket; 119 #endif 120 #endif 121 return file_type::unknown; 122 } 123 124 inline file_status 125 make_file_status(const stat_type& st) noexcept 126 { 127 return file_status{ 128 make_file_type(st), 129 static_cast<perms>(st.st_mode) & perms::mask 130 }; 131 } 132 133 inline std::filesystem::copy_options_existing_file 134 copy_file_options(copy_options opt) 135 { 136 using std::filesystem::is_set; 137 return { 138 is_set(opt, copy_options::skip_existing), 139 is_set(opt, copy_options::update_existing), 140 is_set(opt, copy_options::overwrite_existing) 141 }; 142 } 143 #endif // _GLIBCXX_HAVE_SYS_STAT_H 144 145 _GLIBCXX_END_NAMESPACE_FILESYSTEM 146 147 _GLIBCXX_END_NAMESPACE_VERSION 148 } // namespace std 149 150 #endif // _GLIBCXX_OPS_COMMON_H 151