temporary-1.1.2.4/000755 000765 000024 00000000000 12033302111 015476 5ustar00mbolingbrokestaff000000 000000 temporary-1.1.2.4/Distribution/000755 000765 000024 00000000000 12033302111 020155 5ustar00mbolingbrokestaff000000 000000 temporary-1.1.2.4/LICENSE000644 000765 000024 00000002766 12033302111 016516 0ustar00mbolingbrokestaff000000 000000 Copyright (c) 2008, Maximilian Bolingbroke All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of Maximilian Bolingbroke nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.temporary-1.1.2.4/Setup.lhs000644 000765 000024 00000000113 12033302111 017301 0ustar00mbolingbrokestaff000000 000000 #!/usr/bin/env runhaskell > import Distribution.Simple > main = defaultMaintemporary-1.1.2.4/System/000755 000765 000024 00000000000 12033302111 016762 5ustar00mbolingbrokestaff000000 000000 temporary-1.1.2.4/temporary.cabal000644 000765 000024 00000002656 12033302111 020515 0ustar00mbolingbrokestaff000000 000000 name: temporary version: 1.1.2.4 cabal-version: >= 1.6 synopsis: Portable temporary file and directory support for Windows and Unix, based on code from Cabal description: The functions for creating temporary files and directories in the base library are quite limited. The unixutils package contains some good ones, but they aren't portable to Windows. This library just repackages the Cabal implementations of its own temporary file and folder functions so that you can use them without linking against Cabal or depending on it being installed. category: System, Utils license: BSD3 license-file: LICENSE copyright: (c) 2003-2006, Isaac Jones (c) 2005-2009, Duncan Coutts author: Isaac Jones Duncan Coutts maintainer: Max Bolingbroke homepage: http://www.github.com/batterseapower/temporary build-type: Simple Library exposed-modules: System.IO.Temp other-modules: Distribution.Compat.Exception Distribution.Compat.TempFile build-depends: base >= 3 && < 6, filepath >= 1.1 && < 1.4, directory >= 1.0 && < 1.3 if !os(windows) build-depends: unix >= 2.3 && < 2.7 temporary-1.1.2.4/System/IO/000755 000765 000024 00000000000 12033302111 017271 5ustar00mbolingbrokestaff000000 000000 temporary-1.1.2.4/System/IO/Temp.hs000644 000765 000024 00000006373 12033302111 020543 0ustar00mbolingbrokestaff000000 000000 module System.IO.Temp ( withSystemTempFile, withSystemTempDirectory, withTempFile, withTempDirectory, module Distribution.Compat.TempFile ) where -- NB: this module was extracted directly from "Distribution/Simple/Utils.hs" -- in a Cabal tree whose most recent commit was on Sun Oct 10 22:00:26 -- -- The files in the Distribution/Compat tree are exact copies of the corresponding -- file in the Cabal checkout. import qualified Control.Exception as Exception import System.Directory import System.IO import Distribution.Compat.TempFile -- | Create and use a temporary directory in the system standard temporary directory. -- -- Behaves exactly the same as 'withTempDirectory', except that the parent temporary directory -- will be that returned by 'getTemporaryDirectory'. withSystemTempFile :: String -- ^ File name template. See 'openTempFile'. -> (FilePath -> Handle -> IO a) -- ^ Callback that can use the file -> IO a withSystemTempFile template action = getTemporaryDirectory >>= \tmpDir -> withTempFile tmpDir template action -- | Create and use a temporary directory in the system standard temporary directory. -- -- Behaves exactly the same as 'withTempDirectory', except that the parent temporary directory -- will be that returned by 'getTemporaryDirectory'. withSystemTempDirectory :: String -- ^ Directory name template. See 'openTempFile'. -> (FilePath -> IO a) -- ^ Callback that can use the directory -> IO a withSystemTempDirectory template action = getTemporaryDirectory >>= \tmpDir -> withTempDirectory tmpDir template action -- | Use a temporary filename that doesn't already exist. -- -- Creates a new temporary file inside the given directory, making use of the -- template. The temp file is deleted after use. For example: -- -- > withTempFile "src" "sdist." $ \tmpFile hFile -> do ... -- -- The @tmpFlie@ will be file in the given directory, e.g. -- @src/sdist.342@. withTempFile :: FilePath -- ^ Temp dir to create the file in -> String -- ^ File name template. See 'openTempFile'. -> (FilePath -> Handle -> IO a) -- ^ Callback that can use the file -> IO a withTempFile tmpDir template action = Exception.bracket (openTempFile tmpDir template) (\(name, handle) -> hClose handle >> ignoringIOErrors (removeFile name)) (uncurry action) -- | Create and use a temporary directory. -- -- Creates a new temporary directory inside the given directory, making use -- of the template. The temp directory is deleted after use. For example: -- -- > withTempDirectory "src" "sdist." $ \tmpDir -> do ... -- -- The @tmpDir@ will be a new subdirectory of the given directory, e.g. -- @src/sdist.342@. withTempDirectory :: FilePath -- ^ Temp directory to create the directory in -> String -- ^ Directory name template. See 'openTempFile'. -> (FilePath -> IO a) -- ^ Callback that can use the directory -> IO a withTempDirectory targetDir template = Exception.bracket (createTempDirectory targetDir template) (ignoringIOErrors . removeDirectoryRecursive) ignoringIOErrors :: IO () -> IO () ignoringIOErrors ioe = ioe `Exception.catch` (\e -> const (return ()) (e :: IOError)) temporary-1.1.2.4/Distribution/Compat/000755 000765 000024 00000000000 12033302111 021400 5ustar00mbolingbrokestaff000000 000000 temporary-1.1.2.4/Distribution/Compat/Exception.hs000644 000765 000024 00000002447 12033302111 023701 0ustar00mbolingbrokestaff000000 000000 {-# OPTIONS -cpp #-} -- OPTIONS required for ghc-6.4.x compat, and must appear first {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -cpp #-} {-# OPTIONS_NHC98 -cpp #-} {-# OPTIONS_JHC -fcpp #-} #if !(defined(__HUGS__) || (defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 610)) #define NEW_EXCEPTION #endif module Distribution.Compat.Exception (onException, catchIO, catchExit, throwIOIO) where import System.Exit import qualified Control.Exception as Exception onException :: IO a -> IO b -> IO a #ifdef NEW_EXCEPTION onException = Exception.onException #else onException io what = io `Exception.catch` \e -> do what Exception.throw e #endif throwIOIO :: Exception.IOException -> IO a #ifdef NEW_EXCEPTION throwIOIO = Exception.throwIO #else throwIOIO = Exception.throwIO . Exception.IOException #endif catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a #ifdef NEW_EXCEPTION catchIO = Exception.catch #else catchIO = Exception.catchJust Exception.ioErrors #endif catchExit :: IO a -> (ExitCode -> IO a) -> IO a #ifdef NEW_EXCEPTION catchExit = Exception.catch #else catchExit = Exception.catchJust exitExceptions where exitExceptions (Exception.ExitException ee) = Just ee exitExceptions _ = Nothing #endif temporary-1.1.2.4/Distribution/Compat/TempFile.hs000644 000765 000024 00000016025 12033302111 023445 0ustar00mbolingbrokestaff000000 000000 {-# OPTIONS -cpp #-} -- OPTIONS required for ghc-6.4.x compat, and must appear first {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -cpp #-} {-# OPTIONS_NHC98 -cpp #-} {-# OPTIONS_JHC -fcpp #-} -- #hide module Distribution.Compat.TempFile ( openTempFile, openBinaryTempFile, openNewBinaryFile, createTempDirectory, ) where import System.FilePath (()) import Foreign.C (eEXIST) #if __NHC__ || __HUGS__ import System.IO (openFile, openBinaryFile, Handle, IOMode(ReadWriteMode)) import System.Directory (doesFileExist) import System.FilePath ((<.>), splitExtension) import System.IO.Error (try, isAlreadyExistsError) #else import System.IO (Handle, openTempFile, openBinaryTempFile) import Data.Bits ((.|.)) import System.Posix.Internals (c_open, c_close, o_CREAT, o_EXCL, o_RDWR, o_BINARY, o_NONBLOCK, o_NOCTTY) import System.IO.Error (isAlreadyExistsError) #if __GLASGOW_HASKELL__ >= 706 import Control.Exception (try) #else import System.IO.Error (try) #endif #if __GLASGOW_HASKELL__ >= 611 import System.Posix.Internals (withFilePath) #else import Foreign.C (withCString) #endif import Foreign.C (CInt) #if __GLASGOW_HASKELL__ >= 611 import GHC.IO.Handle.FD (fdToHandle) #else import GHC.Handle (fdToHandle) #endif import Distribution.Compat.Exception (onException) #endif import Foreign.C (getErrno, errnoToIOError) #if __NHC__ import System.Posix.Types (CPid(..)) foreign import ccall unsafe "getpid" c_getpid :: IO CPid #else import System.Posix.Internals (c_getpid) #endif #ifdef mingw32_HOST_OS import System.Directory ( createDirectory ) #else import qualified System.Posix #endif -- ------------------------------------------------------------ -- * temporary files -- ------------------------------------------------------------ -- This is here for Haskell implementations that do not come with -- System.IO.openTempFile. This includes nhc-1.20, hugs-2006.9. -- TODO: Not sure about jhc #if __NHC__ || __HUGS__ -- use a temporary filename that doesn't already exist. -- NB. *not* secure (we don't atomically lock the tmp file we get) openTempFile :: FilePath -> String -> IO (FilePath, Handle) openTempFile tmp_dir template = do x <- getProcessID findTempName x where (templateBase, templateExt) = splitExtension template findTempName :: Int -> IO (FilePath, Handle) findTempName x = do let path = tmp_dir (templateBase ++ "-" ++ show x) <.> templateExt b <- doesFileExist path if b then findTempName (x+1) else do hnd <- openFile path ReadWriteMode return (path, hnd) openBinaryTempFile :: FilePath -> String -> IO (FilePath, Handle) openBinaryTempFile tmp_dir template = do x <- getProcessID findTempName x where (templateBase, templateExt) = splitExtension template findTempName :: Int -> IO (FilePath, Handle) findTempName x = do let path = tmp_dir (templateBase ++ show x) <.> templateExt b <- doesFileExist path if b then findTempName (x+1) else do hnd <- openBinaryFile path ReadWriteMode return (path, hnd) openNewBinaryFile :: FilePath -> String -> IO (FilePath, Handle) openNewBinaryFile = openBinaryTempFile getProcessID :: IO Int getProcessID = fmap fromIntegral c_getpid #else -- This is a copy/paste of the openBinaryTempFile definition, but -- if uses 666 rather than 600 for the permissions. The base library -- needs to be changed to make this better. openNewBinaryFile :: FilePath -> String -> IO (FilePath, Handle) openNewBinaryFile dir template = do pid <- c_getpid findTempName pid where -- We split off the last extension, so we can use .foo.ext files -- for temporary files (hidden on Unix OSes). Unfortunately we're -- below filepath in the hierarchy here. (prefix,suffix) = case break (== '.') $ reverse template of -- First case: template contains no '.'s. Just re-reverse it. (rev_suffix, "") -> (reverse rev_suffix, "") -- Second case: template contains at least one '.'. Strip the -- dot from the prefix and prepend it to the suffix (if we don't -- do this, the unique number will get added after the '.' and -- thus be part of the extension, which is wrong.) (rev_suffix, '.':rest) -> (reverse rest, '.':reverse rev_suffix) -- Otherwise, something is wrong, because (break (== '.')) should -- always return a pair with either the empty string or a string -- beginning with '.' as the second component. _ -> error "bug in System.IO.openTempFile" oflags = rw_flags .|. o_EXCL .|. o_BINARY #if __GLASGOW_HASKELL__ < 611 withFilePath = withCString #endif findTempName x = do fd <- withFilePath filepath $ \ f -> c_open f oflags 0o666 if fd < 0 then do errno <- getErrno if errno == eEXIST then findTempName (x+1) else ioError (errnoToIOError "openNewBinaryFile" errno Nothing (Just dir)) else do -- TODO: We want to tell fdToHandle what the filepath is, -- as any exceptions etc will only be able to report the -- fd currently h <- #if __GLASGOW_HASKELL__ >= 609 fdToHandle fd #elif __GLASGOW_HASKELL__ <= 606 && defined(mingw32_HOST_OS) -- fdToHandle is borked on Windows with ghc-6.6.x openFd (fromIntegral fd) Nothing False filepath ReadWriteMode True #else fdToHandle (fromIntegral fd) #endif `onException` c_close fd return (filepath, h) where filename = prefix ++ show x ++ suffix filepath = dir `combine` filename -- FIXME: bits copied from System.FilePath combine a b | null b = a | null a = b | last a == pathSeparator = a ++ b | otherwise = a ++ [pathSeparator] ++ b -- FIXME: Should use filepath library pathSeparator :: Char #ifdef mingw32_HOST_OS pathSeparator = '\\' #else pathSeparator = '/' #endif -- FIXME: Copied from GHC.Handle std_flags, output_flags, rw_flags :: CInt std_flags = o_NONBLOCK .|. o_NOCTTY output_flags = std_flags .|. o_CREAT rw_flags = output_flags .|. o_RDWR #endif createTempDirectory :: FilePath -> String -> IO FilePath createTempDirectory dir template = do pid <- c_getpid findTempName pid where findTempName x = do let dirpath = dir template ++ show x r <- try $ mkPrivateDir dirpath case r of Right _ -> return dirpath Left e | isAlreadyExistsError e -> findTempName (x+1) | otherwise -> ioError e mkPrivateDir :: String -> IO () #ifdef mingw32_HOST_OS mkPrivateDir s = createDirectory s #else mkPrivateDir s = System.Posix.createDirectory s 0o700 #endif