diff options
Diffstat (limited to 'Utility')
-rw-r--r-- | Utility/FileSystemEncoding.hs | 28 | ||||
-rw-r--r-- | Utility/StatFS.hsc | 2 |
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> |