Always use filesystem encoding for all file and handle reads and writes.
authorJoey Hess <joeyh@joeyh.name>
Sat, 24 Dec 2016 18:46:31 +0000 (14:46 -0400)
committerJoey Hess <joeyh@joeyh.name>
Sat, 24 Dec 2016 18:46:31 +0000 (14:46 -0400)
This is a big scary change. I have convinced myself it should be safe. I
hope!

48 files changed:
Annex/Branch.hs
Annex/CatFile.hs
Annex/Content/Direct.hs
Annex/DirHashes.hs
Annex/Journal.hs
Annex/Link.hs
Annex/Ssh.hs
Annex/VariantFile.hs
Assistant/TransferrerPool.hs
Assistant/WebApp/Control.hs
Backend/Utilities.hs
Build/DistributionUpdate.hs
Build/EvilSplicer.hs
CHANGELOG
CmdLine/Batch.hs
Command/AddUrl.hs
Command/ImportFeed.hs
Command/P2P.hs
Command/TransferKeys.hs
Command/Vicfg.hs
Common.hs
Config.hs
Database/Handle.hs
Git/CatFile.hs
Git/Command.hs
Git/Config.hs
Git/HashObject.hs
Git/Queue.hs
Git/Repair.hs
Git/UnionMerge.hs
Git/UpdateIndex.hs
Logs/Transfer.hs
Logs/Unused.hs
Messages.hs
P2P/IO.hs
Remote/BitTorrent.hs
Remote/External.hs
Test.hs
Utility/CoProcess.hs
Utility/ExternalSHA.hs
Utility/FileSystemEncoding.hs
Utility/Lsof.hs
Utility/MagicWormhole.hs
Utility/Misc.hs
Utility/Quvi.hs
Utility/Shell.hs
git-annex.hs
git-union-merge.hs

index 9663311d51936ac1ba81749b9bc416cc5311e35b..c90958ab0502dd9296075d36ad0f35146cd826bd 100644 (file)
@@ -61,6 +61,7 @@ import qualified Annex.Queue
 import Annex.Branch.Transitions
 import qualified Annex
 import Annex.Hook
+import Utility.FileSystemEncoding
 
 {- Name of the branch that is used to store git-annex's information. -}
 name :: Git.Ref
@@ -436,7 +437,6 @@ stageJournal jl = withIndex $ do
        g <- gitRepo
        let dir = gitAnnexJournalDir g
        (jlogf, jlogh) <- openjlog
-       liftIO $ fileEncoding jlogh
        h <- hashObjectHandle
        withJournalHandle $ \jh ->
                Git.UpdateIndex.streamUpdateIndex g
index b1d8fba287f6d8f658fbcb5b107d9efec4f6a3e8..25952dfecdf6efcc1019c0d1f3e55bc4b03a433d 100644 (file)
@@ -33,6 +33,7 @@ import Git.FilePath
 import Git.Index
 import qualified Git.Ref
 import Annex.Link
+import Utility.FileSystemEncoding
 
 catFile :: Git.Branch -> FilePath -> Annex L.ByteString
 catFile branch file = do
index 2007360e31f57eb7c599094909fcbead6fa91c0c..734a0c1b94c904edd953d5d163f28b3865fb6418 100644 (file)
@@ -52,8 +52,7 @@ associatedFiles key = do
 associatedFilesRelative :: Key -> Annex [FilePath] 
 associatedFilesRelative key = do
        mapping <- calcRepo $ gitAnnexMapping key
-       liftIO $ catchDefaultIO [] $ withFile mapping ReadMode $ \h -> do
-               fileEncoding h
+       liftIO $ catchDefaultIO [] $ withFile mapping ReadMode $ \h ->
                -- Read strictly to ensure the file is closed
                -- before changeAssociatedFiles tries to write to it.
                -- (Especially needed on Windows.)
@@ -68,8 +67,7 @@ changeAssociatedFiles key transform = do
        let files' = transform files
        when (files /= files') $
                modifyContent mapping $
-                       liftIO $ viaTmp writeFileAnyEncoding mapping $
-                               unlines files'
+                       liftIO $ viaTmp writeFile mapping $ unlines files'
        top <- fromRepo Git.repoPath
        return $ map (top </>) files'
 
index 004536ca7919a6983dc54df8354399704369e426..ed20cfb8a71f1050e77aaeaa81ef02a667a17f63 100644 (file)
@@ -26,6 +26,7 @@ import Common
 import Types.Key
 import Types.GitConfig
 import Types.Difference
+import Utility.FileSystemEncoding
 
 type Hasher = Key -> FilePath
 
index e4faa486535b8dcd71f28a5065570da754205937..184bb0ab04c6da0c279dcae472854979256e5e0b 100644 (file)
@@ -37,7 +37,6 @@ setJournalFile _jl file content = do
        let tmpfile = tmp </> takeFileName jfile
        liftIO $ do
                withFile tmpfile WriteMode $ \h -> do
-                       fileEncoding h
 #ifdef mingw32_HOST_OS
                        hSetNewlineMode h noNewlineTranslation
 #endif
@@ -53,7 +52,7 @@ getJournalFile _jl = getJournalFileStale
  - changes. -}
 getJournalFileStale :: FilePath -> Annex (Maybe String)
 getJournalFileStale file = inRepo $ \g -> catchMaybeIO $
-       readFileStrictAnyEncoding $ journalFile file g
+       readFileStrict $ journalFile file g
 
 {- List of files that have updated content in the journal. -}
 getJournalledFiles :: JournalLocked -> Annex [FilePath]
index 90312a04a09d007fea29c0c199d06b655cac8f6c..fcc300beec5d91f0709aac7587ace135d3c7aaae 100644 (file)
@@ -24,6 +24,7 @@ import Git.Types
 import Git.FilePath
 import Annex.HashObject
 import Utility.FileMode
+import Utility.FileSystemEncoding
 
 import qualified Data.ByteString.Lazy as L
 
@@ -63,7 +64,6 @@ getAnnexLinkTarget' file coresymlinks = if coresymlinks
                        Nothing -> fallback
 
        probefilecontent f = withFile f ReadMode $ \h -> do
-               fileEncoding h
                -- The first 8k is more than enough to read; link
                -- files are small.
                s <- take 8192 <$> hGetContents h
index 4f879436b5821248218dbb3e2b2418036a4df5e8..512f0375c2de7ec71b4bf66d4dbec1878bdbfa0d 100644 (file)
@@ -33,6 +33,7 @@ import qualified Git.Url
 import Config
 import Annex.Path
 import Utility.Env
+import Utility.FileSystemEncoding
 import Types.CleanupActions
 import Git.Env
 #ifndef mingw32_HOST_OS
index 9bf027b5ce738e6c1190772bebdfbe464c0a13e2..17658a9c61419ef5103c7c929909659ea36f7e0b 100644 (file)
@@ -8,6 +8,7 @@
 module Annex.VariantFile where
 
 import Annex.Common
+import Utility.FileSystemEncoding
 
 import Data.Hash.MD5
 
index 7c0cb441518b3ea68814e1fb3aad830a3b31581b..892e156e8b88d11e78cbc0c5e540856f671ed8ab 100644 (file)
@@ -74,8 +74,6 @@ mkTransferrer program batchmaker = do
                , std_in = CreatePipe
                , std_out = CreatePipe
                }
