fix bugs and added mkdtemp
authorDeian Stefan <deian@cs.stanford.edu>
Mon, 2 Jan 2012 05:46:26 +0000 (21:46 -0800)
committerDavid Terei <davidterei@gmail.com>
Fri, 6 Jan 2012 02:20:02 +0000 (18:20 -0800)
System/Posix/Temp.hsc
System/Posix/Temp/ByteString.hsc

index a55d5fe..5308c1b 100644 (file)
@@ -19,6 +19,7 @@
 module System.Posix.Temp (
 
     mkstemp
+  , mkdtemp
 
 {- Not ported (yet?):
     tmpfile: can we handle FILE*?
@@ -33,6 +34,7 @@ module System.Posix.Temp (
 import System.IO
 import System.Posix.IO
 import System.Posix.Types
+import System.Posix.Directory (createDirectory)
 import Foreign.C
 
 #if __GLASGOW_HASKELL__ > 700
@@ -55,7 +57,8 @@ peekFilePath = peekCString
 -- The returned 'FilePath' is the (possibly relative) path of
 -- the created file, which is padded with 6 random characters.
 mkstemp :: String -> IO (FilePath, Handle)
-mkstemp template = do
+mkstemp template' = do
+  let template = template' ++ "XXXXXX"
 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
   withFilePath template $ \ ptr -> do
     fd <- throwErrnoIfMinus1 "mkstemp" (c_mkstemp ptr)
@@ -63,13 +66,32 @@ mkstemp template = do
     h <- fdToHandle (Fd fd)
     return (name, h)
 #else
-  name <- mktemp (template ++ "XXXXXX")
+  name <- mktemp template
   h <- openFile name ReadWriteMode
   return (name, h)
+#endif
+
+-- |'mkdtemp' - make a unique directory (only safe on GHC & Hugs).
+-- The returned 'FilePath' is the path of the created directory,
+-- which is padded with 6 random characters.
+mkdtemp :: String -> IO FilePath
+mkdtemp template' = do
+  let template = template' ++ "XXXXXX"
+#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
+  withFilePath template $ \ ptr -> do
+    throwErrnoIfNull "mkdtemp" (c_mkdtemp ptr)
+    name <- peekFilePath ptr
+    return name
+#else
+  name <- mktemp template
+  h <- createDirectory name (toEnum 0o700)
+  return name
+#endif
 
+#if !defined(__GLASGOW_HASKELL__) && !defined(__HUGS__)
 -- |'mktemp' - make a unique file name
+-- It is required that the template have six trailing \'X\'s.
 -- This function should be considered deprecated
-
 mktemp :: String -> IO String
 mktemp template = do
   withFilePath template $ \ ptr -> do
@@ -83,3 +105,5 @@ foreign import ccall unsafe "mktemp"
 foreign import ccall unsafe "HsUnix.h __hscore_mkstemp"
   c_mkstemp :: CString -> IO CInt
 
+foreign import ccall unsafe "HsUnix.h __hscore_mkdtemp"
+  c_mkdtemp :: CString -> IO CString
index c5f8906..b07b68f 100644 (file)
@@ -19,6 +19,7 @@
 module System.Posix.Temp.ByteString (
 
     mkstemp
+  , mkdtemp
 
 {- Not ported (yet?):
     tmpfile: can we handle FILE*?
@@ -30,9 +31,13 @@ module System.Posix.Temp.ByteString (
 
 #include "HsUnix.h"
 
-import System.IO        (Handle)
+import System.IO        (
+     Handle,
+     openFile,
+     IOMode(..) )
 import System.Posix.IO
 import System.Posix.Types
+import System.Posix.Directory (createDirectory)
 
 import Foreign.C hiding (
      throwErrnoPath,
@@ -45,6 +50,8 @@ import Foreign.C hiding (
 import System.Posix.ByteString.FilePath
 
 import Data.ByteString (ByteString)
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Char8 as BC
 
 
 -- |'mkstemp' - make a unique filename and open it for
@@ -52,7 +59,8 @@ import Data.ByteString (ByteString)
 -- The returned 'RawFilePath' is the (possibly relative) path of
 -- the created file, which is padded with 6 random characters.
 mkstemp :: ByteString -> IO (RawFilePath, Handle)
-mkstemp template = do
+mkstemp template' = do
+  let template = template' `B.append` (BC.pack "XXXXXX")
 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
   withFilePath template $ \ ptr -> do
     fd <- throwErrnoIfMinus1 "mkstemp" (c_mkstemp ptr)
@@ -60,13 +68,32 @@ mkstemp template = do
     h <- fdToHandle (Fd fd)
     return (name, h)
 #else
-  name <- mktemp (template ++ "XXXXXX")
-  h <- openFile name ReadWriteMode
+  name <- mktemp template
+  h <- openFile (BC.unpack name) ReadWriteMode
   return (name, h)
+#endif
+
+-- |'mkdtemp' - make a unique directory (only safe on GHC & Hugs).
+-- The returned 'FilePath' is the path of the created directory,
+-- which is padded with 6 random characters.
+mkdtemp :: ByteString -> IO RawFilePath
+mkdtemp template' = do
+  let template = template' `B.append` (BC.pack "XXXXXX")
+#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
+  withFilePath template $ \ ptr -> do
+    throwErrnoIfNull "mkdtemp" (c_mkdtemp ptr)
+    name <- peekFilePath ptr
+    return name
+#else
+  name <- mktemp template
+  h <- createDirectory (BC.unpack name) (toEnum 0o700)
+  return name
+#endif
 
+#if !defined(__GLASGOW_HASKELL__) && !defined(__HUGS__)
 -- |'mktemp' - make a unique file name
+-- It is required that the template have six trailing \'X\'s.
 -- This function should be considered deprecated
-
 mktemp :: ByteString -> IO RawFilePath
 mktemp template = do
   withFilePath template $ \ ptr -> do
@@ -80,3 +107,5 @@ foreign import ccall unsafe "mktemp"
 foreign import ccall unsafe "HsUnix.h __hscore_mkstemp"
   c_mkstemp :: CString -> IO CInt
 
+foreign import ccall unsafe "HsUnix.h __hscore_mkdtemp"
+  c_mkdtemp :: CString -> IO CString