Index: cmake/config-ix.cmake =================================================================== --- cmake/config-ix.cmake +++ cmake/config-ix.cmake @@ -198,6 +198,7 @@ check_symbol_exists(strerror_r string.h HAVE_STRERROR_R) check_symbol_exists(strerror_s string.h HAVE_DECL_STRERROR_S) check_symbol_exists(setenv stdlib.h HAVE_SETENV) +check_symbol_exists(O_CLOEXEC "sys/types.h;sys/stat.h;fcntl.h" HAVE_O_CLOEXEC) if( PURE_WINDOWS ) check_symbol_exists(_chsize_s io.h HAVE__CHSIZE_S) Index: include/llvm/Config/config.h.cmake =================================================================== --- include/llvm/Config/config.h.cmake +++ include/llvm/Config/config.h.cmake @@ -153,6 +153,9 @@ /* Define to 1 if you have the header file, and it defines `DIR'. */ #cmakedefine HAVE_NDIR_H ${HAVE_NDIR_H} +/* Define to 1 if you have the O_CLOEXEC open(2) flag */ +#cmakedefine HAVE_O_CLOEXEC ${HAVE_O_CLOEXEC} + /* Define to 1 if you have the `posix_fallocate' function. */ #cmakedefine HAVE_POSIX_FALLOCATE ${HAVE_POSIX_FALLOCATE} Index: include/llvm/Support/FileSystem.h =================================================================== --- include/llvm/Support/FileSystem.h +++ include/llvm/Support/FileSystem.h @@ -638,7 +638,10 @@ F_Text = 4, /// Open the file for read and write. - F_RW = 8 + F_RW = 8, + + /// Make the handle inheritable for child processes. + F_Inheritable = 16, }; inline OpenFlags operator|(OpenFlags A, OpenFlags B) { Index: lib/Support/Unix/Path.inc =================================================================== --- lib/Support/Unix/Path.inc +++ lib/Support/Unix/Path.inc @@ -629,12 +629,26 @@ if (Flags & F_Excl) OpenFlags |= O_EXCL; +#ifdef HAVE_O_CLOEXEC + if (!(Flags & F_Inheritable)) + OpenFlags |= O_CLOEXEC; +#endif + SmallString<128> Storage; StringRef P = Name.toNullTerminatedStringRef(Storage); while ((ResultFD = open(P.begin(), OpenFlags, Mode)) < 0) { if (errno != EINTR) return std::error_code(errno, std::generic_category()); } + +#ifndef HAVE_O_CLOEXEC + if (!(Flags & F_Inheritable)) { + int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC); + (void)r; + assert(r == 0); + } +#endif + return std::error_code(); } Index: lib/Support/Windows/Path.inc =================================================================== --- lib/Support/Windows/Path.inc +++ lib/Support/Windows/Path.inc @@ -774,9 +774,14 @@ if (Flags & F_RW) Access |= GENERIC_READ; + SECURITY_ATTRIBUTES sa; + sa.nLength = sizeof sa; + sa.lpSecurityDescriptor = nullptr; + sa.bInheritHandle = Flags & F_Inheritable ? TRUE : FALSE; + HANDLE H = ::CreateFileW(PathUTF16.begin(), Access, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, - CreationDisposition, FILE_ATTRIBUTE_NORMAL, NULL); + FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, + CreationDisposition, FILE_ATTRIBUTE_NORMAL, nullptr); if (H == INVALID_HANDLE_VALUE) { DWORD LastError = ::GetLastError();