Index: lib/Support/Unix/Path.inc =================================================================== --- lib/Support/Unix/Path.inc +++ lib/Support/Unix/Path.inc @@ -55,7 +55,7 @@ #include #if !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__FreeBSD__) && \ - !defined(__linux__) && !defined(__FreeBSD_kernel__) + !defined(__linux__) && !defined(__FreeBSD_kernel__) && !defined(_AIX) #include #define STATVFS statvfs #define FSTATVFS fstatvfs @@ -76,6 +76,10 @@ #endif #endif #include +#elif defined(_AIX) +#include +typedef uint_t uint; +#include #else #include #endif @@ -245,7 +249,7 @@ ErrorOr disk_space(const Twine &Path) { struct STATVFS Vfs; - if (::STATVFS(Path.str().c_str(), &Vfs)) + if (::STATVFS(const_cast(Path.str().c_str()), &Vfs)) return std::error_code(errno, std::generic_category()); auto FrSize = STATVFS_F_FRSIZE(Vfs); space_info SpaceInfo; @@ -405,6 +409,35 @@ StringRef fstype(Vfs.f_basetype); // NFS is the only non-local fstype?? return !fstype.equals("nfs"); +#elif defined(_AIX) + // Call mntctl; try more than twice in case of timing issues with a concurrent + // mount. + int ret; + size_t bufsize = 2048u; + std::unique_ptr buf; + int tries = 3; + while (tries--) { + buf = llvm::make_unique(bufsize); + ret = mntctl(MCTL_QUERY, bufsize, buf.get()); + if (ret != 0) + break; + bufsize = *reinterpret_cast(buf.get()); + buf.reset(); + } + if (ret == -1) + return false; + // Look for the correct vmount entry. + char *curobjptr = buf.get(); + while (ret--) { + struct vmount *vp = reinterpret_cast(curobjptr); + static_assert(sizeof(Vfs.f_fsid) == sizeof(vp->vmt_fsid), + "fsid length mismatch"); + if (memcmp(&Vfs.f_fsid, &vp->vmt_fsid, sizeof Vfs.f_fsid) == 0) + return (vp->vmt_flags & MNT_REMOTE) == 0; + + curobjptr += vp->vmt_length; + } + return false; #else return !!(STATVFS_F_FLAG(Vfs) & MNT_LOCAL); #endif @@ -412,7 +445,7 @@ std::error_code is_local(const Twine &Path, bool &Result) { struct STATVFS Vfs; - if (::STATVFS(Path.str().c_str(), &Vfs)) + if (::STATVFS(const_cast(Path.str().c_str()), &Vfs)) return std::error_code(errno, std::generic_category()); Result = is_local_impl(Vfs);