From a13897cf6f71a6837c4de5315c2d72989e6683ce Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 13 Sep 2017 17:37:28 +0200 Subject: [PATCH] system/FileDescriptor: add CheckDuplicate() --- src/system/FileDescriptor.cxx | 10 ++++++++++ src/system/FileDescriptor.hxx | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/src/system/FileDescriptor.cxx b/src/system/FileDescriptor.cxx index 15348215c..403aee068 100644 --- a/src/system/FileDescriptor.cxx +++ b/src/system/FileDescriptor.cxx @@ -188,6 +188,16 @@ FileDescriptor::DisableCloseOnExec() noexcept fcntl(fd, F_SETFD, old_flags & ~FD_CLOEXEC); } +bool +FileDescriptor::CheckDuplicate(int new_fd) noexcept +{ + if (fd == new_fd) { + DisableCloseOnExec(); + return true; + } else + return Duplicate(new_fd); +} + #endif #ifdef USE_EVENTFD diff --git a/src/system/FileDescriptor.hxx b/src/system/FileDescriptor.hxx index 02fc0ebfc..faec76319 100644 --- a/src/system/FileDescriptor.hxx +++ b/src/system/FileDescriptor.hxx @@ -146,6 +146,14 @@ public: bool Duplicate(int new_fd) const noexcept { return ::dup2(Get(), new_fd) == 0; } + + /** + * Similar to Duplicate(), but if destination and source file + * descriptor are equal, clear the close-on-exec flag. Use + * this method to inject file descriptors into a new child + * process, to be used by a newly executed program. + */ + bool CheckDuplicate(int new_fd) noexcept; #endif #ifdef USE_EVENTFD