From 15226db1053b0d24d9e76064d386df57b7442519 Mon Sep 17 00:00:00 2001
From: Deian Stefan <deian@cs.stanford.edu>
Date: Thu, 5 Jan 2012 19:38:13 -0800
Subject: [PATCH] mkstemps

---
 System/Posix/Temp.hsc            | 23 ++++++++++++++++++++++-
 System/Posix/Temp/ByteString.hsc | 23 ++++++++++++++++++++++-
 cbits/HsUnix.c                   |  3 +++
 include/HsUnix.h                 |  1 +
 4 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/System/Posix/Temp.hsc b/System/Posix/Temp.hsc
index 9989ca0..8ab789c 100644
--- a/System/Posix/Temp.hsc
+++ b/System/Posix/Temp.hsc
@@ -17,7 +17,7 @@
 -----------------------------------------------------------------------------
 
 module System.Posix.Temp (
-        mkstemp, mkdtemp
+        mkstemp, mkstemps, mkdtemp
     ) where
 
 #include "HsUnix.h"
@@ -69,6 +69,27 @@ mkstemp template' = do
   return (name, h)
 #endif
 
+#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
+-- |'mkstemps' - make a unique filename with a given prefix and suffix 
+-- and open it for reading\/writing (only safe on GHC & Hugs).
+-- The returned 'FilePath' is the (possibly relative) path of
+-- the created file, which contains  6 random characters in between
+-- the prefix and suffix.
+mkstemps :: String -> String -> IO (FilePath, Handle)
+mkstemps prefix suffix = do
+  let template = prefix ++ "XXXXXX" ++ suffix
+      lenOfsuf :: CInt
+      lenOfsuf = fromIntegral $ length suffix
+  withFilePath template $ \ ptr -> do
+    fd <- throwErrnoIfMinus1 "mkstemps" (c_mkstemps ptr lenOfsuf)
+    name <- peekFilePath ptr
+    h <- fdToHandle (Fd fd)
+    return (name, h)
+
+foreign import ccall unsafe "HsUnix.h __hscore_mkstemps"
+  c_mkstemps :: CString -> CInt -> IO CInt
+#endif
+
 -- | Make a unique directory. The returned 'FilePath' is the path of the
 -- created directory, which is padded with 6 random characters. The argument is
 -- the desired prefix of the filepath of the temporary directory to be created.
diff --git a/System/Posix/Temp/ByteString.hsc b/System/Posix/Temp/ByteString.hsc
index a13e45a..02aca28 100644
--- a/System/Posix/Temp/ByteString.hsc
+++ b/System/Posix/Temp/ByteString.hsc
@@ -17,7 +17,7 @@
 -----------------------------------------------------------------------------
 
 module System.Posix.Temp.ByteString (
-        mkstemp, mkdtemp
+        mkstemp, mkstemps, mkdtemp
     ) where
 
 #include "HsUnix.h"
@@ -60,6 +60,27 @@ mkstemp template' = do
   return (name, h)
 #endif
 
+#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
+-- |'mkstemps' - make a unique filename with a given prefix and suffix 
+-- and open it for reading\/writing (only safe on GHC & Hugs).
+-- The returned 'RawFilePath' is the (possibly relative) path of
+-- the created file, which contains  6 random characters in between
+-- the prefix and suffix.
+mkstemps :: ByteString -> ByteString -> IO (RawFilePath, Handle)
+mkstemps prefix suffix = do
+  let template = prefix `B.append` (BC.pack "XXXXXX") `B.append` suffix
+      lenOfsuf :: CInt
+      lenOfsuf = fromIntegral $ B.length suffix
+  withFilePath template $ \ ptr -> do
+    fd <- throwErrnoIfMinus1 "mkstemps" (c_mkstemps ptr lenOfsuf)
+    name <- peekFilePath ptr
+    h <- fdToHandle (Fd fd)
+    return (name, h)
+
+foreign import ccall unsafe "HsUnix.h __hscore_mkstemps"
+  c_mkstemps :: CString -> CInt -> IO CInt
+#endif
+
 -- | Make a unique directory. The returned 'RawFilePath' is the path of the
 -- created directory, which is padded with 6 random characters. The argument is
 -- the desired prefix of the filepath of the temporary directory to be created.
diff --git a/cbits/HsUnix.c b/cbits/HsUnix.c
index d6366fc..bb3a3c7 100644
--- a/cbits/HsUnix.c
+++ b/cbits/HsUnix.c
@@ -135,6 +135,9 @@ int __hscore_mkstemp(char *filetemplate) {
 char *__hscore_mkdtemp(char *filetemplate) {
     return (mkdtemp(filetemplate));
 }
+int __hscore_mkstemps(char *filetemplate, int suffixlen) {
+    return (mkstemps(filetemplate, suffixlen));
+}
 #endif
 
 #if !defined(__MINGW32__) && !defined(irix_HOST_OS)
diff --git a/include/HsUnix.h b/include/HsUnix.h
index eecbfe8..7cee73a 100644
--- a/include/HsUnix.h
+++ b/include/HsUnix.h
@@ -175,6 +175,7 @@ int __hsunix_push_module(int fd, const char *module);
 
 #if !defined(__MINGW32__)
 int __hscore_mkstemp(char *filetemplate);
+int __hscore_mkstemps(char *filetemplate, int suffixlen);
 char *__hscore_mkdtemp(char *filetemplate);
 #endif
 
-- 
GitLab