git-annex/Utility/RawFilePath.hs

126 lines
4 KiB
Haskell
Raw Normal View History

{- Portability shim for basic operations on RawFilePaths.
-
- On unix, this makes syscalls using RawFilesPaths as efficiently as
- possible.
-
- On Windows, filenames are in unicode, so RawFilePaths have to be
- decoded. So this library will work, but less efficiently than using
- FilePath would. However, this library also takes care to support long
- filenames on Windows, by either using other libraries that do, or by
- doing UNC-style conversion itself.
-
- Copyright 2019-2023 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
{-# LANGUAGE CPP #-}
2020-11-09 16:06:53 +00:00
{-# OPTIONS_GHC -fno-warn-tabs #-}
module Utility.RawFilePath (
RawFilePath,
readSymbolicLink,
createSymbolicLink,
createLink,
removeLink,
getFileStatus,
getSymbolicLinkStatus,
doesPathExist,
getCurrentDirectory,
createDirectory,
setFileMode,
setOwnerAndGroup,
rename,
createNamedPipe,
fileAccess,
) where
#ifndef mingw32_HOST_OS
import Utility.FileSystemEncoding (RawFilePath)
import System.Posix.Files.ByteString
import qualified System.Posix.Directory.ByteString as D
-- | Checks if a file or directory exists. Note that a dangling symlink
2020-07-20 01:31:06 +00:00
-- will be false.
doesPathExist :: RawFilePath -> IO Bool
doesPathExist = fileExist
getCurrentDirectory :: IO RawFilePath
getCurrentDirectory = D.getWorkingDirectory
createDirectory :: RawFilePath -> IO ()
createDirectory p = D.createDirectory p 0o777
#else
import System.PosixCompat (FileStatus, FileMode)
-- System.PosixCompat does not handle UNC-style conversion itself,
-- so all uses of it library have to be pre-converted below. See
-- https://github.com/jacobstanley/unix-compat/issues/56
import qualified System.PosixCompat as P
import qualified System.Directory as D
import Utility.FileSystemEncoding
import Utility.Path.Windows
readSymbolicLink :: RawFilePath -> IO RawFilePath
readSymbolicLink f = toRawFilePath <$> P.readSymbolicLink (fromRawFilePath f)
createSymbolicLink :: RawFilePath -> RawFilePath -> IO ()
createSymbolicLink a b = do
a' <- fromRawFilePath <$> convertToWindowsNativeNamespace a
b' <- fromRawFilePath <$> convertToWindowsNativeNamespace b
P.createSymbolicLink a' b'
createLink :: RawFilePath -> RawFilePath -> IO ()
createLink a b = do
a' <- fromRawFilePath <$> convertToWindowsNativeNamespace a
b' <- fromRawFilePath <$> convertToWindowsNativeNamespace b
P.createLink a' b'
{- On windows, removeLink is not available, so only remove files,
- not symbolic links. -}
removeLink :: RawFilePath -> IO ()
removeLink = D.removeFile . fromRawFilePath
getFileStatus :: RawFilePath -> IO FileStatus
getFileStatus p = P.getFileStatus . fromRawFilePath
=<< convertToWindowsNativeNamespace p
getSymbolicLinkStatus :: RawFilePath -> IO FileStatus
getSymbolicLinkStatus p = P.getSymbolicLinkStatus . fromRawFilePath
=<< convertToWindowsNativeNamespace p
doesPathExist :: RawFilePath -> IO Bool
doesPathExist = D.doesPathExist . fromRawFilePath
getCurrentDirectory :: IO RawFilePath
getCurrentDirectory = toRawFilePath <$> D.getCurrentDirectory
createDirectory :: RawFilePath -> IO ()
createDirectory = D.createDirectory . fromRawFilePath
setFileMode :: RawFilePath -> FileMode -> IO ()
setFileMode p m = do
p' <- fromRawFilePath <$> convertToWindowsNativeNamespace p
P.setFileMode p' m
{- Using renamePath rather than the rename provided in unix-compat
- because of this bug https://github.com/jacobstanley/unix-compat/issues/56-}
rename :: RawFilePath -> RawFilePath -> IO ()
rename a b = D.renamePath (fromRawFilePath a) (fromRawFilePath b)
setOwnerAndGroup :: RawFilePath -> P.UserID -> P.GroupID -> IO ()
setOwnerAndGroup p u g = do
p' <- fromRawFilePath <$> convertToWindowsNativeNamespace p
P.setOwnerAndGroup p' u g
createNamedPipe :: RawFilePath -> FileMode -> IO ()
createNamedPipe p m = do
p' <- fromRawFilePath <$> convertToWindowsNativeNamespace p
P.createNamedPipe p' m
fileAccess :: RawFilePath -> Bool -> Bool -> Bool -> IO Bool
fileAccess p a b c = do
p' <- fromRawFilePath <$> convertToWindowsNativeNamespace p
P.fileAccess p' a b c
#endif