xref: /freebsd/contrib/llvm-project/libcxx/src/filesystem/directory_entry.cpp (revision cb14a3fe5122c879eae1fb480ed7ce82a699ddb6)
106c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric 
906c3fb27SDimitry Andric #include <__config>
1006c3fb27SDimitry Andric #include <cstdint>
1106c3fb27SDimitry Andric #include <filesystem>
1206c3fb27SDimitry Andric #include <system_error>
1306c3fb27SDimitry Andric 
1406c3fb27SDimitry Andric #include "file_descriptor.h"
1506c3fb27SDimitry Andric #include "posix_compat.h"
1606c3fb27SDimitry Andric #include "time_utils.h"
1706c3fb27SDimitry Andric 
1806c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM
1906c3fb27SDimitry Andric 
2006c3fb27SDimitry Andric error_code directory_entry::__do_refresh() noexcept {
2106c3fb27SDimitry Andric   __data_.__reset();
2206c3fb27SDimitry Andric   error_code failure_ec;
2306c3fb27SDimitry Andric 
2406c3fb27SDimitry Andric   detail::StatT full_st;
2506c3fb27SDimitry Andric   file_status st = detail::posix_lstat(__p_, full_st, &failure_ec);
2606c3fb27SDimitry Andric   if (!status_known(st)) {
2706c3fb27SDimitry Andric     __data_.__reset();
2806c3fb27SDimitry Andric     return failure_ec;
2906c3fb27SDimitry Andric   }
3006c3fb27SDimitry Andric 
315f757f3fSDimitry Andric   if (!filesystem::exists(st) || !filesystem::is_symlink(st)) {
3206c3fb27SDimitry Andric     __data_.__cache_type_    = directory_entry::_RefreshNonSymlink;
3306c3fb27SDimitry Andric     __data_.__type_          = st.type();
3406c3fb27SDimitry Andric     __data_.__non_sym_perms_ = st.permissions();
3506c3fb27SDimitry Andric   } else { // we have a symlink
3606c3fb27SDimitry Andric     __data_.__sym_perms_ = st.permissions();
3706c3fb27SDimitry Andric     // Get the information about the linked entity.
3806c3fb27SDimitry Andric     // Ignore errors from stat, since we don't want errors regarding symlink
3906c3fb27SDimitry Andric     // resolution to be reported to the user.
4006c3fb27SDimitry Andric     error_code ignored_ec;
4106c3fb27SDimitry Andric     st = detail::posix_stat(__p_, full_st, &ignored_ec);
4206c3fb27SDimitry Andric 
4306c3fb27SDimitry Andric     __data_.__type_          = st.type();
4406c3fb27SDimitry Andric     __data_.__non_sym_perms_ = st.permissions();
4506c3fb27SDimitry Andric 
4606c3fb27SDimitry Andric     // If we failed to resolve the link, then only partially populate the
4706c3fb27SDimitry Andric     // cache.
4806c3fb27SDimitry Andric     if (!status_known(st)) {
4906c3fb27SDimitry Andric       __data_.__cache_type_ = directory_entry::_RefreshSymlinkUnresolved;
5006c3fb27SDimitry Andric       return error_code{};
5106c3fb27SDimitry Andric     }
5206c3fb27SDimitry Andric     // Otherwise, we resolved the link, potentially as not existing.
5306c3fb27SDimitry Andric     // That's OK.
5406c3fb27SDimitry Andric     __data_.__cache_type_ = directory_entry::_RefreshSymlink;
5506c3fb27SDimitry Andric   }
5606c3fb27SDimitry Andric 
575f757f3fSDimitry Andric   if (filesystem::is_regular_file(st))
5806c3fb27SDimitry Andric     __data_.__size_ = static_cast<uintmax_t>(full_st.st_size);
5906c3fb27SDimitry Andric 
605f757f3fSDimitry Andric   if (filesystem::exists(st)) {
6106c3fb27SDimitry Andric     __data_.__nlink_ = static_cast<uintmax_t>(full_st.st_nlink);
6206c3fb27SDimitry Andric 
6306c3fb27SDimitry Andric     // Attempt to extract the mtime, and fail if it's not representable using
6406c3fb27SDimitry Andric     // file_time_type. For now we ignore the error, as we'll report it when
6506c3fb27SDimitry Andric     // the value is actually used.
6606c3fb27SDimitry Andric     error_code ignored_ec;
67*cb14a3feSDimitry Andric     __data_.__write_time_ = detail::__extract_last_write_time(__p_, full_st, &ignored_ec);
6806c3fb27SDimitry Andric   }
6906c3fb27SDimitry Andric 
7006c3fb27SDimitry Andric   return failure_ec;
7106c3fb27SDimitry Andric }
7206c3fb27SDimitry Andric 
7306c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_FILESYSTEM
74