unix-compat 0.6 → 0.7.4.1
raw patch · 14 files changed
Files
- CHANGELOG.md +32/−1
- cbits/HsUnixCompat.c +1/−1
- cbits/mktemp.c +24/−8
- include/HsUnixCompat.h +0/−2
- src/System/PosixCompat.hs +2/−2
- src/System/PosixCompat/Extensions.hsc +4/−4
- src/System/PosixCompat/Files.hsc +2/−2
- src/System/PosixCompat/Internal/Time.hs +0/−12
- src/System/PosixCompat/Process.hs +30/−0
- src/System/PosixCompat/Temp.hs +2/−2
- src/System/PosixCompat/User.hsc +0/−133
- tests/ProcessSpec.hs +12/−0
- tests/main.hs +2/−0
- unix-compat.cabal +51/−89
CHANGELOG.md view
@@ -1,3 +1,34 @@+## Version 0.7.4.1 (2025-08-26)++- Fix build with `-Werror=unused-packages`.+- Tested with GHC 8.0 - 9.14 alpha1.++## Version 0.7.4 (2025-03-27)++- Add `wasm32-wasi` support+ ([PR #16](https://github.com/haskell-pkg-janitors/unix-compat/pull/16)).+- Tested with GHC 8.0 - 9.12.++## Version 0.7.3 (2024-10-11)++- Fix `sysmacros.h` include for GNU/Hurd+ ([PR #12](https://github.com/haskell-pkg-janitors/unix-compat/pull/12)).+- Tested with GHC 8.0 - 9.10.++## Version 0.7.2 (2024-06-25)++- Remove flag `old-time` and drop support for `old-time`.+- Remove support for GHC 7.+- Tested with GHC 8.0 - 9.10.++## Version 0.7.1 (2023-12-06) Santa Clause edition++- Add `System.PosixCompat.Process` module, exporting `getProcessID`.++## Version 0.7 (2023-03-15)++- Remove `System.PosixCompat.User` module.+ ## Version 0.6 (2022-05-22) -- Better support for symbolic links+- Better support for symbolic links.
cbits/HsUnixCompat.c view
@@ -2,7 +2,7 @@ #ifdef SOLARIS #include <sys/mkdev.h>-#elif defined(__linux__)+#elif defined(__linux__) || defined(__GNU__) #include <sys/sysmacros.h> #endif
cbits/mktemp.c view
@@ -41,13 +41,21 @@ #include <stdlib.h> #include <string.h> #include <unistd.h>++#if defined(__wasm__)+#include <sys/random.h>+#else #include <windows.h> #include <wincrypt.h> -static int random(uint32_t *);+#define open _open+#define stat _stat+#endif++static int unixcompat_random(uint32_t *); static int _gettemp(char *, int *); -static const unsigned char padchar[] =+static const char padchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; int unixcompat_mkstemp(char *path)@@ -64,7 +72,7 @@ { char *start, *trv, *suffp, *carryp; char *pad;- struct _stat sbuf;+ struct stat sbuf; int rval; uint32_t randidx, randval; char carrybuf[MAXPATHLEN];@@ -84,7 +92,7 @@ /* Fill space with random characters */ while (trv >= path && *trv == 'X') {- if (!random(&randval)) {+ if (!unixcompat_random(&randval)) { /* this should never happen */ errno = EIO; return 0;@@ -104,7 +112,7 @@ for (; trv > path; --trv) { if (*trv == '/') { *trv = '\0';- rval = _stat(path, &sbuf);+ rval = stat(path, &sbuf); *trv = '/'; if (rval != 0) return (0);@@ -120,11 +128,11 @@ for (;;) { if (doopen) { if ((*doopen =- _open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)+ open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) return (1); if (errno != EEXIST) return (0);- } else if (_stat(path, &sbuf))+ } else if (stat(path, &sbuf)) return (errno == ENOENT); /* If we have a collision, cycle through the space of filenames */@@ -154,8 +162,15 @@ /*NOTREACHED*/ } -static int random(uint32_t *value)+#if defined(__wasm__)+static int unixcompat_random(uint32_t *value) {+ int r = getentropy(value, sizeof(uint32_t));+ return r == 0 ? 1 : 0;+}+#else+static int unixcompat_random(uint32_t *value)+{ /* This handle is never released. Windows will clean up when the process * exits. Python takes this approach when emulating /dev/urandom, and if * it's good enough for them, then it's good enough for us. */@@ -171,3 +186,4 @@ return 1; }+#endif
include/HsUnixCompat.h view
@@ -4,5 +4,3 @@ unsigned int unix_major(dev_t dev); unsigned int unix_minor(dev_t dev); dev_t unix_makedev(unsigned int maj, unsigned int min);--#define NEED_setSymbolicLinkOwnerAndGroup !HAVE_LCHOWN
src/System/PosixCompat.hs view
@@ -7,20 +7,20 @@ -} module System.PosixCompat ( module System.PosixCompat.Files+ , module System.PosixCompat.Process , module System.PosixCompat.Temp , module System.PosixCompat.Time , module System.PosixCompat.Types , module System.PosixCompat.Unistd- , module System.PosixCompat.User , usingPortableImpl ) where import System.PosixCompat.Files+import System.PosixCompat.Process import System.PosixCompat.Temp import System.PosixCompat.Time import System.PosixCompat.Types import System.PosixCompat.Unistd-import System.PosixCompat.User -- | 'True' if unix-compat is using its portable implementation, -- or 'False' if the unix package is simply being re-exported.
src/System/PosixCompat/Extensions.hsc view
@@ -12,7 +12,7 @@ ) where -#ifndef mingw32_HOST_OS+#if !(defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH)) #include "HsUnixCompat.h" #endif @@ -27,7 +27,7 @@ -- -- The portable implementation always returns @0@. deviceMajor :: DeviceID -> CMajor-#ifdef mingw32_HOST_OS+#if defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH) deviceMajor _ = 0 #else deviceMajor dev = unix_major dev@@ -39,7 +39,7 @@ -- -- The portable implementation always returns @0@. deviceMinor :: DeviceID -> CMinor-#ifdef mingw32_HOST_OS+#if defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH) deviceMinor _ = 0 #else deviceMinor dev = unix_minor dev@@ -49,7 +49,7 @@ -- | Creates a 'DeviceID' for a device file given a major and minor number. makeDeviceID :: CMajor -> CMinor -> DeviceID-#ifdef mingw32_HOST_OS+#if defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH) makeDeviceID _ _ = 0 #else makeDeviceID ma mi = unix_makedev ma mi
src/System/PosixCompat/Files.hsc view
@@ -106,11 +106,11 @@ #ifndef mingw32_HOST_OS -#include "HsUnixCompat.h"+#include "HsUnixConfig.h" import System.Posix.Files -#if NEED_setSymbolicLinkOwnerAndGroup+#if !HAVE_LCHOWN import System.PosixCompat.Types setSymbolicLinkOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO ()
src/System/PosixCompat/Internal/Time.hs view
@@ -10,16 +10,6 @@ ) where import System.Posix.Types (EpochTime)--#ifdef OLD_TIME--import System.Time (ClockTime(TOD), getClockTime)--clockTimeToEpochTime :: ClockTime -> EpochTime-clockTimeToEpochTime (TOD s _) = fromInteger s--#else- import Data.Time.Clock.POSIX (POSIXTime, getPOSIXTime) type ClockTime = POSIXTime@@ -29,5 +19,3 @@ clockTimeToEpochTime :: ClockTime -> EpochTime clockTimeToEpochTime = fromInteger . floor--#endif
+ src/System/PosixCompat/Process.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE CPP #-}++{-|+This module intends to make the operations of @System.Posix.Process@ available+on all platforms.+-}+module System.PosixCompat.Process (+ getProcessID+ ) where++#if defined(mingw32_HOST_OS)++import System.Posix.Types (ProcessID)+import System.Win32.Process (getCurrentProcessId)++getProcessID :: IO ProcessID+getProcessID = fromIntegral <$> getCurrentProcessId++#elif defined(wasm32_HOST_ARCH)++import System.Posix.Types (ProcessID)++getProcessID :: IO ProcessID+getProcessID = pure 1++#else++import System.Posix.Process++#endif
src/System/PosixCompat/Temp.hs view
@@ -11,13 +11,13 @@ mkstemp ) where -#ifndef mingw32_HOST_OS+#if !(defined(mingw32_HOST_OS) || defined(wasm32_HOST_ARCH)) -- Re-export unix package import System.Posix.Temp #elif defined(__GLASGOW_HASKELL__)--- Windows w/ GHC, we have fdToHandle so we+-- Window/WASM w/ GHC, we have fdToHandle so we -- can use our own implementation of mkstemp. import System.IO (Handle)
− src/System/PosixCompat/User.hsc
@@ -1,133 +0,0 @@-{-# LANGUAGE CPP #-}--{-|-This module makes the operations exported by @System.Posix.User@-available on all platforms. On POSIX systems it re-exports operations from-@System.Posix.User@. On other platforms it provides dummy implementations.--}-module System.PosixCompat.User (- -- * User environment- -- ** Querying the user environment- getRealUserID- , getRealGroupID- , getEffectiveUserID- , getEffectiveGroupID- , getGroups- , getLoginName- , getEffectiveUserName-- -- *** The group database- , GroupEntry(..)- , getGroupEntryForID- , getGroupEntryForName- , getAllGroupEntries-- -- *** The user database- , UserEntry(..)- , getUserEntryForID- , getUserEntryForName- , getAllUserEntries-- -- ** Modifying the user environment- , setUserID- , setGroupID- ) where--#ifndef mingw32_HOST_OS--#include "HsUnixCompat.h"--import System.Posix.User--#if __GLASGOW_HASKELL__<605-getAllGroupEntries :: IO [GroupEntry]-getAllGroupEntries = return []--getAllUserEntries :: IO [UserEntry]-getAllUserEntries = return []-#endif--#else /* Portable implementation */--import System.IO.Error-import System.PosixCompat.Types--unsupported :: String -> IO a-unsupported f = ioError $ mkIOError illegalOperationErrorType x Nothing Nothing- where x = "System.PosixCompat.User." ++ f ++ ": not supported"---- -------------------------------------------------------------------------------- User environment--getRealUserID :: IO UserID-getRealUserID = unsupported "getRealUserID"--getRealGroupID :: IO GroupID-getRealGroupID = unsupported "getRealGroupID"--getEffectiveUserID :: IO UserID-getEffectiveUserID = unsupported "getEffectiveUserID"--getEffectiveGroupID :: IO GroupID-getEffectiveGroupID = unsupported "getEffectiveGroupID"--getGroups :: IO [GroupID]-getGroups = return []--getLoginName :: IO String-getLoginName = unsupported "getLoginName"--setUserID :: UserID -> IO ()-setUserID _ = return ()--setGroupID :: GroupID -> IO ()-setGroupID _ = return ()---- -------------------------------------------------------------------------------- User names--getEffectiveUserName :: IO String-getEffectiveUserName = unsupported "getEffectiveUserName"---- -------------------------------------------------------------------------------- The group database--data GroupEntry = GroupEntry- { groupName :: String- , groupPassword :: String- , groupID :: GroupID- , groupMembers :: [String]- } deriving (Show, Read, Eq)--getGroupEntryForID :: GroupID -> IO GroupEntry-getGroupEntryForID _ = unsupported "getGroupEntryForID"--getGroupEntryForName :: String -> IO GroupEntry-getGroupEntryForName _ = unsupported "getGroupEntryForName"--getAllGroupEntries :: IO [GroupEntry]-getAllGroupEntries = return []---- -------------------------------------------------------------------------------- The user database (pwd.h)--data UserEntry = UserEntry- { userName :: String- , userPassword :: String- , userID :: UserID- , userGroupID :: GroupID- , userGecos :: String- , homeDirectory :: String- , userShell :: String- } deriving (Show, Read, Eq)--getUserEntryForID :: UserID -> IO UserEntry-getUserEntryForID _ = unsupported "getUserEntryForID"--getUserEntryForName :: String -> IO UserEntry-getUserEntryForName _ = unsupported "getUserEntryForName"--getAllUserEntries :: IO [UserEntry]-getAllUserEntries = return []--#endif
+ tests/ProcessSpec.hs view
@@ -0,0 +1,12 @@+module ProcessSpec (processSpec) where++import System.PosixCompat+import Test.HUnit+import Test.Hspec++processSpec :: Spec+processSpec = do+ describe "getProcessID" $ do+ it "should work on Windows and Unix" $ do+ pid <- getProcessID+ assert $ pid > 0
tests/main.hs view
@@ -2,6 +2,7 @@ import MkstempSpec import LinksSpec+import ProcessSpec import Test.Hspec @@ -9,3 +10,4 @@ main = hspec $ do mkstempSpec linksSpec+ processSpec
unix-compat.cabal view
@@ -1,148 +1,110 @@+cabal-version: 1.18 name: unix-compat-version: 0.6+version: 0.7.4.1 synopsis: Portable POSIX-compatibility layer. description: This package provides portable implementations of parts of the unix package. This package re-exports the unix package when available. When it isn't available, portable implementations are used. -homepage: http://github.com/jacobstanley/unix-compat+homepage: https://github.com/haskell-pkg-janitors/unix-compat license: BSD3 license-file: LICENSE author: Björn Bringert, Duncan Coutts, Jacob Stanley, Bryan O'Sullivan-maintainer: Jacob Stanley <jacob@stanley.io>+maintainer: https://github.com/haskell-pkg-janitors category: System build-type: Simple-cabal-version: >= 1.10 -extra-source-files:+tested-with:+ GHC == 9.14.1+ GHC == 9.12.2+ GHC == 9.10.2+ GHC == 9.8.4+ GHC == 9.6.7+ GHC == 9.4.8+ GHC == 9.2.8+ GHC == 9.0.2+ GHC == 8.10.7+ GHC == 8.8.4+ GHC == 8.6.5+ GHC == 8.4.4+ GHC == 8.2.2+ GHC == 8.0.2++extra-doc-files: CHANGELOG.md source-repository head type: git- location: git@github.com:jacobstanley/unix-compat.git--flag old-time- description: build against old-time package- default: False+ location: https://github.com/haskell-pkg-janitors/unix-compat.git Library- default-language: Haskell2010 hs-source-dirs: src- ghc-options: -Wall- build-depends: base == 4.* exposed-modules: System.PosixCompat System.PosixCompat.Extensions System.PosixCompat.Files+ System.PosixCompat.Process System.PosixCompat.Temp System.PosixCompat.Time System.PosixCompat.Types System.PosixCompat.Unistd- System.PosixCompat.User + build-depends: base >= 4.9 && < 5+ if os(windows) c-sources: cbits/HsUname.c cbits/mktemp.c extra-libraries: msvcrt- build-depends: Win32 >= 2.5.0.0- build-depends: filepath >= 1.0 && < 1.5-- if flag(old-time)- build-depends: old-time >= 1.0.0.0 && < 1.2.0.0- cpp-options: -DOLD_TIME-- if impl(ghc < 7)- build-depends: directory == 1.0.*- cpp-options: -DDIRECTORY_1_0- else- build-depends: directory == 1.1.*- else- build-depends: time >= 1.0 && < 1.13- build-depends: directory >= 1.3.1 && < 1.4+ build-depends: Win32 >= 2.5.0.0 && < 3+ build-depends: directory >= 1.3.1 && < 1.4+ build-depends: filepath >= 1.4.1.0 && < 1.6+ build-depends: time >= 1.6.0.1 && < 2 other-modules: System.PosixCompat.Internal.Time else- build-depends: unix >= 2.6 && < 2.9- include-dirs: include- includes: HsUnixCompat.h- install-includes: HsUnixCompat.h- c-sources: cbits/HsUnixCompat.c+ build-depends: unix >= 2.7.2.0 && < 2.9+ if arch(wasm32)+ c-sources: cbits/mktemp.c+ else+ include-dirs: include+ includes: HsUnixCompat.h+ install-includes: HsUnixCompat.h+ c-sources: cbits/HsUnixCompat.c if os(solaris) cc-options: -DSOLARIS -Test-Suite unix-compat-testsuite default-language: Haskell2010+ ghc-options:+ -Wall+ -Wcompat++Test-Suite unix-compat-testsuite type: exitcode-stdio-1.0 hs-source-dirs: tests- ghc-options: -Wall main-is: main.hs other-modules: MkstempSpec LinksSpec-- -- ghc-options:- -- -Wall- -- -fwarn-tabs- -- -funbox-strict-fields- -- -threaded- -- -fno-warn-unused-do-bind- -- -fno-warn-type-defaults-- -- extensions:- -- OverloadedStrings- -- ExtendedDefaultRules-- -- if flag(lifted)- -- cpp-options: -DLIFTED+ ProcessSpec build-depends: unix-compat- , base == 4.*+ , base , monad-parallel- , hspec+ , hspec >= 2.5.5 , HUnit- , directory- , extra+ , directory >= 1.3.1.0+ -- directory-1.3.1.0 adds createFileLink , temporary - if os(windows)- -- c-sources:- -- cbits/HsUname.c- -- cbits/mktemp.c-- -- extra-libraries: msvcrt- -- build-depends: Win32 >= 2.5.0.0-- if flag(old-time)- build-depends: old-time >= 1.0.0.0 && < 1.2.0.0- cpp-options: -DOLD_TIME-- if impl(ghc < 7)- build-depends: directory == 1.0.*- cpp-options: -DDIRECTORY_1_0- else- build-depends: directory == 1.1.*- else- build-depends: time >= 1.0 && < 1.13- build-depends: directory >= 1.3.1 && < 1.4-- -- other-modules:- -- System.PosixCompat.Internal.Time-- else- -- build-depends: unix >= 2.4 && < 2.9- -- include-dirs: include- -- includes: HsUnixCompat.h- -- install-includes: HsUnixCompat.h- -- c-sources: cbits/HsUnixCompat.c- if os(solaris)- cc-options: -DSOLARIS-- build-depends: directory >= 1.3.1 && < 1.4+ default-language: Haskell2010+ ghc-options:+ -Wall+ -Wcompat