diff --git a/Userland/Libraries/LibCore/System.cpp b/Userland/Libraries/LibCore/System.cpp index 923281510b..820ccb9b1f 100644 --- a/Userland/Libraries/LibCore/System.cpp +++ b/Userland/Libraries/LibCore/System.cpp @@ -1563,16 +1563,35 @@ ErrorOr socketpair(int domain, int type, int protocol, int sv[2]) return {}; } -ErrorOr> pipe2([[maybe_unused]] int flags) +ErrorOr> pipe2(int flags) { Array fds; + #if defined(__unix__) if (::pipe2(fds.data(), flags) < 0) return Error::from_syscall("pipe2"sv, -errno); #else if (::pipe(fds.data()) < 0) return Error::from_syscall("pipe2"sv, -errno); + + // Ensure we don't leak the fds if any of the system calls below fail. + AK::ArmedScopeGuard close_fds { [&]() { + MUST(close(fds[0])); + MUST(close(fds[1])); + } }; + + if ((flags & O_CLOEXEC) != 0) { + TRY(fcntl(fds[0], F_SETFD, FD_CLOEXEC)); + TRY(fcntl(fds[1], F_SETFD, FD_CLOEXEC)); + } + if ((flags & O_NONBLOCK) != 0) { + TRY(fcntl(fds[0], F_SETFL, TRY(fcntl(fds[0], F_GETFL)) | O_NONBLOCK)); + TRY(fcntl(fds[1], F_SETFL, TRY(fcntl(fds[1], F_GETFL)) | O_NONBLOCK)); + } + + close_fds.disarm(); #endif + return fds; }