Skip to content
This repository was archived by the owner on Apr 23, 2020. It is now read-only.

Commit bc083d5

Browse files
author
Zachary Turner
committed
Add a file open flag that disables O_CLOEXEC.
O_CLOEXEC is the right default, but occasionally you don't want this. This is especially true for tools like debuggers where you might need to spawn the child process with specific files already open, but it's occasionally useful in other scenarios as well, like when you want to do some IPC between parent and child. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@334293 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9d5c29c commit bc083d5

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

include/llvm/Support/FileSystem.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,11 @@ enum OpenFlags : unsigned {
717717
F_Append = 2, // For compatibility
718718

719719
/// Delete the file on close. Only makes a difference on windows.
720-
OF_Delete = 4
720+
OF_Delete = 4,
721+
722+
/// When a child process is launched, this file should remain open in the
723+
/// child process.
724+
OF_ChildInherit = 8,
721725
};
722726

723727
/// Create a uniquely named file.

lib/Support/Unix/Path.inc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -753,7 +753,8 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags,
753753
Result |= O_APPEND;
754754

755755
#ifdef O_CLOEXEC
756-
Result |= O_CLOEXEC;
756+
if (!(Flags & OF_ChildInherit))
757+
Result |= O_CLOEXEC;
757758
#endif
758759

759760
return Result;
@@ -770,9 +771,11 @@ std::error_code openFile(const Twine &Name, int &ResultFD,
770771
0)
771772
return std::error_code(errno, std::generic_category());
772773
#ifndef O_CLOEXEC
773-
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
774-
(void)r;
775-
assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed");
774+
if (!(Flags & OF_ChildInherit)) {
775+
int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
776+
(void)r;
777+
assert(r == 0 && "fcntl(F_SETFD, FD_CLOEXEC) failed");
778+
}
776779
#endif
777780
return std::error_code();
778781
}

lib/Support/Windows/Path.inc

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,15 +1104,21 @@ static DWORD nativeAccess(FileAccess Access, OpenFlags Flags) {
11041104

11051105
static std::error_code openNativeFileInternal(const Twine &Name,
11061106
file_t &ResultFile, DWORD Disp,
1107-
DWORD Access, DWORD Flags) {
1107+
DWORD Access, DWORD Flags,
1108+
bool Inherit = false) {
11081109
SmallVector<wchar_t, 128> PathUTF16;
11091110
if (std::error_code EC = widenPath(Name, PathUTF16))
11101111
return EC;
11111112

1113+
SECURITY_ATTRIBUTES SA;
1114+
SA.nLength = sizeof(SA);
1115+
SA.lpSecurityDescriptor = nullptr;
1116+
SA.bInheritHandle = Inherit;
1117+
11121118
HANDLE H =
11131119
::CreateFileW(PathUTF16.begin(), Access,
1114-
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
1115-
NULL, Disp, Flags, NULL);
1120+
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, &SA,
1121+
Disp, Flags, NULL);
11161122
if (H == INVALID_HANDLE_VALUE) {
11171123
DWORD LastError = ::GetLastError();
11181124
std::error_code EC = mapWindowsError(LastError);
@@ -1140,9 +1146,13 @@ Expected<file_t> openNativeFile(const Twine &Name, CreationDisposition Disp,
11401146
DWORD NativeDisp = nativeDisposition(Disp, Flags);
11411147
DWORD NativeAccess = nativeAccess(Access, Flags);
11421148

1149+
bool Inherit = false;
1150+
if (Flags & OF_ChildInherit)
1151+
Inherit = true;
1152+
11431153
file_t Result;
1144-
std::error_code EC = openNativeFileInternal(Name, Result, NativeDisp,
1145-
NativeAccess, NativeFlags);
1154+
std::error_code EC = openNativeFileInternal(
1155+
Name, Result, NativeDisp, NativeAccess, NativeFlags, Inherit);
11461156
if (EC)
11471157
return errorCodeToError(EC);
11481158
return Result;

0 commit comments

Comments
 (0)