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
This commit is contained in:
Joey Hess 2025-09-04 15:04:03 -04:00
commit 6ba848d275
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
2 changed files with 12 additions and 1 deletions

View file

@ -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

View file

@ -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