mirror of
https://github.com/snoyberg/keter.git
synced 2024-12-15 01:23:09 +03:00
CloseOnExec for creating files
This should solve the text file busy issue. The problem was that while one green thread was writing a file to disk, another would already be forking a process for executing a separate app. That new process would retain a write FD to the file being created, which prevented that file from eventually being executed.
This commit is contained in:
parent
cbd0f9d19e
commit
bc095450b2
22
Keter/App.hs
22
Keter/App.hs
@ -24,16 +24,18 @@ import Codec.Compression.GZip (decompress)
|
|||||||
import qualified Filesystem.Path.CurrentOS as F
|
import qualified Filesystem.Path.CurrentOS as F
|
||||||
import Data.Yaml
|
import Data.Yaml
|
||||||
import Control.Applicative ((<$>), (<*>))
|
import Control.Applicative ((<$>), (<*>))
|
||||||
import System.PosixCompat.Files
|
|
||||||
import qualified Network
|
import qualified Network
|
||||||
import Data.Maybe (fromMaybe, mapMaybe)
|
import Data.Maybe (fromMaybe, mapMaybe)
|
||||||
import Control.Exception (onException, throwIO)
|
import Control.Exception (onException, throwIO, bracket)
|
||||||
import System.IO (hClose)
|
import System.IO (hClose)
|
||||||
import qualified Data.ByteString.Lazy as L
|
import qualified Data.ByteString.Lazy as L
|
||||||
import Data.Conduit (($$), yield, runResourceT)
|
import Data.Conduit (($$), yield)
|
||||||
import Data.Conduit.Binary (sinkFile)
|
|
||||||
import Data.Set (Set)
|
import Data.Set (Set)
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
import qualified Data.Conduit.List as CL
|
||||||
|
import System.Posix.IO.ByteString (fdWriteBuf, closeFd, FdOption (CloseOnExec), setFdOption, createFile)
|
||||||
|
import Foreign.Ptr (castPtr)
|
||||||
|
import Data.ByteString.Unsafe (unsafeUseAsCStringLen)
|
||||||
|
|
||||||
data Config = Config
|
data Config = Config
|
||||||
{ configExec :: F.FilePath
|
{ configExec :: F.FilePath
|
||||||
@ -121,8 +123,16 @@ unpackTar dir =
|
|||||||
case Tar.entryContent e of
|
case Tar.entryContent e of
|
||||||
Tar.NormalFile lbs _ -> do
|
Tar.NormalFile lbs _ -> do
|
||||||
createTree $ F.directory fp
|
createTree $ F.directory fp
|
||||||
runResourceT $ mapM_ yield (L.toChunks lbs) $$ sinkFile (F.encodeString fp)
|
let write fd bs = unsafeUseAsCStringLen bs $ \(ptr, len) -> do
|
||||||
setFileMode (F.encodeString fp) $ Tar.entryPermissions e
|
_ <- fdWriteBuf fd (castPtr ptr) (fromIntegral len)
|
||||||
|
return ()
|
||||||
|
bracket
|
||||||
|
(do
|
||||||
|
fd <- createFile (F.encode fp) $ Tar.entryPermissions e
|
||||||
|
setFdOption fd CloseOnExec True
|
||||||
|
return fd)
|
||||||
|
closeFd
|
||||||
|
(\fd -> mapM_ yield (L.toChunks lbs) $$ CL.mapM_ (write fd))
|
||||||
_ -> return ()
|
_ -> return ()
|
||||||
|
|
||||||
start :: TempFolder
|
start :: TempFolder
|
||||||
|
Loading…
Reference in New Issue
Block a user