summaryrefslogtreecommitdiff
path: root/Utility
diff options
context:
space:
mode:
Diffstat (limited to 'Utility')
-rw-r--r--Utility/FileSystemEncoding.hs28
-rw-r--r--Utility/StatFS.hsc2
2 files changed, 17 insertions, 13 deletions
diff --git a/Utility/FileSystemEncoding.hs b/Utility/FileSystemEncoding.hs
index 048323ee3..fe4202a75 100644
--- a/Utility/FileSystemEncoding.hs
+++ b/Utility/FileSystemEncoding.hs
@@ -7,31 +7,37 @@
module Utility.FileSystemEncoding where
-import System.IO
+import qualified GHC.Foreign as GHC
+import qualified GHC.IO.Encoding as Encoding
import Foreign.C
-import GHC.Foreign as GHC
-import GHC.IO.Encoding
+import System.IO
+import System.IO.Unsafe
{- Sets a Handle to use the filesystem encoding. This causes data
- written or read from it to be encoded/decoded the same
- as ghc 7.4 does to filenames etc. This special encoding
- allows "arbitrary undecodable bytes to be round-tripped through it". -}
fileEncoding :: Handle -> IO ()
-fileEncoding h = hSetEncoding h =<< getFileSystemEncoding
+fileEncoding h = hSetEncoding h =<< Encoding.getFileSystemEncoding
{- Marshal a Haskell FilePath into a NUL terminated C string using temporary
- storage. The FilePath is encoded using the filesystem encoding,
- reversing the decoding that should have been done when the FilePath
- was obtained. -}
withFilePath :: FilePath -> (CString -> IO a) -> IO a
-withFilePath fp f = getFileSystemEncoding >>= \enc -> GHC.withCString enc fp f
+withFilePath fp f = Encoding.getFileSystemEncoding
+ >>= \enc -> GHC.withCString enc fp f
{- Encodes a FilePath into a String of encoded bytes, applying the
- filesystem encoding.
-
- - This does not do any IO, beyond allocating a C buffer. GHC does not
- - seem to provide a pure way to do this conversion. -}
-encodeFilePath :: FilePath -> IO String
-encodeFilePath fp = do
- enc <- getFileSystemEncoding
- GHC.withCString enc fp $ GHC.peekCString enc
+ - This use of unsafePerformIO is belived to be safe; GHC's interface
+ - only allows doing this conversion with CStrings, and the CString buffer
+ - is allocated, used, and deallocated within the call, with no side
+ - effects.
+ -}
+{-# NOINLINE encodeFilePath #-}
+encodeFilePath :: FilePath -> String
+encodeFilePath fp = unsafePerformIO $ do
+ enc <- Encoding.getFileSystemEncoding
+ GHC.withCString enc fp $ GHC.peekCString Encoding.char8
diff --git a/Utility/StatFS.hsc b/Utility/StatFS.hsc
index 58d0b3e02..ed4c9f1cb 100644
--- a/Utility/StatFS.hsc
+++ b/Utility/StatFS.hsc
@@ -52,8 +52,6 @@ import Utility.FileSystemEncoding
import Foreign
import Foreign.C.Types
import Foreign.C.String
-import GHC.IO.Encoding (getFileSystemEncoding)
-import GHC.Foreign as GHC
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
# include <sys/param.h>