diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d507b54..1ab0b91 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,8 +13,8 @@ jobs: ghc: - 8.8.4 - 8.10.7 - - 9.0.1 - - 9.2.1 + - 9.0.2 + - 9.2.4 fail-fast: false continue-on-error: ${{ startsWith(matrix.os, 'windows') && startsWith(matrix.ghc, '9.2') }} diff --git a/.gitignore b/.gitignore index a5f630a..26cfce9 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ *.swp .ghc.* .stack-work +cabal.project.local diff --git a/cabal.project b/cabal.project new file mode 100644 index 0000000..6a6840c --- /dev/null +++ b/cabal.project @@ -0,0 +1 @@ +packages: ./unix-compat.cabal diff --git a/src/System/PosixCompat/Types.hs b/src/System/PosixCompat/Types.hs index f9288bc..82fcbb9 100644 --- a/src/System/PosixCompat/Types.hs +++ b/src/System/PosixCompat/Types.hs @@ -1,47 +1,163 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# OPTIONS_GHC -Wno-unused-imports #-} + {-| This module re-exports the types from @System.Posix.Types@ on all platforms. - -On Windows 'UserID', 'GroupID' and 'LinkCount' are missing, so they are -redefined by this module. +It defines drop-in replacements for types that are missing from that module on a +specific OS. Namely Mac OS and Windows are supported. -} module System.PosixCompat.Types ( module System.Posix.Types +#ifdef darwin_HOST_OS + , CTimer(..) +#endif #ifdef mingw32_HOST_OS + , CBlkCnt(..) + , CBlkSize(..) + , CCc(..) + , CFsBlkCnt(..) + , CFsFilCnt(..) + , CId(..) + , CKey(..) + , CRLim(..) + , CSpeed(..) + , CTcflag(..) + , CTimer(..) , UserID + , CUid(..) , GroupID + , CGid(..) , LinkCount + , CNlink(..) +#endif +#if defined mingw32_HOST_OS || !MIN_VERSION_base(4, 14, 0) + , CNfds(..) + , CSocklen(..) #endif ) where +import Data.Int (Int32, Int64) +import Data.Word (Word8, Word32, Word64) +import Foreign (Ptr) +import System.Posix.Types + +#ifdef darwin_HOST_OS + +newtype CTimer = CTimer (Ptr ()) + deriving (Eq, Ord) +instance Show CTimer where show (CTimer x) = show x + +#endif + #ifdef mingw32_HOST_OS -- Since CIno (FileID's underlying type) reflects ino_t, -- which mingw defines as short int (int16), it must be overriden to -- match the size of windows fileIndex (word64). -import System.Posix.Types -import Data.Word (Word32) +newtype CBlkCnt = CBlkCnt Int64 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CBlkCnt where show (CBlkCnt x) = show x +instance Read CBlkCnt where readsPrec i s = [ (CBlkCnt x, s') + | (x,s') <- readsPrec i s] -newtype UserID = UserID Word32 +newtype CBlkSize = CBlkSize Int64 deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) -instance Show UserID where show (UserID x) = show x -instance Read UserID where readsPrec i s = [ (UserID x, s') +instance Show CBlkSize where show (CBlkSize x) = show x +instance Read CBlkSize where readsPrec i s = [ (CBlkSize x, s') | (x,s') <- readsPrec i s] -newtype GroupID = GroupID Word32 +newtype CCc = CCc Word8 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CCc where show (CCc x) = show x +instance Read CCc where readsPrec i s = [ (CCc x, s') + | (x,s') <- readsPrec i s] + +newtype CFsBlkCnt = CFsBlkCnt Word64 deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) -instance Show GroupID where show (GroupID x) = show x -instance Read GroupID where readsPrec i s = [ (GroupID x, s') +instance Show CFsBlkCnt where show (CFsBlkCnt x) = show x +instance Read CFsBlkCnt where readsPrec i s = [ (CFsBlkCnt x, s') | (x,s') <- readsPrec i s] -newtype LinkCount = LinkCount Word32 +newtype CFsFilCnt = CFsFilCnt Word64 deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) -instance Show LinkCount where show (LinkCount x) = show x -instance Read LinkCount where readsPrec i s = [ (LinkCount x, s') - | (x,s') <- readsPrec i s] +instance Show CFsFilCnt where show (CFsFilCnt x) = show x +instance Read CFsFilCnt where readsPrec i s = [ (CFsFilCnt x, s') + | (x,s') <- readsPrec i s] + +newtype CId = CId Word32 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CId where show (CId x) = show x +instance Read CId where readsPrec i s = [ (CId x, s') + | (x,s') <- readsPrec i s] + +newtype CKey = CKey Int32 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CKey where show (CKey x) = show x +instance Read CKey where readsPrec i s = [ (CKey x, s') + | (x,s') <- readsPrec i s] + +newtype CRLim = CRLim Word64 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CRLim where show (CRLim x) = show x +instance Read CRLim where readsPrec i s = [ (CRLim x, s') + | (x,s') <- readsPrec i s] + +newtype CSpeed = CSpeed Word32 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CSpeed where show (CSpeed x) = show x +instance Read CSpeed where readsPrec i s = [ (CSpeed x, s') + | (x,s') <- readsPrec i s] + +newtype CTcflag = CTcflag Word32 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CTcflag where show (CTcflag x) = show x +instance Read CTcflag where readsPrec i s = [ (CTcflag x, s') + | (x,s') <- readsPrec i s] + +newtype CTimer = CTimer (Ptr ()) + deriving (Eq, Ord) +instance Show CTimer where show (CTimer x) = show x + +type UserID = CUid + +newtype CUid = CUid Word32 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CUid where show (CUid x) = show x +instance Read CUid where readsPrec i s = [ (CUid x, s') + | (x,s') <- readsPrec i s] + +type GroupID = CGid + +newtype CGid = CGid Word32 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CGid where show (CGid x) = show x +instance Read CGid where readsPrec i s = [ (CGid x, s') + | (x,s') <- readsPrec i s] + +type LinkCount = CNlink + +newtype CNlink = CNlink Word64 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CNlink where show (CNlink x) = show x +instance Read CNlink where readsPrec i s = [ (CNlink x, s') + | (x,s') <- readsPrec i s] + +#endif + +#if defined mingw32_HOST_OS || !MIN_VERSION_base(4, 14, 0) + +newtype CNfds = CNfds Word64 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CNfds where show (CNfds x) = show x +instance Read CNfds where readsPrec i s = [ (CNfds x, s') + | (x,s') <- readsPrec i s] + +newtype CSocklen = CSocklen Word32 + deriving (Eq, Ord, Enum, Bounded, Integral, Num, Real) +instance Show CSocklen where show (CSocklen x) = show x +instance Read CSocklen where readsPrec i s = [ (CSocklen x, s') + | (x,s') <- readsPrec i s] -#else -import System.Posix.Types #endif diff --git a/tests/check-types.hs b/tests/check-types.hs new file mode 100644 index 0000000..3505046 --- /dev/null +++ b/tests/check-types.hs @@ -0,0 +1,178 @@ +{-# LANGUAGE CPP #-} + +{-# OPTIONS_GHC -Wno-unused-top-binds #-} + +module Main (main) where + +import Data.Int +import Data.Word +import System.PosixCompat.Types + +import qualified Foreign +import qualified Foreign.C.Types + +main :: IO () +main = pure () + +newtypeCBlkCnt :: CBlkCnt -> Int64 +newtypeCBlkCnt (CBlkCnt x) = x + +#ifdef darwin_HOST_OS +newtypeCBlkSize :: CBlkSize -> Int32 +#else +newtypeCBlkSize :: CBlkSize -> Int64 +#endif +newtypeCBlkSize (CBlkSize x) = x + +newtypeCCc :: CCc -> Word8 +newtypeCCc (CCc x) = x + +#ifdef darwin_HOST_OS +newtypeCClockId :: CClockId -> Word32 +#else +newtypeCClockId :: CClockId -> Int32 +#endif +newtypeCClockId (CClockId x) = x + +#ifdef darwin_HOST_OS +newtypeCDev :: CDev -> Int32 +#elif defined mingw32_HOST_OS +newtypeCDev :: CDev -> Word32 +#else +newtypeCDev :: CDev -> Word64 +#endif +newtypeCDev (CDev x) = x + +#ifdef darwin_HOST_OS +newtypeCFsBlkCnt :: CFsBlkCnt -> Word32 +#else +newtypeCFsBlkCnt :: CFsBlkCnt -> Word64 +#endif +newtypeCFsBlkCnt (CFsBlkCnt x) = x + +#ifdef darwin_HOST_OS +newtypeCFsFilCnt :: CFsFilCnt -> Word32 +#else +newtypeCFsFilCnt :: CFsFilCnt -> Word64 +#endif +newtypeCFsFilCnt (CFsFilCnt x) = x + +newtypeCGid :: CGid -> Word32 +newtypeCGid (CGid x) = x + +newtypeCId :: CId -> Word32 +newtypeCId (CId x) = x + +#ifdef mingw32_HOST_OS +newtypeCIno :: CIno -> Word16 +#else +newtypeCIno :: CIno -> Word64 +#endif +newtypeCIno (CIno x) = x + +newtypeCKey :: CKey -> Int32 +newtypeCKey (CKey x) = x + +#ifdef darwin_HOST_OS +newtypeCMode :: CMode -> Word16 +#elif defined mingw32_HOST_OS +newtypeCMode :: CMode -> Word16 +#else +newtypeCMode :: CMode -> Word32 +#endif +newtypeCMode (CMode x) = x + +#if defined darwin_HOST_OS && MIN_VERSION_base(4, 14, 0) +newtypeCNfds :: CNfds -> Word32 +#else +newtypeCNfds :: CNfds -> Word64 +#endif +newtypeCNfds (CNfds x) = x + +#ifdef darwin_HOST_OS +newtypeCNlink :: CNlink -> Word16 +#else +newtypeCNlink :: CNlink -> Word64 +#endif +newtypeCNlink (CNlink x) = x + +newtypeCOff :: COff -> Int64 +newtypeCOff (COff x) = x + +#ifdef mingw32_HOST_OS +newtypeCPid :: CPid -> Int64 +#else +newtypeCPid :: CPid -> Int32 +#endif +newtypeCPid (CPid x) = x + +newtypeCRLim :: CRLim -> Word64 +newtypeCRLim (CRLim x) = x + +newtypeCSocklen :: CSocklen -> Word32 +newtypeCSocklen (CSocklen x) = x + +#ifdef darwin_HOST_OS +newtypeCSpeed :: CSpeed -> Word64 +#else +newtypeCSpeed :: CSpeed -> Word32 +#endif +newtypeCSpeed (CSpeed x) = x + +newtypeCSsize :: CSsize -> Int64 +newtypeCSsize (CSsize x) = x + +#ifdef darwin_HOST_OS +newtypeCTcflag :: CTcflag -> Word64 +#else +newtypeCTcflag :: CTcflag -> Word32 +#endif +newtypeCTcflag (CTcflag x) = x + +newtypeCTimer :: CTimer -> Foreign.Ptr () +newtypeCTimer (CTimer x) = x + +newtypeCUid :: CUid -> Word32 +newtypeCUid (CUid x) = x + +newtypeFd :: Fd -> Foreign.C.Types.CInt +newtypeFd (Fd x) = x + +typeByteCount :: ByteCount -> Foreign.C.Types.CSize +typeByteCount = id + +typeClockTick :: ClockTick -> Foreign.C.Types.CClock +typeClockTick = id + +typeDeviceID :: DeviceID -> CDev +typeDeviceID = id + +typeEpochTime :: EpochTime -> Foreign.C.Types.CTime +typeEpochTime = id + +typeFileID :: FileID -> CIno +typeFileID = id + +typeFileMode :: FileMode -> CMode +typeFileMode = id + +typeFileOffset :: FileOffset -> COff +typeFileOffset = id + +typeGroupID :: GroupID -> CGid +typeGroupID = id + +typeLimit :: Limit -> Foreign.C.Types.CLong +typeLimit = id + +typeLinkCount :: LinkCount -> CNlink +typeLinkCount = id + +typeProcessGroupID :: ProcessGroupID -> CPid +typeProcessGroupID = id + +typeProcessID :: ProcessID -> CPid +typeProcessID = id + +typeUserID :: UserID -> CUid +typeUserID = id diff --git a/unix-compat.cabal b/unix-compat.cabal index 8879404..94eb267 100644 --- a/unix-compat.cabal +++ b/unix-compat.cabal @@ -146,3 +146,15 @@ Test-Suite unix-compat-testsuite cc-options: -DSOLARIS build-depends: directory >= 1.3.1 && < 1.4 + +Test-Suite unix-compat-check-types + default-language: Haskell2010 + type: exitcode-stdio-1.0 + hs-source-dirs: tests + ghc-options: -Wall + main-is: check-types.hs + + build-depends: + unix-compat + , base == 4.* +