packages feed

unix 2.8.0.0 → 2.8.1.0

raw patch · 22 files changed

+312/−55 lines, 22 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ System.Posix.Semaphore: semWaitInterruptible :: Semaphore -> IO Bool

Files

System/Posix/Directory.hsc view
@@ -49,7 +49,6 @@   ) where  import Data.Maybe-import System.IO.Error import System.Posix.Error import System.Posix.Types import Foreign@@ -157,18 +156,16 @@ --   the current working directory to @dir@. changeWorkingDirectory :: FilePath -> IO () changeWorkingDirectory path =-  modifyIOError (`ioeSetFileName` path) $-    withFilePath path $ \s ->-       throwErrnoIfMinus1Retry_ "changeWorkingDirectory" (c_chdir s)+  withFilePath path $ \s ->+     throwErrnoPathIfMinus1Retry_ "changeWorkingDirectory" path (c_chdir s)  foreign import ccall unsafe "chdir"    c_chdir :: CString -> IO CInt  removeDirectory :: FilePath -> IO () removeDirectory path =-  modifyIOError (`ioeSetFileName` path) $-    withFilePath path $ \s ->-       throwErrnoIfMinus1Retry_ "removeDirectory" (c_rmdir s)+  withFilePath path $ \s ->+     throwErrnoPathIfMinus1Retry_ "removeDirectory" path (c_rmdir s)  foreign import ccall unsafe "rmdir"    c_rmdir :: CString -> IO CInt
System/Posix/Directory/ByteString.hsc view
@@ -49,7 +49,6 @@   ) where  import Data.Maybe-import System.IO.Error import System.Posix.Types import Foreign import Foreign.C@@ -158,18 +157,16 @@ --   the current working directory to @dir@. changeWorkingDirectory :: RawFilePath -> IO () changeWorkingDirectory path =-  modifyIOError (`ioeSetFileName` (BC.unpack path)) $-    withFilePath path $ \s ->-       throwErrnoIfMinus1Retry_ "changeWorkingDirectory" (c_chdir s)+  withFilePath path $ \s ->+     throwErrnoPathIfMinus1Retry_ "changeWorkingDirectory" path (c_chdir s)  foreign import ccall unsafe "chdir"    c_chdir :: CString -> IO CInt  removeDirectory :: RawFilePath -> IO () removeDirectory path =-  modifyIOError (`ioeSetFileName` BC.unpack path) $-    withFilePath path $ \s ->-       throwErrnoIfMinus1Retry_ "removeDirectory" (c_rmdir s)+  withFilePath path $ \s ->+     throwErrnoPathIfMinus1Retry_ "removeDirectory" path (c_rmdir s)  foreign import ccall unsafe "rmdir"    c_rmdir :: CString -> IO CInt
System/Posix/Directory/Common.hsc view
@@ -36,6 +36,11 @@ import Foreign hiding (void) import Foreign.C +#if !defined(HAVE_FCHDIR)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+ newtype DirStream = DirStream (Ptr CDir)  data {-# CTYPE "DIR" #-} CDir@@ -111,9 +116,19 @@   c_telldir :: Ptr CDir -> IO CLong #endif +#if defined(HAVE_FCHDIR)+ changeWorkingDirectoryFd :: Fd -> IO () changeWorkingDirectoryFd (Fd fd) =   throwErrnoIfMinus1Retry_ "changeWorkingDirectoryFd" (c_fchdir fd)  foreign import ccall unsafe "fchdir"   c_fchdir :: CInt -> IO CInt++#else++{-# WARNING changeWorkingDirectoryFd "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_FCHDIR@)" #-}+changeWorkingDirectoryFd :: Fd -> IO ()+changeWorkingDirectoryFd _ = ioError (ioeSetLocation unsupportedOperation "changeWorkingDirectoryFd")++#endif // HAVE_FCHDIR
System/Posix/Directory/PosixPath.hsc view
@@ -46,15 +46,11 @@    changeWorkingDirectoryFd,   ) where -import System.IO.Error import System.Posix.Types import Foreign import Foreign.C  import System.OsPath.Types-import GHC.IO.Encoding.UTF8 ( mkUTF8 )-import GHC.IO.Encoding.Failure ( CodingFailureMode(..) )-import System.OsPath.Posix import System.Posix.Directory hiding (createDirectory, openDirStream, readDirStream, getWorkingDirectory, changeWorkingDirectory, removeDirectory) import qualified System.Posix.Directory.Common as Common import System.Posix.PosixPath.FilePath@@ -145,22 +141,16 @@ --   the current working directory to @dir@. changeWorkingDirectory :: PosixPath -> IO () changeWorkingDirectory path =-  modifyIOError (`ioeSetFileName` (_toStr path)) $-    withFilePath path $ \s ->-       throwErrnoIfMinus1Retry_ "changeWorkingDirectory" (c_chdir s)+  withFilePath path $ \s ->+     throwErrnoPathIfMinus1Retry_ "changeWorkingDirectory" path (c_chdir s)  foreign import ccall unsafe "chdir"    c_chdir :: CString -> IO CInt  removeDirectory :: PosixPath -> IO () removeDirectory path =-  modifyIOError (`ioeSetFileName` _toStr path) $-    withFilePath path $ \s ->-       throwErrnoIfMinus1Retry_ "removeDirectory" (c_rmdir s)+  withFilePath path $ \s ->+     throwErrnoPathIfMinus1Retry_ "removeDirectory" path (c_rmdir s)  foreign import ccall unsafe "rmdir"    c_rmdir :: CString -> IO CInt--_toStr :: PosixPath -> String-_toStr fp = either (error . show) id $ decodeWith (mkUTF8 TransliterateCodingFailure) fp-
System/Posix/DynamicLinker/Module.hsc view
@@ -56,6 +56,7 @@  #include "HsUnix.h" +import Prelude hiding (head, tail) import System.Posix.DynamicLinker import System.Posix.DynamicLinker.Common import Foreign.Ptr      ( Ptr, nullPtr, FunPtr )@@ -101,9 +102,10 @@ withModule mdir file flags p = do   let modPath = case mdir of                   Nothing -> file-                  Just dir  -> dir ++ if ((head (reverse dir)) == '/')-                                       then file-                                       else ('/':file)+                  Just dir  -> dir ++ case unsnoc dir of+                    Just (_, '/') -> file+                    Just{}        -> '/' : file+                    Nothing       -> error "System.Posix.DynamicLinker.Module.withModule: directory should not be Just \"\", pass Nothing instead"   modu <- moduleOpen modPath flags   result <- p modu   moduleClose modu@@ -115,3 +117,10 @@             -> (Module -> IO a)             -> IO () withModule_ dir file flags p = withModule dir file flags p >>= \ _ -> return ()++-- Dual to 'Data.List.uncons'.+unsnoc :: [a] -> Maybe ([a], a)+unsnoc = foldr go Nothing+  where+    go x Nothing = Just ([], x)+    go x (Just (xs, lst)) = Just (x : xs, lst)
System/Posix/DynamicLinker/Prim.hsc view
@@ -1,3 +1,4 @@+{-# LANGUAGE CApiFFI #-} {-# LANGUAGE Trustworthy #-} {-# OPTIONS_GHC -Wno-trustworthy-safe #-} @@ -84,10 +85,17 @@   | RTLD_LOCAL     deriving (Show, Read) -foreign import ccall unsafe "dlopen" c_dlopen :: CString -> CInt -> IO (Ptr ())+#if defined(HAVE_DLFCN_H)+foreign import capi safe "dlfcn.h dlopen" c_dlopen :: CString -> CInt -> IO (Ptr ())+foreign import capi unsafe "dlfcn.h dlsym"  c_dlsym  :: Ptr () -> CString -> IO (FunPtr a)+foreign import capi unsafe "dlfcn.h dlerror" c_dlerror :: IO CString+foreign import capi safe "dlfcn.h dlclose" c_dlclose :: (Ptr ()) -> IO CInt+#else+foreign import ccall safe "dlopen" c_dlopen :: CString -> CInt -> IO (Ptr ()) foreign import ccall unsafe "dlsym"  c_dlsym  :: Ptr () -> CString -> IO (FunPtr a) foreign import ccall unsafe "dlerror" c_dlerror :: IO CString-foreign import ccall unsafe "dlclose" c_dlclose :: (Ptr ()) -> IO CInt+foreign import ccall safe "dlclose" c_dlclose :: (Ptr ()) -> IO CInt+#endif // HAVE_DLFCN_H  packRTLDFlags :: [RTLDFlags] -> CInt packRTLDFlags flags = foldl (\ s f -> (packRTLDFlag f) .|. s) 0 flags
System/Posix/Files.hsc view
@@ -108,7 +108,7 @@  import Data.Time.Clock.POSIX (POSIXTime) -#if !defined(HAVE_MKNOD)+#if !defined(HAVE_MKNOD) || !defined(HAVE_CHOWN) import System.IO.Error ( ioeSetLocation ) import GHC.IO.Exception ( unsupportedOperation ) #endif@@ -323,6 +323,8 @@ -- ----------------------------------------------------------------------------- -- chown() +#if defined(HAVE_CHOWN)+ -- | @setOwnerAndGroup path uid gid@ changes the owner and group of @path@ to -- @uid@ and @gid@, respectively. --@@ -336,6 +338,14 @@  foreign import ccall unsafe "chown"   c_chown :: CString -> CUid -> CGid -> IO CInt++#else++{-# WARNING setOwnerAndGroup "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_CHOWN@)" #-}+setOwnerAndGroup :: FilePath -> UserID -> GroupID -> IO ()+setOwnerAndGroup _ _ _ = ioError (ioeSetLocation unsupportedOperation "setOwnerAndGroup")++#endif // HAVE_CHOWN  #if HAVE_LCHOWN -- | Acts as 'setOwnerAndGroup' but does not follow symlinks (and thus
System/Posix/Files/ByteString.hsc view
@@ -109,7 +109,7 @@  import Data.Time.Clock.POSIX (POSIXTime) -#if !defined(HAVE_MKNOD)+#if !defined(HAVE_MKNOD) || !defined(HAVE_CHOWN) import System.IO.Error ( ioeSetLocation ) import GHC.IO.Exception ( unsupportedOperation ) #endif@@ -319,6 +319,8 @@ -- ----------------------------------------------------------------------------- -- chown() +#if defined(HAVE_CHOWN)+ -- | @setOwnerAndGroup path uid gid@ changes the owner and group of @path@ to -- @uid@ and @gid@, respectively. --@@ -332,6 +334,14 @@  foreign import ccall unsafe "chown"   c_chown :: CString -> CUid -> CGid -> IO CInt++#else++{-# WARNING setOwnerAndGroup "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_CHOWN@)" #-}+setOwnerAndGroup :: RawFilePath -> UserID -> GroupID -> IO ()+setOwnerAndGroup _ _ _ = ioError (ioeSetLocation unsupportedOperation "setOwnerAndGroup")++#endif // HAVE_CHOWN  #if HAVE_LCHOWN -- | Acts as 'setOwnerAndGroup' but does not follow symlinks (and thus
System/Posix/Files/Common.hsc view
@@ -1,3 +1,4 @@+{-# LANGUAGE CApiFFI #-} {-# LANGUAGE Trustworthy #-}  -----------------------------------------------------------------------------@@ -97,6 +98,11 @@ import Foreign.Ptr import Foreign.Storable +#if !defined(HAVE_FCHMOD) || !defined(HAVE_CHOWN)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+ -- ----------------------------------------------------------------------------- -- POSIX file modes @@ -207,6 +213,8 @@ socketMode :: FileMode socketMode = (#const S_IFSOCK) +#if defined(HAVE_FCHMOD)+ -- | @setFdMode fd mode@ acts like 'setFileMode' but uses a file descriptor -- @fd@ instead of a 'FilePath'. --@@ -218,6 +226,14 @@ foreign import ccall unsafe "fchmod"   c_fchmod :: CInt -> CMode -> IO CInt +#else++{-# WARNING setFdMode "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_FCHMOD@)" #-}+setFdMode :: Fd -> FileMode -> IO ()+setFdMode _ _ = ioError (ioeSetLocation unsupportedOperation "setFdMode")++#endif // HAVE_FCHMOD+ -- | @setFileCreationMask mode@ sets the file mode creation mask to @mode@. -- Modes set by this operation are subtracted from files and directories upon -- creation. The previous file creation mask is returned.@@ -452,12 +468,12 @@ #endif  #ifdef HAVE_UTIMENSAT-foreign import ccall unsafe "utimensat"+foreign import capi unsafe "sys/stat.h utimensat"     c_utimensat :: CInt -> CString -> Ptr CTimeSpec -> CInt -> IO CInt #endif  #if HAVE_FUTIMENS-foreign import ccall unsafe "futimens"+foreign import capi unsafe "sys/stat.h futimens"     c_futimens :: CInt -> Ptr CTimeSpec -> IO CInt #endif @@ -480,16 +496,16 @@     (sec, frac) = if (frac' < 0) then (sec' - 1, frac' + 1) else (sec', frac')     (sec', frac') = properFraction $ toRational t -foreign import ccall unsafe "utimes"+foreign import capi unsafe "sys/time.h utimes"     c_utimes :: CString -> Ptr CTimeVal -> IO CInt  #ifdef HAVE_LUTIMES-foreign import ccall unsafe "lutimes"+foreign import capi unsafe "sys/time.h lutimes"     c_lutimes :: CString -> Ptr CTimeVal -> IO CInt #endif  #if HAVE_FUTIMES-foreign import ccall unsafe "futimes"+foreign import capi unsafe "sys/time.h futimes"     c_futimes :: CInt -> Ptr CTimeVal -> IO CInt #endif @@ -539,6 +555,8 @@ -- ----------------------------------------------------------------------------- -- fchown() +#if defined(HAVE_CHOWN)+ -- | Acts as 'setOwnerAndGroup' but uses a file descriptor instead of a -- 'FilePath'. --@@ -549,6 +567,14 @@  foreign import ccall unsafe "fchown"   c_fchown :: CInt -> CUid -> CGid -> IO CInt++#else++{-# WARNING setFdOwnerAndGroup "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_CHOWN@)" #-}+setFdOwnerAndGroup :: Fd -> UserID -> GroupID -> IO ()+setFdOwnerAndGroup _ _ _ = ioError (ioeSetLocation unsupportedOperation "setFdOwnerAndGroup")++#endif // HAVE_CHOWN  -- ----------------------------------------------------------------------------- -- ftruncate()
System/Posix/Files/PosixString.hsc view
@@ -107,6 +107,11 @@  import Data.Time.Clock.POSIX (POSIXTime) +#if !defined(HAVE_MKNOD) || !defined(HAVE_CHOWN)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif+ -- ----------------------------------------------------------------------------- -- chmod() @@ -205,6 +210,13 @@   withFilePath name $ \s ->     throwErrnoPathIfMinus1_ "createNamedPipe" name (c_mkfifo s mode) +#if !defined(HAVE_MKNOD)++{-# WARNING createDevice "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_MKNOD@)" #-}+createDevice :: PosixPath -> FileMode -> DeviceID -> IO ()+createDevice _ _ _ = ioError (ioeSetLocation unsupportedOperation "createDevice")++#else -- | @createDevice path mode dev@ creates either a regular or a special file -- depending on the value of @mode@ (and @dev@).  @mode@ will normally be either -- 'blockSpecialMode' or 'characterSpecialMode'.  May fail with@@ -221,6 +233,8 @@ foreign import capi unsafe "HsUnix.h mknod"   c_mknod :: CString -> CMode -> CDev -> IO CInt +#endif // HAVE_MKNOD+ -- ----------------------------------------------------------------------------- -- Hard links @@ -302,6 +316,8 @@ -- ----------------------------------------------------------------------------- -- chown() +#if defined(HAVE_CHOWN)+ -- | @setOwnerAndGroup path uid gid@ changes the owner and group of @path@ to -- @uid@ and @gid@, respectively. --@@ -315,6 +331,14 @@  foreign import ccall unsafe "chown"   c_chown :: CString -> CUid -> CGid -> IO CInt++#else++{-# WARNING setOwnerAndGroup "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_CHOWN@)" #-}+setOwnerAndGroup :: PosixPath -> UserID -> GroupID -> IO ()+setOwnerAndGroup _ _ _ = ioError (ioeSetLocation unsupportedOperation "setOwnerAndGroup")++#endif // HAVE_CHOWN  #if HAVE_LCHOWN -- | Acts as 'setOwnerAndGroup' but does not follow symlinks (and thus
System/Posix/Semaphore.hsc view
@@ -1,5 +1,6 @@ {-# LANGUAGE Safe #-} {-# LANGUAGE CApiFFI #-}+{-# LANGUAGE InterruptibleFFI #-} ----------------------------------------------------------------------------- -- | -- Module      :  System.Posix.Semaphore@@ -16,7 +17,7 @@  module System.Posix.Semaphore     (OpenSemFlags(..), Semaphore(),-     semOpen, semUnlink, semWait, semTryWait, semThreadWait,+     semOpen, semUnlink, semWait, semWaitInterruptible, semTryWait, semThreadWait,      semPost, semGetValue)     where @@ -39,6 +40,13 @@ import Foreign.Storable #endif +#if __GLASGOW_HASKELL__ >= 902+import System.Posix.Internals (hostIsThreaded)+#else+hostIsThreaded :: Bool+hostIsThreaded = False+#endif+ data OpenSemFlags = OpenSemFlags { semCreate :: Bool,                                    -- ^ If true, create the semaphore if it                                    --   does not yet exist.@@ -79,6 +87,20 @@     where semWait' sem = throwErrnoIfMinus1Retry_ "semWait" $                          sem_wait sem +-- | Lock the semaphore, blocking until it becomes available.+--+-- Unlike 'semWait', this wait operation can be interrupted with+-- an asynchronous exception (e.g. a call to 'throwTo' from another thread).+semWaitInterruptible :: Semaphore -> IO Bool+semWaitInterruptible (Semaphore fptr) = withForeignPtr fptr semWait'+    where semWait' sem =+            do res <- sem_wait_interruptible sem+               if res == 0 then return True+                           else do errno <- getErrno+                                   if errno == eINTR+                                     then return False+                                     else throwErrno "semWaitInterrruptible"+ -- | Attempt to lock the semaphore without blocking.  Immediately return --   False if it is not available. semTryWait :: Semaphore -> IO Bool@@ -96,9 +118,15 @@ --   semWait, this will block only the current thread rather than the --   entire process. semThreadWait :: Semaphore -> IO ()-semThreadWait sem = do res <- semTryWait sem-                       (if res then return ()-                        else ( do { yield; semThreadWait sem } ))+semThreadWait sem+  -- N.B. semWait can be safely used in the case of the threaded runtime, where+  -- the safe foreign call will be performed in its own thread, thereby not+  -- blocking the process.+  | hostIsThreaded = semWait sem+  | otherwise = do+      res <- semTryWait sem+      if res then return ()+             else do yield >> semThreadWait sem  -- | Unlock the semaphore. semPost :: Semaphore -> IO ()@@ -132,9 +160,10 @@         sem_close :: Ptr () -> IO CInt foreign import capi safe "semaphore.h sem_unlink"         sem_unlink :: CString -> IO CInt- foreign import capi safe "semaphore.h sem_wait"         sem_wait :: Ptr () -> IO CInt+foreign import capi interruptible "semaphore.h sem_wait"+        sem_wait_interruptible :: Ptr () -> IO CInt foreign import capi safe "semaphore.h sem_trywait"         sem_trywait :: Ptr () -> IO CInt foreign import capi safe "semaphore.h sem_post"
System/Posix/Signals.hsc view
@@ -101,7 +101,7 @@ import Foreign.Marshal import Foreign.Ptr import Foreign.Storable-#if !defined(HAVE_SIGNAL_H)+#if !defined(HAVE_SIGNAL_H) || !defined(HAVE_ALARM) import System.IO.Error ( ioeSetLocation ) import GHC.IO.Exception ( unsupportedOperation ) #endif
System/Posix/Temp/PosixString.hsc view
@@ -35,6 +35,19 @@ import System.Posix.IO.PosixString import System.Posix.Types +#if !defined(HAVE_MKSTEMP)+import System.IO.Error ( ioeSetLocation )+import GHC.IO.Exception ( unsupportedOperation )+#endif++#if !defined(HAVE_MKSTEMP)++{-# WARNING mkstemp "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_MKSTEMP@)" #-}+mkstemp :: PosixString -> IO (PosixPath, Handle)+mkstemp _ = ioError (ioeSetLocation unsupportedOperation "mkstemp")++#else+ foreign import capi unsafe "HsUnix.h mkstemp"   c_mkstemp :: CString -> IO CInt @@ -53,6 +66,8 @@     name <- peekFilePath ptr     h <- fdToHandle (Fd fd)     return (name, h)++#endif // HAVE_MKSTEMP  #if HAVE_MKSTEMPS foreign import capi unsafe "HsUnix.h mkstemps"
System/Posix/Terminal/Common.hsc view
@@ -216,13 +216,16 @@    | ReturnMeansLF              -- ^ @ONLRET@ - (XSI) NL performs CR function                                 --                                 -- @since 2.8.0.0+#ifdef TAB0    | TabDelayMask0              -- ^ @TABDLY(TAB0)@ - (XSI) Select horizontal-tab delays: type 0                                 --                                 -- @since 2.8.0.0+#endif+#ifdef TAB3    | TabDelayMask3              -- ^ @TABDLY(TAB3)@ - (XSI) Select horizontal-tab delays: type 3                                 --                                 -- @since 2.8.0.0-+#endif         -- control flags    | LocalMode                  -- ^ @CLOCAL@ - Ignore modem status lines    | ReadEnable                 -- ^ @CREAD@ - Enable receiver@@ -289,8 +292,12 @@ withoutMode termios OutputMapCRtoLF = clearOutputFlag (#const OCRNL) termios withoutMode termios NoCRAtColumnZero = clearOutputFlag (#const ONOCR) termios withoutMode termios ReturnMeansLF = clearOutputFlag (#const ONLRET) termios+#ifdef TAB0 withoutMode termios TabDelayMask0 = clearOutputFlag (#const TAB0) termios+#endif+#ifdef TAB3 withoutMode termios TabDelayMask3 = clearOutputFlag (#const TAB3) termios+#endif withoutMode termios LocalMode = clearControlFlag (#const CLOCAL) termios withoutMode termios ReadEnable = clearControlFlag (#const CREAD) termios withoutMode termios TwoStopBits = clearControlFlag (#const CSTOPB) termios@@ -325,8 +332,12 @@ withMode termios OutputMapCRtoLF = setOutputFlag (#const OCRNL) termios withMode termios NoCRAtColumnZero = setOutputFlag (#const ONOCR) termios withMode termios ReturnMeansLF = setOutputFlag (#const ONLRET) termios+#ifdef TAB0 withMode termios TabDelayMask0 = setOutputFlag (#const TAB0) termios+#endif+#ifdef TAB3 withMode termios TabDelayMask3 = setOutputFlag (#const TAB3) termios+#endif withMode termios LocalMode = setControlFlag (#const CLOCAL) termios withMode termios ReadEnable = setControlFlag (#const CREAD) termios withMode termios TwoStopBits = setControlFlag (#const CSTOPB) termios@@ -361,8 +372,12 @@ terminalMode OutputMapCRtoLF = testOutputFlag (#const OCRNL) terminalMode NoCRAtColumnZero = testOutputFlag (#const ONOCR) terminalMode ReturnMeansLF = testOutputFlag (#const ONLRET)+#ifdef TAB0 terminalMode TabDelayMask0 = testOutputFlag (#const TAB0)+#endif+#ifdef TAB3 terminalMode TabDelayMask3 = testOutputFlag (#const TAB3)+#endif terminalMode LocalMode = testControlFlag (#const CLOCAL) terminalMode ReadEnable = testControlFlag (#const CREAD) terminalMode TwoStopBits = testControlFlag (#const CSTOPB)
changelog.md view
@@ -1,5 +1,32 @@ # Changelog for [`unix` package](http://hackage.haskell.org/package/unix) +## 2.8.1.0 *Feb 2023*+  * Fix build if HAVE_ALARM is undefined++  * Add missing autoconf checks for chown/fchdir/fchmod++  * Make TABX constructors and code conditional on underlying #defines++  * Bump bounds to accomodate base-4.18++  * Add semWaitInterruptible++  * semaphore: Teach semThreadWait to use semWait with threaded RTS++  * make the foreign imports of dlopen & dlclose safe++  * do not use capi for dlfcn.h stuff under wasm-wasi++  * Use capi for syscalls that break under musl's handling of 64-bit `time_t`++  * Replace `last` with `unsnoc`++  * Avoid Data.List.{head,tail}++  * Consistently use `throwErrnoPathIf*`++  * Fix WASI build+ ## 2.8.0.0 *August 2022*   * Use ByteString for GroupEntry/UserEntry 
configure view
@@ -3824,7 +3824,7 @@     We can't simply define LARGE_OFF_T to be 9223372036854775807,     since some C++ compilers masquerading as C compilers     incorrectly reject 9223372036854775807.  */-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 		       && LARGE_OFF_T % 2147483647 == 1) 		      ? 1 : -1];@@ -3870,7 +3870,7 @@     We can't simply define LARGE_OFF_T to be 9223372036854775807,     since some C++ compilers masquerading as C compilers     incorrectly reject 9223372036854775807.  */-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 		       && LARGE_OFF_T % 2147483647 == 1) 		      ? 1 : -1];@@ -3894,7 +3894,7 @@     We can't simply define LARGE_OFF_T to be 9223372036854775807,     since some C++ compilers masquerading as C compilers     incorrectly reject 9223372036854775807.  */-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 		       && LARGE_OFF_T % 2147483647 == 1) 		      ? 1 : -1];@@ -3939,7 +3939,7 @@     We can't simply define LARGE_OFF_T to be 9223372036854775807,     since some C++ compilers masquerading as C compilers     incorrectly reject 9223372036854775807.  */-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 		       && LARGE_OFF_T % 2147483647 == 1) 		      ? 1 : -1];@@ -3963,7 +3963,7 @@     We can't simply define LARGE_OFF_T to be 9223372036854775807,     since some C++ compilers masquerading as C compilers     incorrectly reject 9223372036854775807.  */-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))   int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 		       && LARGE_OFF_T % 2147483647 == 1) 		      ? 1 : -1];@@ -4230,6 +4230,18 @@ if test "x$ac_cv_func_times" = xyes; then :   cat >>confdefs.h <<_ACEOF #define HAVE_TIMES 1+_ACEOF++fi+done++for ac_func in chown fchdir fchmod+do :+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :+  cat >>confdefs.h <<_ACEOF+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF  fi
configure.ac view
@@ -42,6 +42,7 @@ AC_CHECK_FUNCS([mkstemp]) AC_CHECK_FUNCS([pipe]) AC_CHECK_FUNCS([times])+AC_CHECK_FUNCS([chown fchdir fchmod])  AC_CHECK_TYPE([struct rlimit],[AC_DEFINE([HAVE_STRUCT_RLIMIT],[1],[HAVE_STRUCT_RLIMIT])],[],[#include <sys/resource.h>]) 
include/HsUnixConfig.h.in view
@@ -105,6 +105,9 @@ /* Define to 1 if you have the <bsd/libutil.h> header file. */ #undef HAVE_BSD_LIBUTIL_H +/* Define to 1 if you have the `chown' function. */+#undef HAVE_CHOWN+ /* Define to 1 if you have the `clearenv' function. */ #undef HAVE_CLEARENV @@ -155,6 +158,12 @@  /* Define to 1 if you have the `execvpe' function. */ #undef HAVE_EXECVPE++/* Define to 1 if you have the `fchdir' function. */+#undef HAVE_FCHDIR++/* Define to 1 if you have the `fchmod' function. */+#undef HAVE_FCHMOD  /* Define to 1 if you have the <fcntl.h> header file. */ #undef HAVE_FCNTL_H
tests/Semaphore001.hs view
@@ -4,6 +4,6 @@  main :: IO () main = do-  sem <- semOpen "/test" OpenSemFlags {semCreate = True, semExclusive = False} stdFileMode 1+  sem <- semOpen "/test-001" OpenSemFlags {semCreate = True, semExclusive = False} stdFileMode 1   semThreadWait sem   semPost sem
+ tests/Semaphore002.hs view
@@ -0,0 +1,15 @@+module Main (main) where++import Control.Concurrent+import System.Posix++main :: IO ()+main = do+  sem <- semOpen "/test-002" OpenSemFlags {semCreate = True, semExclusive = False} stdFileMode 0+  _ <- forkIO $ do+      threadDelay (1000*1000)+      semPost sem++  -- This should succeed after 1 second.+  semThreadWait sem+  semPost sem
+ tests/SemaphoreInterrupt.hs view
@@ -0,0 +1,32 @@+module Main (main) where++import Control.Concurrent+import Control.Monad+import Data.IORef+import System.Posix++main :: IO ()+main = do++  sem <- semOpen "/test-interrupt" OpenSemFlags {semCreate = True, semExclusive = False} stdFileMode 0+  ref <- newIORef False+  _ <- forkIO $ do+    res <- semWaitInterruptible sem+    writeIORef ref res+  threadDelay 100000 -- 100 ms+  semPost sem+  threadDelay 100000 -- 100 ms+  succ1 <- readIORef ref+  unless succ1 $+    error "SemaphoreInterrupt: semWaitInterruptible failed"++  writeIORef ref False+  tid <- forkIO $ do+    res <- semWaitInterruptible sem+    writeIORef ref res+  threadDelay 100000 -- 100 ms+  killThread tid+  threadDelay 100000 -- 100 ms+  succ2 <- readIORef ref+  when succ2 $+    error "SemaphoreInterrupt: semWaitInterruptible not interrupted"
unix.cabal view
@@ -1,6 +1,6 @@ cabal-version:  1.12 name:           unix-version:        2.8.0.0+version:        2.8.1.0 -- NOTE: Don't forget to update ./changelog.md  license:        BSD3@@ -69,7 +69,7 @@         buildable: False      build-depends:-        base        >= 4.10    && < 4.18,+        base        >= 4.10    && < 4.19,         bytestring  >= 0.9.2   && < 0.12,         filepath    >= 1.4.100.0 && < 1.5,         time        >= 1.2     && < 1.13@@ -262,3 +262,19 @@     default-language: Haskell2010     build-depends: base, unix     ghc-options: -Wall++test-suite Semaphore002+    hs-source-dirs: tests+    main-is: Semaphore002.hs+    type: exitcode-stdio-1.0+    default-language: Haskell2010+    build-depends: base, unix+    ghc-options: -Wall -threaded++test-suite SemaphoreInterrupt+    hs-source-dirs: tests+    main-is: SemaphoreInterrupt.hs+    type: exitcode-stdio-1.0+    default-language: Haskell2010+    build-depends: base, unix+    ghc-options: -Wall -threaded