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