2020-10-28 21:25:59 +00:00
|
|
|
{- Portability shim for basic operations on RawFilePaths.
|
2019-12-06 18:17:48 +00:00
|
|
|
-
|
|
|
|
- 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
|
2023-03-01 19:55:58 +00:00
|
|
|
- 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.
|
2019-01-14 19:19:20 +00:00
|
|
|
-
|
2023-03-01 19:55:58 +00:00
|
|
|
- Copyright 2019-2023 Joey Hess <id@joeyh.name>
|
2019-01-14 19:19:20 +00:00
|
|
|
-
|
|
|
|
- License: BSD-2-clause
|
|
|
|
-}
|
|
|
|
|
|
|
|
{-# LANGUAGE CPP #-}
|
2020-11-09 16:06:53 +00:00
|
|
|
{-# OPTIONS_GHC -fno-warn-tabs #-}
|
2019-01-14 19:19:20 +00:00
|
|
|
|
|
|
|
module Utility.RawFilePath (
|
|
|
|
RawFilePath,
|
|
|
|
readSymbolicLink,
|
2020-10-28 20:03:45 +00:00
|
|
|
createSymbolicLink,
|
2020-10-29 14:33:12 +00:00
|
|
|
createLink,
|
|
|
|
removeLink,
|
2019-12-06 18:44:42 +00:00
|
|
|
getFileStatus,
|
2019-12-06 19:37:12 +00:00
|
|
|
getSymbolicLinkStatus,
|
2019-12-11 18:12:22 +00:00
|
|
|
doesPathExist,
|
2020-10-28 20:03:45 +00:00
|
|
|
getCurrentDirectory,
|
2020-10-28 21:25:59 +00:00
|
|
|
createDirectory,
|
2020-11-05 22:45:37 +00:00
|
|
|
setFileMode,
|
2023-03-01 19:55:58 +00:00
|
|
|
setOwnerAndGroup,
|
2022-06-22 20:47:34 +00:00
|
|
|
rename,
|
2023-03-01 19:55:58 +00:00
|
|
|
createNamedPipe,
|
|
|
|
fileAccess,
|
2019-01-14 19:19:20 +00:00
|
|
|
) where
|
|
|
|
|
|
|
|
#ifndef mingw32_HOST_OS
|
2019-12-06 18:44:42 +00:00
|
|
|
import Utility.FileSystemEncoding (RawFilePath)
|
2019-01-14 19:19:20 +00:00
|
|
|
import System.Posix.Files.ByteString
|
2020-10-28 21:25:59 +00:00
|
|
|
import qualified System.Posix.Directory.ByteString as D
|
2019-12-11 18:12:22 +00:00
|
|
|
|
2020-10-29 16:02:46 +00:00
|
|
|
-- | Checks if a file or directory exists. Note that a dangling symlink
|
2020-07-20 01:31:06 +00:00
|
|
|
-- will be false.
|
2019-12-11 18:12:22 +00:00
|
|
|
doesPathExist :: RawFilePath -> IO Bool
|
|
|
|
doesPathExist = fileExist
|
|
|
|
|
2020-10-28 20:03:45 +00:00
|
|
|
getCurrentDirectory :: IO RawFilePath
|
2020-10-28 21:25:59 +00:00
|
|
|
getCurrentDirectory = D.getWorkingDirectory
|
|
|
|
|
|
|
|
createDirectory :: RawFilePath -> IO ()
|
|
|
|
createDirectory p = D.createDirectory p 0o777
|
2020-10-28 20:03:45 +00:00
|
|
|
|
2019-01-14 19:19:20 +00:00
|
|
|
#else
|
2020-11-05 22:45:37 +00:00
|
|
|
import System.PosixCompat (FileStatus, FileMode)
|
2023-03-01 19:55:58 +00:00
|
|
|
-- 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
|
2019-12-06 18:17:48 +00:00
|
|
|
import qualified System.PosixCompat as P
|
2019-12-11 18:12:22 +00:00
|
|
|
import qualified System.Directory as D
|
2019-12-06 18:17:48 +00:00
|
|
|
import Utility.FileSystemEncoding
|
2023-03-01 19:55:58 +00:00
|
|
|
import Utility.Path.Windows
|
2019-01-14 19:19:20 +00:00
|
|
|
|
|
|
|
readSymbolicLink :: RawFilePath -> IO RawFilePath
|
2019-12-06 18:17:48 +00:00
|
|
|
readSymbolicLink f = toRawFilePath <$> P.readSymbolicLink (fromRawFilePath f)
|
2019-12-06 18:44:42 +00:00
|
|
|
|
2020-10-28 20:03:45 +00:00
|
|
|
createSymbolicLink :: RawFilePath -> RawFilePath -> IO ()
|
2023-03-01 19:55:58 +00:00
|
|
|
createSymbolicLink a b = do
|
|
|
|
a' <- fromRawFilePath <$> convertToWindowsNativeNamespace a
|
|
|
|
b' <- fromRawFilePath <$> convertToWindowsNativeNamespace b
|
|
|
|
P.createSymbolicLink a' b'
|
2020-10-28 20:03:45 +00:00
|
|
|
|
2020-10-29 14:33:12 +00:00
|
|
|
createLink :: RawFilePath -> RawFilePath -> IO ()
|
2023-03-01 19:55:58 +00:00
|
|
|
createLink a b = do
|
|
|
|
a' <- fromRawFilePath <$> convertToWindowsNativeNamespace a
|
|
|
|
b' <- fromRawFilePath <$> convertToWindowsNativeNamespace b
|
|
|
|
P.createLink a' b'
|
2020-10-29 14:33:12 +00:00
|
|
|
|
2020-11-19 16:20:18 +00:00
|
|
|
{- On windows, removeLink is not available, so only remove files,
|
|
|
|
- not symbolic links. -}
|
2020-10-29 14:33:12 +00:00
|
|
|
removeLink :: RawFilePath -> IO ()
|
2020-11-19 16:20:18 +00:00
|
|
|
removeLink = D.removeFile . fromRawFilePath
|
2020-10-29 14:33:12 +00:00
|
|
|
|
2019-12-06 18:44:42 +00:00
|
|
|
getFileStatus :: RawFilePath -> IO FileStatus
|
2023-03-01 19:55:58 +00:00
|
|
|
getFileStatus p = P.getFileStatus . fromRawFilePath
|
|
|
|
=<< convertToWindowsNativeNamespace p
|
2019-12-06 19:37:12 +00:00
|
|
|
|
|
|
|
getSymbolicLinkStatus :: RawFilePath -> IO FileStatus
|
2023-03-01 19:55:58 +00:00
|
|
|
getSymbolicLinkStatus p = P.getSymbolicLinkStatus . fromRawFilePath
|
|
|
|
=<< convertToWindowsNativeNamespace p
|
2019-12-11 18:12:22 +00:00
|
|
|
|
|
|
|
doesPathExist :: RawFilePath -> IO Bool
|
|
|
|
doesPathExist = D.doesPathExist . fromRawFilePath
|
2020-10-28 20:03:45 +00:00
|
|
|
|
|
|
|
getCurrentDirectory :: IO RawFilePath
|
|
|
|
getCurrentDirectory = toRawFilePath <$> D.getCurrentDirectory
|
2020-10-28 21:25:59 +00:00
|
|
|
|
|
|
|
createDirectory :: RawFilePath -> IO ()
|
|
|
|
createDirectory = D.createDirectory . fromRawFilePath
|
2020-11-05 22:45:37 +00:00
|
|
|
|
|
|
|
setFileMode :: RawFilePath -> FileMode -> IO ()
|
2023-03-01 19:55:58 +00:00
|
|
|
setFileMode p m = do
|
|
|
|
p' <- fromRawFilePath <$> convertToWindowsNativeNamespace p
|
|
|
|
P.setFileMode p' m
|
2022-06-22 20:47:34 +00:00
|
|
|
|
2022-07-12 18:53:32 +00:00
|
|
|
{- Using renamePath rather than the rename provided in unix-compat
|
|
|
|
- because of this bug https://github.com/jacobstanley/unix-compat/issues/56-}
|
2022-06-22 20:47:34 +00:00
|
|
|
rename :: RawFilePath -> RawFilePath -> IO ()
|
2022-07-12 18:53:32 +00:00
|
|
|
rename a b = D.renamePath (fromRawFilePath a) (fromRawFilePath b)
|
2023-03-01 19:55:58 +00:00
|
|
|
|
|
|
|
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
|
2019-01-14 19:19:20 +00:00
|
|
|
#endif
|