1 // Filesystem operation utilities -*- C++ -*-
3 // Copyright (C) 2014-2018 Free Software Foundation, Inc.
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)
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.
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.
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/>.
25 #ifndef _GLIBCXX_OPS_COMMON_H
26 #define _GLIBCXX_OPS_COMMON_H 1
30 #ifdef _GLIBCXX_HAVE_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>
37 #if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
38 # include <utime.h> // utime
41 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
45 namespace std
_GLIBCXX_VISIBILITY(default)
47 _GLIBCXX_BEGIN_NAMESPACE_VERSION
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
); }
57 inline int open(const wchar_t* path
, int flags
, int mode
)
58 { return ::_wopen(path
, flags
, mode
); }
60 inline int close(int fd
)
61 { return ::_close(fd
); }
63 typedef struct ::_stat stat_type
;
65 inline int stat(const wchar_t* path
, stat_type
* buffer
)
66 { return ::_wstat(path
, buffer
); }
68 inline lstat(const wchar_t* path
, stat_type
* buffer
)
70 // TODO symlinks not currently supported
71 return stat(path
, buffer
);
76 inline int chmod(const wchar_t* path
, mode_t mode
)
77 { return ::_wchmod(path
, mode
); }
79 inline int mkdir(const wchar_t* path
, mode_t
)
80 { return ::_wmkdir(path
); }
82 inline wchar_t* getcwd(wchar_t* buf
, size_t size
)
83 { return ::_wgetcwd(buf
, size
> (size_t)INT_MAX
? INT_MAX
: (int)size
); }
85 inline int chdir(const wchar_t* path
)
86 { return ::_wchdir(path
); }
88 #if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
89 using utimbuf
= _utimbuf
;
91 inline int utime(const wchar_t* path
, utimbuf
* times
)
92 { return ::_wutime(path
, times
); }
95 inline int rename(const wchar_t* oldname
, const wchar_t* newname
)
96 { return _wrename(oldname
, newname
); }
98 inline int truncate(const wchar_t* path
, _off64_t length
)
100 const int fd
= ::_wopen(path
, _O_BINARY
|_O_RDWR
);
103 const int ret
= ::ftruncate64(fd
, length
);
110 using char_type
= wchar_t;
111 #else // _GLIBCXX_FILESYSTEM_IS_WINDOWS
114 #ifdef _GLIBCXX_HAVE_SYS_STAT_H
115 typedef struct ::stat stat_type
;
124 #if !_GLIBCXX_USE_UTIMENSAT && _GLIBCXX_HAVE_UTIME_H
130 using char_type
= char;
131 #endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS
132 } // namespace __gnu_posix
134 template<typename Bitmask
>
135 inline bool is_set(Bitmask obj
, Bitmask bits
)
137 return (obj
& bits
) != Bitmask::none
;
141 is_not_found_errno(int err
) noexcept
143 return err
== ENOENT
|| err
== ENOTDIR
;
146 #ifdef _GLIBCXX_HAVE_SYS_STAT_H
147 using __gnu_posix::stat_type
;
149 inline std::chrono::system_clock::time_point
150 file_time(const stat_type
& st
, std::error_code
& ec
) noexcept
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
};
157 time_t s
= st
.st_mtime
;
161 if (s
>= (nanoseconds::max().count() / 1e9
))
163 ec
= std::make_error_code(std::errc::value_too_large
); // EOVERFLOW
164 return system_clock::time_point::min();
167 return system_clock::time_point
{seconds
{s
} + ns
};
170 struct copy_options_existing_file
172 bool skip
, update
, overwrite
;
176 do_copy_file(const __gnu_posix::char_type
* from
,
177 const __gnu_posix::char_type
* to
,
178 copy_options_existing_file options
,
179 stat_type
* from_st
, stat_type
* to_st
,
180 std::error_code
& ec
) noexcept
;
183 do_space(const __gnu_posix::char_type
* pathname
,
184 uintmax_t& capacity
, uintmax_t& free
, uintmax_t& available
,
187 #endif // _GLIBCXX_HAVE_SYS_STAT_H
189 } // namespace filesystem
191 // BEGIN/END macros must be defined before including this file.
192 _GLIBCXX_BEGIN_NAMESPACE_FILESYSTEM
194 #ifdef _GLIBCXX_HAVE_SYS_STAT_H
195 using std::filesystem::__gnu_posix::stat_type
;
198 make_file_type(const stat_type
& st
) noexcept
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
;
211 #ifdef S_ISLNK // not present in mingw
212 else if (S_ISLNK(st
.st_mode
))
213 return file_type::symlink
;
215 #ifdef S_ISSOCK // not present until POSIX:2001
216 else if (S_ISSOCK(st
.st_mode
))
217 return file_type::socket
;
220 return file_type::unknown
;
224 make_file_status(const stat_type
& st
) noexcept
228 static_cast<perms
>(st
.st_mode
) & perms::mask
232 inline std::filesystem::copy_options_existing_file
233 copy_file_options(copy_options opt
)
235 using std::filesystem::is_set
;
237 is_set(opt
, copy_options::skip_existing
),
238 is_set(opt
, copy_options::update_existing
),
239 is_set(opt
, copy_options::overwrite_existing
)
242 #endif // _GLIBCXX_HAVE_SYS_STAT_H
244 _GLIBCXX_END_NAMESPACE_FILESYSTEM
246 _GLIBCXX_END_NAMESPACE_VERSION
249 #endif // _GLIBCXX_OPS_COMMON_H