]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/src/filesystem/ops-common.h
Implement C++17 Filesystem library
[thirdparty/gcc.git] / libstdc++-v3 / src / filesystem / ops-common.h
1 // Filesystem operation utilities -*- C++ -*-
2
3 // Copyright (C) 2014-2017 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 else if (S_ISSOCK(st.st_mode))
117 return file_type::socket;
118 #endif
119 return file_type::unknown;
120 }
121
122 inline file_status
123 make_file_status(const stat_type& st) noexcept
124 {
125 return file_status{
126 make_file_type(st),
127 static_cast<perms>(st.st_mode) & perms::mask
128 };
129 }
130
131 inline std::filesystem::copy_options_existing_file
132 copy_file_options(copy_options opt)
133 {
134 using std::filesystem::is_set;
135 return {
136 is_set(opt, copy_options::skip_existing),
137 is_set(opt, copy_options::update_existing),
138 is_set(opt, copy_options::overwrite_existing)
139 };
140 }
141 #endif // _GLIBCXX_HAVE_SYS_STAT_H
142
143 _GLIBCXX_END_NAMESPACE_FILESYSTEM
144
145 _GLIBCXX_END_NAMESPACE_VERSION
146 } // namespace std
147
148 #endif // _GLIBCXX_OPS_COMMON_H