diff options
Diffstat (limited to 'libcxx/src/filesystem/operations.cpp')
-rw-r--r-- | libcxx/src/filesystem/operations.cpp | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp index 8a7d6cc..6253d15 100644 --- a/libcxx/src/filesystem/operations.cpp +++ b/libcxx/src/filesystem/operations.cpp @@ -460,8 +460,21 @@ path __current_path(error_code* ec) { typedef decltype(&::free) Deleter; Deleter deleter = &::free; #else + errno = 0; // Note: POSIX mandates that modifying `errno` is thread-safe. auto size = ::pathconf(".", _PC_PATH_MAX); - _LIBCPP_ASSERT_UNCATEGORIZED(size >= 0, "pathconf returned a 0 as max size"); + if (size == -1) { + if (errno != 0) { + return err.report(capture_errno(), "call to pathconf failed"); + + // `pathconf` returns `-1` without an error to indicate no limit. + } else { +# if defined(__MVS__) && !defined(PATH_MAX) + size = _XOPEN_PATH_MAX + 1; +# else + size = PATH_MAX + 1; +# endif + } + } auto buff = unique_ptr<path::value_type[]>(new path::value_type[size + 1]); path::value_type* ptr = buff.get(); @@ -620,7 +633,9 @@ void __permissions(const path& p, perms prms, perm_options opts, error_code* ec) set_sym_perms = is_symlink(st); if (m_ec) return err.report(m_ec); - _LIBCPP_ASSERT_UNCATEGORIZED(st.permissions() != perms::unknown, "Permissions unexpectedly unknown"); + // TODO(hardening): double-check this assertion -- it might be a valid (if rare) case when the permissions are + // unknown. + _LIBCPP_ASSERT_VALID_EXTERNAL_API_CALL(st.permissions() != perms::unknown, "Permissions unexpectedly unknown"); if (add_perms) prms |= st.permissions(); else if (remove_perms) @@ -667,7 +682,7 @@ path __read_symlink(const path& p, error_code* ec) { detail::SSizeT ret; if ((ret = detail::readlink(p.c_str(), buff.get(), size)) == -1) return err.report(capture_errno()); - _LIBCPP_ASSERT_UNCATEGORIZED(ret > 0, "TODO"); + // Note that `ret` returning `0` would work, resulting in a valid empty string being returned. if (static_cast<size_t>(ret) >= size) return err.report(errc::value_too_large); buff[ret] = 0; |