diff --git a/include/llvm/Support/FileSystem.h b/include/llvm/Support/FileSystem.h index 11622aa52f8..0428f837d2a 100644 --- a/include/llvm/Support/FileSystem.h +++ b/include/llvm/Support/FileSystem.h @@ -717,7 +717,11 @@ enum OpenFlags : unsigned { F_Append = 2, // For compatibility /// Delete the file on close. Only makes a difference on windows. - OF_Delete = 4 + OF_Delete = 4, + + /// When a child process is launched, this file should remain open in the + /// child process. + OF_ChildInherit = 8, }; /// Create a uniquely named file. diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc index c4c4cfc3afe..f3f529e54d7 100644 --- a/lib/Support/Unix/Path.inc +++ b/lib/Support/Unix/Path.inc @@ -753,7 +753,8 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, Result |= O_APPEND; #ifdef O_CLOEXEC - Result |= O_CLOEXEC; + if (!(Flags & OF_ChildInherit)) + Result |= O_CLOEXEC; #endif return Result; @@ -770,9 +771,11 @@ std::error_code openFile(const Twine &Name, int &ResultFD, 0) return std::error_code(errno, std::generic_category()); #ifndef O_CLOEXEC - int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC); - (void)r; - assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed"); + if (!(Flags & OF_ChildInherit)) { + int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC); + (void)r; + assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed"); + } #endif return std::error_code(); } diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc index 6017fcedc33..9173206d816 100644 --- a/lib/Support/Windows/Path.inc +++ b/lib/Support/Windows/Path.inc @@ -1104,15 +1104,21 @@ static DWORD nativeAccess(FileAccess Access, OpenFlags Flags) { static std::error_code openNativeFileInternal(const Twine &Name, file_t &ResultFile, DWORD Disp, - DWORD Access, DWORD Flags) { + DWORD Access, DWORD Flags, + bool Inherit = false) { SmallVector PathUTF16; if (std::error_code EC = widenPath(Name, PathUTF16)) return EC; + SECURITY_ATTRIBUTES SA; + SA.nLength = sizeof(SA); + SA.lpSecurityDescriptor = nullptr; + SA.bInheritHandle = Inherit; + HANDLE H = ::CreateFileW(PathUTF16.begin(), Access, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, Disp, Flags, NULL); + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &SA, + Disp, Flags, NULL); if (H == INVALID_HANDLE_VALUE) { DWORD LastError = ::GetLastError(); std::error_code EC = mapWindowsError(LastError); @@ -1140,9 +1146,13 @@ Expected openNativeFile(const Twine &Name, CreationDisposition Disp, DWORD NativeDisp = nativeDisposition(Disp, Flags); DWORD NativeAccess = nativeAccess(Access, Flags); + bool Inherit = false; + if (Flags & OF_ChildInherit) + Inherit = true; + file_t Result; - std::error_code EC = openNativeFileInternal(Name, Result, NativeDisp, - NativeAccess, NativeFlags); + std::error_code EC = openNativeFileInternal( + Name, Result, NativeDisp, NativeAccess, NativeFlags, Inherit); if (EC) return errorCodeToError(EC); return Result;