Index: src/filesystem/operations.cpp =================================================================== --- src/filesystem/operations.cpp +++ src/filesystem/operations.cpp @@ -530,11 +530,20 @@ ErrorHandler err("canonical", ec, &orig_p, &cwd); path p = __do_absolute(orig_p, &cwd, ec); +#if _POSIX_VERSION >= 200112 + char *buff; + if ((buff = ::realpath(p.c_str(), NULL)) == nullptr) + return err.report(capture_errno()); + path ret = {buff}; + free(buff); + return ret; +#else char buff[PATH_MAX + 1]; char* ret; if ((ret = ::realpath(p.c_str(), buff)) == nullptr) return err.report(capture_errno()); return {ret}; +#endif } void __copy(const path& from, const path& to, copy_options options, @@ -1075,10 +1084,12 @@ path __read_symlink(const path& p, error_code* ec) { ErrorHandler err("read_symlink", ec, &p); + ::ssize_t ret; +#ifdef PATH_MAX char buff[PATH_MAX + 1]; error_code m_ec; - ::ssize_t ret; + if ((ret = ::readlink(p.c_str(), buff, PATH_MAX)) == -1) { return err.report(capture_errno()); } @@ -1086,6 +1097,23 @@ _LIBCPP_ASSERT(ret > 0, "TODO"); buff[ret] = 0; return {buff}; +#else + struct stat sb; + if (::lstat(p.c_str(), &sb) == -1) { + return err.report(capture_errno()); + } + size_t size = sb.st_size + 1; + auto buff = unique_ptr(new char[size]); + + if ((ret = ::readlink(p.c_str(), buff.get(), size)) == -1) + return err.report(capture_errno()); + if (ret >= size) + return err.report(errc::value_too_large); + _LIBCPP_ASSERT(ret > 0, "TODO"); + buff[ret] = 0; + path res = {buff.get()}; + return res; +#endif } bool __remove(const path& p, error_code* ec) {