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

source code of libcxx/src/filesystem/directory_entry.cpp