1{-# LANGUAGE CPP #-} 2{-# LANGUAGE Safe #-} 3{- Windows compatibility layer 4Copyright (c) 2005-2011 John Goerzen <jgoerzen@complete.org> 5 6All rights reserved. 7 8For license and copyright information, see the file LICENSE 9-} 10 11{- | 12 Module : System.IO.WindowsCompat 13 Copyright : Copyright (C) 2005-2011 John Goerzen 14 SPDX-License-Identifier: BSD-3-Clause 15 16 Stability : provisional 17 Portability: portable 18 19Provides some types and related items on Windows to be compatible with 20the System.Posix.* libraries 21 22See also "System.IO.StatCompat", which this module re-exports. 23 24On non-Windows platforms, this module does nothing. 25 26On Windows, it re-exports "System.IO.StatCompat". It also provides various 27file type information modes that are otherwise in "System.Posix.Types" or 28"System.Posix.Files". It also provides 29a rudimentary implemention of getFileStatus that emulates the Posix call 30to stat(2). 31 32Common usage might be like this: 33 34>import System.Posix.Types 35>#if (defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__)) 36>import System.IO.WindowsCompat 37>#else 38>import System.Posix.Files 39>#endif 40 41Or, to avoid having to use CPP and make things even easier, just import 42"System.IO.PlafCompat", which essentially does the above. 43 44-} 45 46module System.IO.WindowsCompat 47#if !(defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__)) 48where 49#else 50 (module System.IO.StatCompat, module System.IO.WindowsCompat) 51where 52 53import System.Posix.Types 54import Data.Bits 55import System.IO.StatCompat 56import System.Posix.Consts 57import System.Time.Utils 58import System.Directory 59import Data.Time 60import Data.Time.Clock.POSIX 61 62-- these types aren't defined here 63 64nullFileMode :: FileMode 65nullFileMode = 0 66 67ownerReadMode :: FileMode 68ownerReadMode = 0o00400 69 70ownerWriteMode :: FileMode 71ownerWriteMode = 0o00200 72 73ownerExecuteMode :: FileMode 74ownerExecuteMode = 0o00100 75 76groupReadMode :: FileMode 77groupReadMode = 0o00040 78 79groupWriteMode :: FileMode 80groupWriteMode = 0o00020 81 82groupExecuteMode :: FileMode 83groupExecuteMode = 0o00010 84 85otherReadMode :: FileMode 86otherReadMode = 0o00004 87 88otherWriteMode :: FileMode 89otherWriteMode = 0o00002 90 91otherExecuteMode :: FileMode 92otherExecuteMode = 0o00001 93 94setUserIDMode :: FileMode 95setUserIDMode = 0o0004000 96 97setGroupIDMode :: FileMode 98setGroupIDMode = 0o0002000 99 100stdFileMode :: FileMode 101stdFileMode = ownerReadMode .|. ownerWriteMode .|. 102 groupReadMode .|. groupWriteMode .|. 103 otherReadMode .|. otherWriteMode 104 105ownerModes :: FileMode 106ownerModes = 0o00700 107 108groupModes :: FileMode 109groupModes = 0o00070 110 111otherModes :: FileMode 112otherModes = 0o00007 113 114accessModes :: FileMode 115accessModes = ownerModes .|. groupModes .|. otherModes 116 117utcTimeToSeconds :: Num a => UTCTime -> a 118utcTimeToSeconds = fromInteger . floor . utcTimeToPOSIXSeconds 119 120----------- stat 121type FileStatus = FileStatusCompat 122getFileStatus :: FilePath -> IO FileStatus 123getFileStatus fp = 124 do isfile <- doesFileExist fp 125 isdir <- doesDirectoryExist fp 126 perms <- getPermissions fp 127 modct <- getModificationTime fp 128#if MIN_VERSION_directory(1,2,0) 129 let epochtime = utcTimeToSeconds modct 130#else 131 let epochtime = clockTimeToEpoch modct 132#endif 133 return $ FileStatusCompat {deviceID = -1, 134 fileID = -1, 135 fileMode = if isfile then regularFileMode 136 else directoryMode, 137 linkCount = 1, 138 fileOwner = 0, 139 fileGroup = 0, 140 specialDeviceID = -1, 141 fileSize = 0, -- fixme: hFileSize? 142 accessTime = fromInteger epochtime, 143 modificationTime = fromInteger epochtime, 144 statusChangeTime = fromInteger epochtime 145 } 146#endif 147