Skip to content

Commit 0e997ef

Browse files
committed
[hurd] Fix unconditional use of PATH_MAX
Patch by Samuel Thibault The GNU/Hurd system does not define an arbitrary PATH_MAX limitation, the POSIX 2001 realpath extension can be used instead, and the size of symlinks can be determined. Reviewed as https://reviews.llvm.org/D54677 llvm-svn: 351414
1 parent cbda16e commit 0e997ef

File tree

1 file changed

+25
-6
lines changed

1 file changed

+25
-6
lines changed

libcxx/src/filesystem/operations.cpp

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -543,11 +543,19 @@ path __canonical(path const& orig_p, error_code* ec) {
543543
ErrorHandler<path> err("canonical", ec, &orig_p, &cwd);
544544

545545
path p = __do_absolute(orig_p, &cwd, ec);
546+
#if _POSIX_VERSION >= 200112
547+
std::unique_ptr<char, decltype(&::free)>
548+
hold(::realpath(p.c_str(), nullptr), &::free);
549+
if (hold.get() == nullptr)
550+
return err.report(capture_errno());
551+
return {hold.get()};
552+
#else
546553
char buff[PATH_MAX + 1];
547554
char* ret;
548555
if ((ret = ::realpath(p.c_str(), buff)) == nullptr)
549556
return err.report(capture_errno());
550557
return {ret};
558+
#endif
551559
}
552560

553561
void __copy(const path& from, const path& to, copy_options options,
@@ -1089,16 +1097,27 @@ void __permissions(const path& p, perms prms, perm_options opts,
10891097
path __read_symlink(const path& p, error_code* ec) {
10901098
ErrorHandler<path> err("read_symlink", ec, &p);
10911099

1092-
char buff[PATH_MAX + 1];
1093-
error_code m_ec;
1094-
::ssize_t ret;
1095-
if ((ret = ::readlink(p.c_str(), buff, PATH_MAX)) == -1) {
1100+
#ifdef PATH_MAX
1101+
struct NullDeleter { void operator()(void*) const {} };
1102+
const size_t size = PATH_MAX + 1;
1103+
char stack_buff[size];
1104+
auto buff = std::unique_ptr<char[], NullDeleter>(stack_buff);
1105+
#else
1106+
StatT sb;
1107+
if (::lstat(p.c_str(), &sb) == -1) {
10961108
return err.report(capture_errno());
10971109
}
1098-
_LIBCPP_ASSERT(ret <= PATH_MAX, "TODO");
1110+
const size_t size = sb.st_size + 1;
1111+
auto buff = unique_ptr<char[]>(new char[size]);
1112+
#endif
1113+
::ssize_t ret;
1114+
if ((ret = ::readlink(p.c_str(), buff.get(), size)) == -1)
1115+
return err.report(capture_errno());
10991116
_LIBCPP_ASSERT(ret > 0, "TODO");
1117+
if (static_cast<size_t>(ret) >= size)
1118+
return err.report(errc::value_too_large);
11001119
buff[ret] = 0;
1101-
return {buff};
1120+
return {buff.get()};
11021121
}
11031122

11041123
bool __remove(const path& p, error_code* ec) {

0 commit comments

Comments
 (0)