-       fileEncoding readh
-       fileEncoding writeh
        return $ Transferrer
                { transferrerRead = readh
                , transferrerWrite = writeh
index 93b923fed936d8fa1082411a176580da3f7dbc3f..8a0e82119dc6487a54ec36aba476209c9eb8eaab 100644 (file)
@@ -74,5 +74,5 @@ getLogR :: Handler Html
 getLogR = page "Logs" Nothing $ do
        logfile <- liftAnnex $ fromRepo gitAnnexLogFile
        logs <- liftIO $ listLogs logfile
-       logcontent <- liftIO $ concat <$> mapM readFileStrictAnyEncoding logs
+       logcontent <- liftIO $ concat <$> mapM readFile logs
        $(widgetFile "control/log")
index 04221650b4993b21253069b4a60335419b1aee7f..d1fb94f2af06181b2469756c51c14b97b6dd127d 100644 (file)
@@ -10,6 +10,7 @@ module Backend.Utilities where
 import Data.Hash.MD5
 
 import Annex.Common
+import Utility.FileSystemEncoding
 
 {- Generates a keyName from an input string. Takes care of sanitizing it.
  - If it's not too long, the full string is used as the keyName.
index 814927e99549906c143b17587c4a783ca6fb55a8..dd18a788376968349ec5da37e1d603c107f693c8 100644 (file)
@@ -14,6 +14,7 @@ import Build.Version (getChangelogVersion, Version)
 import Utility.UserInfo
 import Utility.Url
 import Utility.Tmp
+import Utility.FileSystemEncoding
 import qualified Git.Construct
 import qualified Annex
 import Annex.Content
@@ -50,6 +51,7 @@ autobuilds =
 
 main :: IO ()
 main = do
+       useFileSystemEncoding
        version <- liftIO getChangelogVersion
        repodir <- getRepoDir
        changeWorkingDirectory repodir
index ca690c2501adf2ecd4a17f3fd88faea59a09a137..32d9a1c9fbcdab2a7be3aa18053cab6d87f2c0b9 100644 (file)
@@ -210,7 +210,6 @@ applySplices destdir imports splices@(first:_) = do
        when (oldcontent /= Just newcontent) $ do
                putStrLn $ "splicing " ++ f
                withFile dest WriteMode $ \h -> do
-                       fileEncoding h
                        hPutStr h newcontent
                        hClose h
   where
@@ -721,7 +720,9 @@ parsecAndReplace p s = case parse find "" s of
        find = many $ try (Right <$> p) <|> (Left <$> anyChar)
 
 main :: IO ()
-main = go =<< getArgs
+main = do
+       useFileSystemEncoding
+       go =<< getArgs
   where
        go (destdir:log:header:[]) = run destdir log (Just header)
        go (destdir:log:[]) = run destdir log Nothing
index 2d7ea22a70620fdd81994b4bcf4bc4281196aea1..7a0ca2eb20ca4becc6fa93b395e65067ace9f366 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,8 @@ git-annex (6.20161211) UNRELEASED; urgency=medium
   * enable-tor: No longer needs to be run as root.
   * enable-tor: When run as a regular user, test a connection back to 
     the hidden service over tor.
+  * Always use filesystem encoding for all file and handle reads and
+    writes.
   * Fix build with directory-1.3.
   * Debian: Suggest tor and magic-wormhole.
   * Debian: Build webapp on armel.
index 6ef21372f53c262382118aef942246c895e21ae6..82038314c087c64f6880bf7c0e6b789bb6fef394 100644 (file)
@@ -57,9 +57,7 @@ batchInput parser a = go =<< batchLines
        parseerr s = giveup $ "Batch input parse failure: " ++ s
 
 batchLines :: Annex [String]
-batchLines = liftIO $ do
-       fileEncoding stdin
-       lines <$> getContents
+batchLines = liftIO $ lines <$> getContents
 
 -- Runs a CommandStart in batch mode.
 --
index e49d2727c7616b8f2eab529d147c8838cf58eef3..8cc14844066bef00f9794b0410d08631d132ff2f 100644 (file)
@@ -27,6 +27,7 @@ import Types.UrlContents
 import Annex.FileMatcher
 import Logs.Location
 import Utility.Metered
+import Utility.FileSystemEncoding
 import qualified Annex.Transfer as Transfer
 import Annex.Quvi
 import qualified Utility.Quvi as Quvi
index 832ec1246f1e2ff942a526db765f381226dda66b..ea936e84a52a96ac1a0e8cbfa1c212ef22e3dd67 100644 (file)
@@ -156,7 +156,7 @@ downloadFeed url
                liftIO $ withTmpFile "feed" $ \f h -> do
                        hClose h
                        ifM (Url.download url f uo)
-                               ( parseFeedString <$> readFileStrictAnyEncoding f
+                               ( parseFeedString <$> readFileStrict f
                                , return Nothing
                                )
 
index afa5f9dc6892387b70b3f8fab287178a8e938c33..4ba3e43d537794a4d0068ffe9d3bf341c6d60caa 100644 (file)
@@ -161,7 +161,6 @@ performPairing remotename addrs = do
        getcode ourcode = do
                putStr "Enter the other repository's pairing code: "
                hFlush stdout
-               fileEncoding stdin
                l <- getLine
                case Wormhole.toCode l of
                        Just code
@@ -236,7 +235,7 @@ wormholePairing remotename ouraddrs ui = do
                                then return ReceiveFailed
                                else do
                                        r <- liftIO $ tryIO $
-                                               readFileStrictAnyEncoding recvf
+                                               readFileStrict recvf
                                        case r of
                                                Left _e -> return ReceiveFailed
                                                Right s -> maybe 
index 2ac784589060249e44ce3a3393aadf80a780c946..d875f496d0df6e19355830479af54999c11c4206 100644 (file)
@@ -56,10 +56,7 @@ runRequests
        -> (TransferRequest -> Annex Bool)
        -> Annex ()
 runRequests readh writeh a = do
-       liftIO $ do
-               hSetBuffering readh NoBuffering
-               fileEncoding readh
-               fileEncoding writeh
+       liftIO $ hSetBuffering readh NoBuffering
        go =<< readrequests
   where
        go (d:rn:k:f:rest) = do
index 64daa598b729fae8c4565d8f751669e01f5d918a..d9e8b88232b94c2658905c8dd07b20683d9603f1 100644 (file)
@@ -41,7 +41,7 @@ start = do
        createAnnexDirectory $ parentDir f
        cfg <- getCfg
        descs <- uuidDescriptions
-       liftIO $ writeFileAnyEncoding f $ genCfg cfg descs
+       liftIO $ writeFile f $ genCfg cfg descs
        vicfg cfg f
        stop
 
@@ -51,11 +51,11 @@ vicfg curcfg f = do
        -- Allow EDITOR to be processed by the shell, so it can contain options.
        unlessM (liftIO $ boolSystem "sh" [Param "-c", Param $ unwords [vi, shellEscape f]]) $
                giveup $ vi ++ " exited nonzero; aborting"
-       r <- parseCfg (defCfg curcfg) <$> liftIO (readFileStrictAnyEncoding f)
+       r <- parseCfg (defCfg curcfg) <$> liftIO (readFileStrict f)
        liftIO $ nukeFile f
        case r of
                Left s -> do
-                       liftIO $ writeFileAnyEncoding f s
+                       liftIO $ writeFile f s
                        vicfg curcfg f
                Right newcfg -> setCfg curcfg newcfg
 
index 5213863b9fd598369103e44cd5a60492e6565e4c..2e28117b6c13bc11a172b5b5a46e6bba4087c0de 100644 (file)
--- a/Common.hs
+++ b/Common.hs
@@ -29,7 +29,6 @@ import Utility.Directory as X
 import Utility.Monad as X
 import Utility.Data as X
 import Utility.Applicative as X
-import Utility.FileSystemEncoding as X
 import Utility.PosixFiles as X hiding (fileSize)
 import Utility.FileSize as X
 import Utility.Network as X
index be60852daa099ec5b958873f82db6984cdd01932..84736cac35fcd700568072d518cbc59fbf7267aa 100644 (file)
--- a/Config.hs
+++ b/Config.hs
@@ -112,7 +112,7 @@ configureSmudgeFilter = do
                createDirectoryIfMissing True (takeDirectory lf)
                writeFile lf (lfs ++ "\n" ++ stdattr)
   where
-       readattr = liftIO . catchDefaultIO "" . readFileStrictAnyEncoding
+       readattr = liftIO . catchDefaultIO "" . readFileStrict
        stdattr = unlines
                [ "* filter=annex"
                , ".* !filter"
index 748feaa9767ea948237922d7e10855e318a018de..9071cd5380446f36995a4c7b9aa08213ff822788 100644 (file)
@@ -69,7 +69,7 @@ openDb db tablename = do
        worker <- async (workerThread (T.pack db) tablename jobs)
        
        -- work around https://github.com/yesodweb/persistent/issues/474
-       liftIO setConsoleEncoding
+       liftIO useFileSystemEncoding
 
        return $ DbHandle worker jobs
 
index 061349f0547df377465ecfc9d5d8548d8455ca19..4935cdffa06c24ff2d0d43535d713f2739d5ac76 100644 (file)
@@ -37,6 +37,7 @@ import Git.Command
 import Git.Types
 import Git.FilePath
 import qualified Utility.CoProcess as CoProcess
+import Utility.FileSystemEncoding
 
 data CatFileHandle = CatFileHandle 
        { catFileProcess :: CoProcess.CoProcessHandle
index 206056368871155e757bc9836bdd8e04ce8aa162..adea7622e026accfb174595292c56584bff69485 100644 (file)
@@ -53,7 +53,6 @@ runQuiet params repo = withQuietOutput createProcessSuccess $
 pipeReadLazy :: [CommandParam] -> Repo -> IO (String, IO Bool)
 pipeReadLazy params repo = assertLocal repo $ do
        (_, Just h, _, pid) <- createProcess p { std_out = CreatePipe }
-       fileEncoding h
        c <- hGetContents h
        return (c, checkSuccessProcess pid)
   where
@@ -66,7 +65,6 @@ pipeReadLazy params repo = assertLocal repo $ do
 pipeReadStrict :: [CommandParam] -> Repo -> IO String
 pipeReadStrict params repo = assertLocal repo $
        withHandle StdoutHandle (createProcessChecked ignoreFailureProcess) p $ \h -> do
-               fileEncoding h
                output <- hGetContentsStrict h
                hClose h
                return output
@@ -81,9 +79,7 @@ pipeWriteRead params writer repo = assertLocal repo $
        writeReadProcessEnv "git" (toCommand $ gitCommandLine params repo) 
                (gitEnv repo) writer (Just adjusthandle)
   where
-       adjusthandle h = do
-               fileEncoding h
-               hSetNewlineMode h noNewlineTranslation
+       adjusthandle h = hSetNewlineMode h noNewlineTranslation
 
 {- Runs a git command, feeding it input on a handle with an action. -}
 pipeWrite :: [CommandParam] -> Repo -> (Handle -> IO ()) -> IO ()
index 3d6239560f43868fa56463e4cfa368ae968ec0b1..65bd9b7ba3cd9649b5a78785bbb08638d1fd3bbb 100644 (file)
@@ -79,10 +79,6 @@ global = do
 {- Reads git config from a handle and populates a repo with it. -}
 hRead :: Repo -> Handle -> IO Repo
 hRead repo h = do
-       -- We use the FileSystemEncoding when reading from git-config,
-       -- because it can contain arbitrary filepaths (and other strings)
-       -- in any encoding.
-       fileEncoding h
        val <- hGetContentsStrict h
        store val repo
 
@@ -167,7 +163,6 @@ coreBare = "core.bare"
 fromPipe :: Repo -> String -> [CommandParam] -> IO (Either SomeException (Repo, String))
 fromPipe r cmd params = try $
        withHandle StdoutHandle createProcessSuccess p $ \h -> do
-               fileEncoding h
                val <- hGetContentsStrict h
                r' <- store val r
                return (r', val)
index 4cd54ef54c3590956946b97e3b288b5c7e29c9c7..399e36d46073206ecdb3d3a4b0aaedadace4afcb 100644 (file)
@@ -41,7 +41,6 @@ hashFile h file = CoProcess.query h send receive
  - interface does not allow batch hashing without using temp files. -}
 hashBlob :: HashObjectHandle -> String -> IO Sha
 hashBlob h s = withTmpFile "hash" $ \tmp tmph -> do
-       fileEncoding tmph
 #ifdef mingw32_HOST_OS
        hSetNewlineMode tmph noNewlineTranslation
 #endif
index 0b0025b0a76be5b5dcbd63d417b315df14cf2829..ee1f83ca9cb9fc91945fa8f2483c84c0d7dfdbf5 100644 (file)
@@ -159,7 +159,6 @@ runAction repo action@(CommandAction {}) = do
 #ifndef mingw32_HOST_OS
        let p = (proc "xargs" $ "-0":"git":toCommand gitparams) { env = gitEnv repo }
        withHandle StdinHandle createProcessSuccess p $ \h -> do
-               fileEncoding h
                hPutStr h $ intercalate "\0" $ toCommand $ getFiles action
                hClose h
 #else
index fcfc03600ce94395a0e7e15ae1cf357ed0c2e3f1..1baf51a644ddd10b46b94d78354667e3b5950b90 100644 (file)
@@ -614,4 +614,4 @@ successfulRepair = fst
 safeReadFile :: FilePath -> IO String
 safeReadFile f = do
        allowRead f
-       readFileStrictAnyEncoding f
+       readFileStrict f
index 9ae8295ae28d0ad39ab5aa1e61afdfc61b19ad21..c6157a9ed0927fdcec5d45fa2b9f2e511453cec3 100644 (file)
@@ -22,6 +22,7 @@ import Git.UpdateIndex
 import Git.HashObject
 import Git.Types
 import Git.FilePath
+import Utility.FileSystemEncoding
 
 {- Performs a union merge between two branches, staging it in the index.
  - Any previously staged changes in the index will be lost.
@@ -94,8 +95,7 @@ mergeFile info file hashhandle h = case filter (/= nullSha) [Ref asha, Ref bsha]
        -- We don't know how the file is encoded, but need to
        -- split it into lines to union merge. Using the
        -- FileSystemEncoding for this is a hack, but ensures there
-       -- are no decoding errors. Note that this works because
-       -- hashObject sets fileEncoding on its write handle.
+       -- are no decoding errors.
        getcontents s = lines . encodeW8NUL . L.unpack <$> catObject h s
 
 {- Calculates a union merge between a list of refs, with contents.
index 55c5b3bb21c63119e978384b2e3dfd9a824f611d..7fdc9450f42542db49ffe980566b311a1cb42b8d 100644 (file)
@@ -55,7 +55,6 @@ startUpdateIndex :: Repo -> IO UpdateIndexHandle
 startUpdateIndex repo = do
        (Just h, _, _, p) <- createProcess (gitCreateProcess params repo)
                { std_in = CreatePipe }
-       fileEncoding h
        return $ UpdateIndexHandle p h
   where
        params = map Param ["update-index", "-z", "--index-info"]
index 65a4e3796d949da73623628fd2d94386fa473e18..28f7b0a2639a1a4b7fe5a1fa9a63b6dad6938909 100644 (file)
@@ -220,8 +220,7 @@ parseTransferFile file
        bits = splitDirectories file
 
 writeTransferInfoFile :: TransferInfo -> FilePath -> IO ()
-writeTransferInfoFile info tfile = writeFileAnyEncoding tfile $
-       writeTransferInfo info
+writeTransferInfoFile info tfile = writeFile tfile $ writeTransferInfo info
 
 {- File format is a header line containing the startedTime and any
  - bytesComplete value. Followed by a newline and the associatedFile.
@@ -243,7 +242,7 @@ writeTransferInfo info = unlines
 
 readTransferInfoFile :: Maybe PID -> FilePath -> IO (Maybe TransferInfo)
 readTransferInfoFile mpid tfile = catchDefaultIO Nothing $
-       readTransferInfo mpid <$> readFileStrictAnyEncoding tfile
+       readTransferInfo mpid <$> readFileStrict tfile
 
 readTransferInfo :: Maybe PID -> String -> Maybe TransferInfo
 readTransferInfo mpid s = TransferInfo
index 1035d1246c3547ae8938c4da00a5788aea29a2bc..2361fedbcf09525c067b3e01c9b8de828dea50e2 100644 (file)
@@ -66,7 +66,7 @@ updateUnusedLog prefix m = do
 writeUnusedLog :: FilePath -> UnusedLog -> Annex ()
 writeUnusedLog prefix l = do
        logfile <- fromRepo $ gitAnnexUnusedLog prefix
-       liftIO $ viaTmp writeFileAnyEncoding logfile $ unlines $ map format $ M.toList l
+       liftIO $ viaTmp writeFile logfile $ unlines $ map format $ M.toList l
   where
        format (k, (i, Just t)) = show i ++ " " ++ key2file k ++ " " ++ show t
        format (k, (i, Nothing)) = show i ++ " " ++ key2file k
@@ -76,7 +76,7 @@ readUnusedLog prefix = do
        f <- fromRepo $ gitAnnexUnusedLog prefix
        ifM (liftIO $ doesFileExist f)
                ( M.fromList . mapMaybe parse . lines
-                       <$> liftIO (readFileStrictAnyEncoding f)
+                       <$> liftIO (readFileStrict f)
                , return M.empty
                )
   where
index 0ab1f72bbbc00f7de107386e1c7e2683cba7abdb..0036e57596d28feb5e406b31e42b666f5982da49 100644 (file)
@@ -183,7 +183,6 @@ setupConsole = do
                <$> streamHandler stderr DEBUG
                <*> pure preciseLogFormatter
        updateGlobalLogger rootLoggerName (setLevel NOTICE . setHandlers [s])
-       setConsoleEncoding
        {- Force output to be line buffered. This is normally the case when
         - it's connected to a terminal, but may not be when redirected to
         - a file or a pipe. -}
index ee1724d7b373666c2efa159dcc9dc4c0b4091718..9ebb102f19b3f571ac3a9cae805dd1ee8ea09138 100644 (file)
--- a/P2P/IO.hs
+++ b/P2P/IO.hs
@@ -99,7 +99,6 @@ setupHandle s = do
        h <- socketToHandle s ReadWriteMode
        hSetBuffering h LineBuffering
        hSetBinaryMode h False
-       fileEncoding h
        return h
 
 -- Purposefully incomplete interpreter of Proto.
index 899c57e3eb581679d1224d3ad21c359babc3384d..0ec78aa6420df8ea7fa2cd8ec56c06877377971f 100644 (file)
@@ -21,6 +21,7 @@ import Types.CleanupActions
 import Messages.Progress
 import Utility.Metered
 import Utility.Tmp
+import Utility.FileSystemEncoding
 import Backend.URL
 import Annex.Perms
 import Annex.UUID
index 0b0e1dc18b576c51cfc9c79bc97efefedaf19b02..7091a657c8db63457a0c4b158a906de32ebb37d5 100644 (file)
@@ -384,9 +384,6 @@ startExternal external = do
                p <- propgit g basep
                (Just hin, Just hout, Just herr, ph) <- 
                        createProcess p `catchIO` runerr
-               fileEncoding hin
-               fileEncoding hout
-               fileEncoding herr
                stderrelay <- async $ errrelayer herr
                checkearlytermination =<< getProcessExitCode ph
                cv <- newTVarIO $ externalDefaultConfig external
diff --git a/Test.hs b/Test.hs
index 3f6727721118fba4a1ddf76b414420457335e7a4..0ab7bf1309705b79070891281f1a13739633dbc4 100644 (file)
--- a/Test.hs
+++ b/Test.hs
@@ -95,6 +95,7 @@ import qualified Utility.HumanTime
 import qualified Utility.ThreadScheduler
 import qualified Utility.Base64
 import qualified Utility.Tmp
+import qualified Utility.FileSystemEncoding
 import qualified Command.Uninit
 import qualified CmdLine.GitAnnex as GitAnnex
 #ifndef mingw32_HOST_OS
@@ -1675,7 +1676,8 @@ test_add_subdirs = intmpclonerepo $ do
         - calculated correctly for files in subdirs. -}
        unlessM (unlockedFiles <$> getTestMode) $ do
                git_annex "sync" [] @? "sync failed"
-               l <- annexeval $ decodeBS <$> Annex.CatFile.catObject (Git.Types.Ref "HEAD:dir/foo")
+               l <- annexeval $ Utility.FileSystemEncoding.decodeBS
+                       <$> Annex.CatFile.catObject (Git.Types.Ref "HEAD:dir/foo")
                "../.git/annex/" `isPrefixOf` l @? ("symlink from subdir to .git/annex is wrong: " ++ l)
 
        createDirectory "dir2"
index 94d5ac3bc4172efc76a12531527c15227ae6576a..2bae40fbaea793002bebe66b4ee7bbfdecf043f0 100644 (file)
@@ -47,10 +47,10 @@ start' s = do
        rawMode to
        return $ CoProcessState pid to from s
   where
-       rawMode h = do
-               fileEncoding h
 #ifdef mingw32_HOST_OS
-               hSetNewlineMode h noNewlineTranslation
+       rawMode h = hSetNewlineMode h noNewlineTranslation
+#else
+       rawMode _ = return ()
 #endif
 
 stop :: CoProcessHandle -> IO ()
index e581697aef0355ee81dd91a4a698bda91fc3674b..7b08820040ebb5047bc13f93b394fd48dd5390fb 100644 (file)
@@ -14,7 +14,6 @@ module Utility.ExternalSHA (externalSHA) where
 
 import Utility.SafeCommand
 import Utility.Process
-import Utility.FileSystemEncoding
 import Utility.Misc
 import Utility.Exception
 
@@ -30,7 +29,6 @@ externalSHA command shasize file = do
                Left _ -> Left (command ++ " failed")
   where
        readsha args = withHandle StdoutHandle createProcessSuccess p $ \h -> do
-               fileEncoding h
                output  <- hGetContentsStrict h
                hClose h
                return output
index eab98337a869cc1c9ada0f70ce9d79d70b7507e3..be43ace95e863d87665e36049d6828de8079a643 100644 (file)
@@ -1,6 +1,6 @@
 {- GHC File system encoding handling.
  -
- - Copyright 2012-2014 Joey Hess <id@joeyh.name>
+ - Copyright 2012-2016 Joey Hess <id@joeyh.name>
  -
  - License: BSD-2-clause
  -}
@@ -9,7 +9,7 @@
 {-# OPTIONS_GHC -fno-warn-tabs #-}
 
 module Utility.FileSystemEncoding (
-       fileEncoding,
+       useFileSystemEncoding,
        withFilePath,
        md5FilePath,
        decodeBS,
@@ -19,7 +19,6 @@ module Utility.FileSystemEncoding (
        encodeW8NUL,
        decodeW8NUL,
        truncateFilePath,
-       setConsoleEncoding,
 ) where
 
 import qualified GHC.Foreign as GHC
@@ -39,19 +38,30 @@ import qualified Data.ByteString.Lazy.UTF8 as L8
 
 import Utility.Exception
 
-{- 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".
+{- Makes all subsequent Handles that are opened, as well as stdio Handles,
+ - use the filesystem encoding, instead of the encoding of the current
+ - locale.
+ -
+ - The filesystem encoding allows "arbitrary undecodable bytes to be
+ - round-tripped through it". This avoids encoded failures when data is not
+ - encoded matching the current locale.
+ -
+ - Note that code can still use hSetEncoding to change the encoding of a
+ - Handle. This only affects the default encoding.
  -}
-fileEncoding :: Handle -> IO ()
+useFileSystemEncoding :: IO ()
+useFileSystemEncoding = do
 #ifndef mingw32_HOST_OS
-fileEncoding h = hSetEncoding h =<< Encoding.getFileSystemEncoding
+       e <- Encoding.getFileSystemEncoding
 #else
-{- The file system encoding does not work well on Windows,
- - and Windows only has utf FilePaths anyway. -}
-fileEncoding h = hSetEncoding h Encoding.utf8
+       {- The file system encoding does not work well on Windows,
       - and Windows only has utf FilePaths anyway. -}
+       let e = Encoding.utf8
 #endif
+       hSetEncoding stdin e
+       hSetEncoding stdout e
+       hSetEncoding stderr e
+       Encoding.setLocaleEncoding e    
 
 {- Marshal a Haskell FilePath into a NUL terminated C string using temporary
  - storage. The FilePath is encoded using the filesystem encoding,
@@ -165,10 +175,3 @@ truncateFilePath n = reverse . go [] n . L8.fromString
                                        else go (c:coll) (cnt - x') (L8.drop 1 bs)
                        _ -> coll
 #endif
-
-{- This avoids ghc's output layer crashing on invalid encoded characters in
- - filenames when printing them out. -}
-setConsoleEncoding :: IO ()
-setConsoleEncoding = do
-       fileEncoding stdout
-       fileEncoding stderr
index 433b7c67999773dcff697ff9debf10320f0c79bc..27d34b5925715a50f50c9ca1233aa04ea9dc1829 100644 (file)
@@ -47,9 +47,8 @@ queryDir path = query ["+d", path]
  -}
 query :: [String] -> IO [(FilePath, LsofOpenMode, ProcessInfo)]
 query opts =
-       withHandle StdoutHandle (createProcessChecked checkSuccessProcess) p $ \h -> do
-               fileEncoding h
-               parse <$> hGetContentsStrict h
+       withHandle StdoutHandle (createProcessChecked checkSuccessProcess) p $
+               parse <$$> hGetContentsStrict
   where
        p = proc "lsof" ("-F0can" : opts)
 
index 9a99cba33ffb57a22b0e647e4163de52abb94db3..e217dcdca6a6a698900e0aed61c7fb41ccf70825 100644 (file)
@@ -27,7 +27,6 @@ import Utility.Process
 import Utility.SafeCommand
 import Utility.Monad
 import Utility.Misc
-import Utility.FileSystemEncoding
 import Utility.Env
 import Utility.Path
 
@@ -105,8 +104,7 @@ sendFile f (CodeObserver observer) ps = do
        -- Work around stupid stdout buffering behavior of python.
        -- See https://github.com/warner/magic-wormhole/issues/108
        environ <- addEntry "PYTHONUNBUFFERED" "1" <$> getEnvironment
-       runWormHoleProcess p { env = Just environ} $ \_hin hout -> do
-               fileEncoding hout
+       runWormHoleProcess p { env = Just environ} $ \_hin hout ->
                findcode =<< words <$> hGetContents hout
   where
        p = wormHoleProcess (Param "send" : ps ++ [File f])
index ebb42576b20c094696c1341d89ee373d15ac06a8..4498c0a03e43317d411953e1672f59ac3a508daf 100644 (file)
@@ -10,9 +10,6 @@
 
 module Utility.Misc where
 
-import Utility.FileSystemEncoding
-import Utility.Monad
-
 import System.IO
 import Control.Monad
 import Foreign
@@ -35,20 +32,6 @@ hGetContentsStrict = hGetContents >=> \s -> length s `seq` return s
 readFileStrict :: FilePath -> IO String
 readFileStrict = readFile >=> \s -> length s `seq` return s
 
-{-  Reads a file strictly, and using the FileSystemEncoding, so it will
- -  never crash on a badly encoded file. -}
-readFileStrictAnyEncoding :: FilePath -> IO String
-readFileStrictAnyEncoding f = withFile f ReadMode $ \h -> do
-       fileEncoding h
-       hClose h `after` hGetContentsStrict h
-
-{- Writes a file, using the FileSystemEncoding so it will never crash
- - on a badly encoded content string. -}
-writeFileAnyEncoding :: FilePath -> String -> IO ()
-writeFileAnyEncoding f content = withFile f WriteMode $ \h -> do
-       fileEncoding h
-       hPutStr h content
-
 {- Like break, but the item matching the condition is not included
  - in the second result list.
  -
index 417ab7041cc095edbb9cbcb5464e64a44a024d47..d33d79bb8ee500efe65e1fa2109cee56fb74fcde 100644 (file)
@@ -153,11 +153,8 @@ httponly :: QuviParams
 httponly Quvi04 = [Param "-c", Param "http"]
 httponly _ = [] -- No way to do it with 0.9?
 
-{- Both versions of quvi will output utf-8 encoded data even when
- - the locale doesn't support it. -}
 readQuvi :: [String] -> IO String
 readQuvi ps = withHandle StdoutHandle createProcessSuccess p $ \h -> do
-       fileEncoding h
        r <- hGetContentsStrict h
        hClose h
        return r
index 860ee11ddaf05d6c83c3f8581663f05b445cea91..7adb65128907d9cc9f1d1e53220843f2465f924f 100644 (file)
@@ -48,9 +48,8 @@ findShellCommand f = do
 #ifndef mingw32_HOST_OS
        defcmd
 #else
-       l <- catchDefaultIO Nothing $ withFile f ReadMode $ \h -> do
-               fileEncoding h
-               headMaybe . lines <$> hGetContents h
+       l <- catchDefaultIO Nothing $ withFile f ReadMode $
+               headMaybe . lines <$$> hGetContents h
        case l of
                Just ('#':'!':rest) -> case words rest of
                        [] -> defcmd
index d5fab7f477f1175643404727a488e3f77aa63efd..e30d320b92431b4e66bfc818c3ce76241d7d9199 100644 (file)
@@ -15,6 +15,7 @@ import qualified CmdLine.GitAnnex
 import qualified CmdLine.GitAnnexShell
 import qualified CmdLine.GitRemoteTorAnnex
 import qualified Test
+import Utility.FileSystemEncoding
 
 #ifdef mingw32_HOST_OS
 import Utility.UserInfo
@@ -23,6 +24,7 @@ import Utility.Env
 
 main :: IO ()
 main = withSocketsDo $ do
+       useFileSystemEncoding
        ps <- getArgs
 #ifdef mingw32_HOST_OS
        winEnv
index 3bf628c754094183c97eb559e050ad90da98b6b0..18c88b1a9e6b263cb6fa1ccd1cf73f32e183db71 100644 (file)
@@ -14,6 +14,7 @@ import qualified Git.CurrentRepo
 import qualified Git.Branch
 import qualified Git.Index
 import qualified Git
+import Utility.FileSystemEncoding
 
 header :: String
 header = "Usage: git-union-merge ref ref newref"
@@ -39,6 +40,7 @@ parseArgs = do
 
 main :: IO ()
 main = do
+       useFileSystemEncoding
        [aref, bref, newref] <- map Git.Ref <$> parseArgs
        g <- Git.Config.read =<< Git.CurrentRepo.get
        _ <- Git.Index.override (tmpIndex g) g