From 70a99e494da6d265774899d7674097fac05b817f Mon Sep 17 00:00:00 2001 From: ridiculous_fish Date: Sun, 4 Jan 2015 01:21:23 -0800 Subject: [PATCH] Mark libnotify FDs as CLO_EXEC Fixes a fd leak on OS X --- env_universal_common.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/env_universal_common.cpp b/env_universal_common.cpp index 15c1524d8..a8d45bcd9 100644 --- a/env_universal_common.cpp +++ b/env_universal_common.cpp @@ -1275,9 +1275,18 @@ class universal_notifier_notifyd_t : public universal_notifier_t } if (this->notify_fd >= 0) { - // Mark us for non-blocking reads, with CLO_EXEC + // Mark us for non-blocking reads, and CLO_EXEC int flags = fcntl(this->notify_fd, F_GETFL, 0); - fcntl(this->notify_fd, F_SETFL, flags | O_NONBLOCK | FD_CLOEXEC); + if (flags >= 0 && ! (flags & O_NONBLOCK)) + { + fcntl(this->notify_fd, F_SETFL, flags | O_NONBLOCK); + } + + set_cloexec(this->notify_fd); + // Serious hack: notify_fd is likely the read end of a pipe. The other end is owned by libnotify, which does not mark it as CLO_EXEC (it should!) + // The next fd is probably notify_fd + 1 + // Do it ourselves. If the implementation changes and some other FD gets marked as CLO_EXEC, that's probably a good thing. + set_cloexec(this->notify_fd + 1); } #endif }