xref: /llvm-project/libcxx/src/filesystem/directory_entry.cpp (revision 9783f28cbb155e4a8d49c12e1c60ce14dcfaf0c7)
1c7d3c844SLouis Dionne //===----------------------------------------------------------------------===//
2c7d3c844SLouis Dionne //
3c7d3c844SLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4c7d3c844SLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5c7d3c844SLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6c7d3c844SLouis Dionne //
7c7d3c844SLouis Dionne //===----------------------------------------------------------------------===//
8c7d3c844SLouis Dionne 
9c7d3c844SLouis Dionne #include <__config>
10c7d3c844SLouis Dionne #include <cstdint>
11c7d3c844SLouis Dionne #include <filesystem>
12c7d3c844SLouis Dionne #include <system_error>
13c7d3c844SLouis Dionne 
14c7d3c844SLouis Dionne #include "file_descriptor.h"
15c7d3c844SLouis Dionne #include "posix_compat.h"
16c7d3c844SLouis Dionne #include "time_utils.h"
17c7d3c844SLouis Dionne 
18c7d3c844SLouis Dionne _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
19c7d3c844SLouis Dionne 
__do_refresh()20c7d3c844SLouis Dionne error_code directory_entry::__do_refresh() noexcept {
21c7d3c844SLouis Dionne   __data_.__reset();
22c7d3c844SLouis Dionne   error_code failure_ec;
23c7d3c844SLouis Dionne 
24c7d3c844SLouis Dionne   detail::StatT full_st;
25c7d3c844SLouis Dionne   file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
26c7d3c844SLouis Dionne   if (!status_known(st)) {
27c7d3c844SLouis Dionne     __data_.__reset();
28c7d3c844SLouis Dionne     return failure_ec;
29c7d3c844SLouis Dionne   }
30c7d3c844SLouis Dionne 
31ac8c9f1eSLouis Dionne   if (!filesystem::exists(st) || !filesystem::is_symlink(st)) {
32c7d3c844SLouis Dionne     __data_.__cache_type_    = directory_entry::_RefreshNonSymlink;
33c7d3c844SLouis Dionne     __data_.__type_          = st.type();
34c7d3c844SLouis Dionne     __data_.__non_sym_perms_ = st.permissions();
35c7d3c844SLouis Dionne   } else { // we have a symlink
36c7d3c844SLouis Dionne     __data_.__sym_perms_ = st.permissions();
37c7d3c844SLouis Dionne     // Get the information about the linked entity.
38c7d3c844SLouis Dionne     // Ignore errors from stat, since we don't want errors regarding symlink
39c7d3c844SLouis Dionne     // resolution to be reported to the user.
40c7d3c844SLouis Dionne     error_code ignored_ec;
41c7d3c844SLouis Dionne     st = detail::posix_stat(__p_, full_st, &ignored_ec);
42c7d3c844SLouis Dionne 
43c7d3c844SLouis Dionne     __data_.__type_          = st.type();
44c7d3c844SLouis Dionne     __data_.__non_sym_perms_ = st.permissions();
45c7d3c844SLouis Dionne 
46c7d3c844SLouis Dionne     // If we failed to resolve the link, then only partially populate the
47c7d3c844SLouis Dionne     // cache.
48c7d3c844SLouis Dionne     if (!status_known(st)) {
49c7d3c844SLouis Dionne       __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
50c7d3c844SLouis Dionne       return error_code{};
51c7d3c844SLouis Dionne     }
52c7d3c844SLouis Dionne     // Otherwise, we resolved the link, potentially as not existing.
53c7d3c844SLouis Dionne     // That's OK.
54c7d3c844SLouis Dionne     __data_.__cache_type_ = directory_entry::_RefreshSymlink;
55c7d3c844SLouis Dionne   }
56c7d3c844SLouis Dionne 
57ac8c9f1eSLouis Dionne   if (filesystem::is_regular_file(st))
58c7d3c844SLouis Dionne     __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
59c7d3c844SLouis Dionne 
60ac8c9f1eSLouis Dionne   if (filesystem::exists(st)) {
61c7d3c844SLouis Dionne     __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
62c7d3c844SLouis Dionne 
63c7d3c844SLouis Dionne     // Attempt to extract the mtime, and fail if it's not representable using
64c7d3c844SLouis Dionne     // file_time_type. For now we ignore the error, as we'll report it when
65c7d3c844SLouis Dionne     // the value is actually used.
66c7d3c844SLouis Dionne     error_code ignored_ec;
67*9783f28cSLouis Dionne     __data_.__write_time_ = detail::__extract_last_write_time(__p_, full_st, &ignored_ec);
68c7d3c844SLouis Dionne   }
69c7d3c844SLouis Dionne 
70c7d3c844SLouis Dionne   return failure_ec;
71c7d3c844SLouis Dionne }
72c7d3c844SLouis Dionne 
73c7d3c844SLouis Dionne _LIBCPP_END_NAMESPACE_FILESYSTEM
74