]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/src/filesystem/ops-common.h
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / src / filesystem / ops-common.h
CommitLineData
641cb5a6
JW
1// Filesystem operation utilities -*- C++ -*-
2
a5544970 3// Copyright (C) 2014-2019 Free Software Foundation, Inc.
641cb5a6
JW
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
9534a5e6
JW
37#if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
38# include <utime.h> // utime
39#endif
40
41#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
42# include <wchar.h>
43#endif
641cb5a6
JW
44
45namespace std _GLIBCXX_VISIBILITY(default)
46{
47_GLIBCXX_BEGIN_NAMESPACE_VERSION
48namespace filesystem
49{
9534a5e6
JW
50namespace __gnu_posix
51{
52#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
53// Adapt the Windows _wxxx functions to look like POSIX xxx, but for wchar_t*.
54 inline int open(const wchar_t* path, int flags)
55 { return ::_wopen(path, flags); }
56
57 inline int open(const wchar_t* path, int flags, int mode)
58 { return ::_wopen(path, flags, mode); }
59
60 inline int close(int fd)
61 { return ::_close(fd); }
62
63 typedef struct ::_stat stat_type;
64
65 inline int stat(const wchar_t* path, stat_type* buffer)
66 { return ::_wstat(path, buffer); }
67
68 inline lstat(const wchar_t* path, stat_type* buffer)
69 {
70 // TODO symlinks not currently supported
71 return stat(path, buffer);
72 }
73
74 using ::mode_t;
75
76 inline int chmod(const wchar_t* path, mode_t mode)
77 { return ::_wchmod(path, mode); }
78
79 inline int mkdir(const wchar_t* path, mode_t)
80 { return ::_wmkdir(path); }
81
82 inline wchar_t* getcwd(wchar_t* buf, size_t size)
83 { return ::_wgetcwd(buf, size > (size_t)INT_MAX ? INT_MAX : (int)size); }
84
85 inline int chdir(const wchar_t* path)
86 { return ::_wchdir(path); }
87
88#if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
89 using utimbuf = _utimbuf;
90
91 inline int utime(const wchar_t* path, utimbuf* times)
92 { return ::_wutime(path, times); }
93#endif
94
95 inline int rename(const wchar_t* oldname, const wchar_t* newname)
96 { return _wrename(oldname, newname); }
97
98 inline int truncate(const wchar_t* path, _off64_t length)
99 {
100 const int fd = ::_wopen(path, _O_BINARY|_O_RDWR);
101 if (fd == -1)
102 return fd;
103 const int ret = ::ftruncate64(fd, length);
104 int err;
105 ::_get_errno(&err);
106 ::_close(fd);
107 ::_set_errno(err);
108 return ret;
109 }
110 using char_type = wchar_t;
111#else // _GLIBCXX_FILESYSTEM_IS_WINDOWS
112 using ::open;
113 using ::close;
114#ifdef _GLIBCXX_HAVE_SYS_STAT_H
115 typedef struct ::stat stat_type;
116 using ::stat;
117 using ::lstat;
118#endif
119 using ::mode_t;
120 using ::chmod;
121 using ::mkdir;
122 using ::getcwd;
123 using ::chdir;
124#if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
125 using ::utimbuf;
126 using ::utime;
127#endif
128 using ::rename;
129 using ::truncate;
130 using char_type = char;
131#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS
132} // namespace __gnu_posix
133
641cb5a6
JW
134 template<typename Bitmask>
135 inline bool is_set(Bitmask obj, Bitmask bits)
136 {
137 return (obj & bits) != Bitmask::none;
138 }
139
140 inline bool
141 is_not_found_errno(int err) noexcept
142 {
143 return err == ENOENT || err == ENOTDIR;
144 }
145
146#ifdef _GLIBCXX_HAVE_SYS_STAT_H
9534a5e6 147 using __gnu_posix::stat_type;
641cb5a6
JW
148
149 inline std::chrono::system_clock::time_point
150 file_time(const stat_type& st, std::error_code& ec) noexcept
151 {
152 using namespace std::chrono;
153#ifdef _GLIBCXX_USE_ST_MTIM
154 time_t s = st.st_mtim.tv_sec;
155 nanoseconds ns{st.st_mtim.tv_nsec};
156#else
157 time_t s = st.st_mtime;
158 nanoseconds ns{};
159#endif
160
161 if (s >= (nanoseconds::max().count() / 1e9))
162 {
163 ec = std::make_error_code(std::errc::value_too_large); // EOVERFLOW
164 return system_clock::time_point::min();
165 }
166 ec.clear();
167 return system_clock::time_point{seconds{s} + ns};
168 }
169
170 struct copy_options_existing_file
171 {
172 bool skip, update, overwrite;
173 };
174
175 bool
9534a5e6
JW
176 do_copy_file(const __gnu_posix::char_type* from,
177 const __gnu_posix::char_type* to,
641cb5a6
JW
178 copy_options_existing_file options,
179 stat_type* from_st, stat_type* to_st,
180 std::error_code& ec) noexcept;
181
9534a5e6
JW
182 void
183 do_space(const __gnu_posix::char_type* pathname,
184 uintmax_t& capacity, uintmax_t& free, uintmax_t& available,
185 std::error_code&);
186
641cb5a6
JW
187#endif // _GLIBCXX_HAVE_SYS_STAT_H
188
189} // namespace filesystem
190
191// BEGIN/END macros must be defined before including this file.
192_GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
193
194#ifdef _GLIBCXX_HAVE_SYS_STAT_H
9534a5e6 195 using std::filesystem::__gnu_posix::stat_type;
641cb5a6
JW
196
197 inline file_type
198 make_file_type(const stat_type& st) noexcept
199 {
200#ifdef _GLIBCXX_HAVE_S_ISREG
201 if (S_ISREG(st.st_mode))
202 return file_type::regular;
203 else if (S_ISDIR(st.st_mode))
204 return file_type::directory;
205 else if (S_ISCHR(st.st_mode))
206 return file_type::character;
207 else if (S_ISBLK(st.st_mode))
208 return file_type::block;
209 else if (S_ISFIFO(st.st_mode))
210 return file_type::fifo;
9534a5e6 211#ifdef S_ISLNK // not present in mingw
641cb5a6
JW
212 else if (S_ISLNK(st.st_mode))
213 return file_type::symlink;
9534a5e6 214#endif
d8dcc3a6 215#ifdef S_ISSOCK // not present until POSIX:2001
641cb5a6
JW
216 else if (S_ISSOCK(st.st_mode))
217 return file_type::socket;
d8dcc3a6 218#endif
641cb5a6
JW
219#endif
220 return file_type::unknown;
221 }
222
223 inline file_status
224 make_file_status(const stat_type& st) noexcept
225 {
226 return file_status{
227 make_file_type(st),
228 static_cast<perms>(st.st_mode) & perms::mask
229 };
230 }
231
232 inline std::filesystem::copy_options_existing_file
233 copy_file_options(copy_options opt)
234 {
235 using std::filesystem::is_set;
236 return {
237 is_set(opt, copy_options::skip_existing),
238 is_set(opt, copy_options::update_existing),
239 is_set(opt, copy_options::overwrite_existing)
240 };
241 }
242#endif // _GLIBCXX_HAVE_SYS_STAT_H
243
244_GLIBCXX_END_NAMESPACE_FILESYSTEM
245
246_GLIBCXX_END_NAMESPACE_VERSION
247} // namespace std
248
249#endif // _GLIBCXX_OPS_COMMON_H