From 6ba848d2756cf7dd33c6bc5f5148d9ffca33340b Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 4 Sep 2025 15:04:03 -0400 Subject: [PATCH] avoid overhead of fcntl when setting close-on-exec unix-2.8.0 adds cloexec to OpenFileFlags, rather than needing to call setFdOption after opening. This also might avoid a race, if another thread started a process at just the wrong time, before the flag got set, it could inherit the FD. Unfortunately, the arm64-ancient build needs support for older versions of unix than that, so had to ifdef. That build is still needed to support using git-annex in termux on phones like mine, I have confirmed today. Sponsored-by: Luke T. Shumaker --- Git/LockFile.hs | 4 ++++ Utility/LockFile/Posix.hs | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Git/LockFile.hs b/Git/LockFile.hs index 70d8e5bb54..9d9042f453 100644 --- a/Git/LockFile.hs +++ b/Git/LockFile.hs @@ -53,8 +53,12 @@ openLock' lck = do #ifndef mingw32_HOST_OS -- On unix, git simply uses O_EXCL h <- openFdWithMode (fromOsPath lck) ReadWrite (Just 0O666) +#if MIN_VERSION_unix(2,8,0) + (defaultFileFlags { exclusive = True, cloexec = True }) +#else (defaultFileFlags { exclusive = True }) setFdOption h CloseOnExec True +#endif #else -- It's not entirely clear how git manages locking on Windows, -- since it's buried in the portability layer, and different diff --git a/Utility/LockFile/Posix.hs b/Utility/LockFile/Posix.hs index f74e3691a7..3ad3554a8b 100644 --- a/Utility/LockFile/Posix.hs +++ b/Utility/LockFile/Posix.hs @@ -5,6 +5,8 @@ - License: BSD-2-clause -} +{-# LANGUAGE CPP #-} + module Utility.LockFile.Posix ( LockHandle, lockShared, @@ -76,8 +78,13 @@ tryLock lockreq mode lockfile = uninterruptibleMask_ $ do openLockFile :: LockRequest -> Maybe ModeSetter -> LockFile -> IO Fd openLockFile lockreq filemode lockfile = do l <- applyModeSetter filemode lockfile $ \filemode' -> - openFdWithMode (fromOsPath lockfile) openfor filemode' defaultFileFlags + openFdWithMode (fromOsPath lockfile) openfor filemode' $ +#if MIN_VERSION_unix(2,8,0) + defaultFileFlags { cloexec = True } +#else + defaultFileFlags setFdOption l CloseOnExec True +#endif return l where openfor = case lockreq of