packages feed

posix-api 0.6.0.1 → 0.6.1.0

raw patch · 5 files changed

+75/−11 lines, 5 files

Files

CHANGELOG.md view
@@ -7,6 +7,12 @@  This project adheres to the [Haskell Package Versioning Policy](https://pvp.haskell.org/). +## [0.6.1.0] - 2023-08-14++- Add `uninterruptibleWriteBytesCompletelyErrno`+- Add `writeBytesCompletelyErrno`+- Add `uninterruptibleAccept4_`+ ## [0.6.0.1] - 2023-07-13  - Fix mistake in header file that caused builds to fail
cbits/HaskellPosix.c view
@@ -26,13 +26,15 @@ // way to support providing an offset (without just copying the bytes // into pinned memory) is to use a wrapper. -ssize_t write_offset_loop(int fd, const char *message, HsInt offset, size_t length){+// This returns an error code, not a length of written bytes. The error+// code zero means "no error".+int write_offset_loop(int fd, const char *message, HsInt offset, size_t length){   ssize_t r;   size_t bytesSent;   const char* buf = message + offset;   while(length > 0){     if ((r = write(fd, (const void*)buf, length)) == -1) {-      return (-1);+      return errno;     } else {       bytesSent = (size_t)r;       buf = buf + bytesSent;
posix-api.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: posix-api-version: 0.6.0.1+version: 0.6.1.0 synopsis: posix bindings description:   This library provides a very thin wrapper around POSIX APIs. It can be
src/Linux/Socket.hs view
@@ -12,6 +12,7 @@   , uninterruptibleReceiveMultipleMessageC   , uninterruptibleReceiveMultipleMessageD   , uninterruptibleAccept4+  , uninterruptibleAccept4_     -- * Types   , SocketFlags(..)     -- * Option Names@@ -49,26 +50,28 @@  import Control.Monad (when) import Data.Bits ((.|.))-import Data.Primitive.Addr (Addr(..),plusAddr,nullAddr) import Data.Primitive (MutableByteArray(..),ByteArray(..),MutablePrimArray(..))+import Data.Primitive.Addr (Addr(..),plusAddr,nullAddr) import Data.Primitive.Unlifted.Array (MutableUnliftedArray,UnliftedArray) import Data.Primitive.Unlifted.Array (MutableUnliftedArray_(MutableUnliftedArray))+import Data.Primitive.Unlifted.Array.Primops (MutableUnliftedArray#(MutableUnliftedArray#))+import Data.Void (Void) import Data.Word (Word8) import Foreign.C.Error (Errno,getErrno) import Foreign.C.Types (CInt(..),CSize(..),CUInt(..))+import Foreign.Ptr (nullPtr) import GHC.Exts (Ptr(..),RealWorld,MutableArray#,MutableByteArray#,Addr#,Int(I#)) import GHC.Exts (shrinkMutableByteArray#,touch#,nullAddr#) import GHC.IO (IO(..)) import Linux.Socket.Types (SocketFlags(..)) import Posix.Socket (Type(..),MessageFlags(..),Message(Receive),SocketAddress(..)) import System.Posix.Types (Fd(..),CSsize(..))-import Data.Primitive.Unlifted.Array.Primops (MutableUnliftedArray#(MutableUnliftedArray#)) +import qualified Control.Monad.Primitive as PM import qualified Data.Primitive as PM import qualified Data.Primitive.Unlifted.Array as PM-import qualified Control.Monad.Primitive as PM-import qualified Posix.Socket as S import qualified Linux.Socket.Types as LST+import qualified Posix.Socket as S  foreign import ccall unsafe "sys/socket.h recvmmsg"   c_unsafe_addr_recvmmsg :: Fd@@ -85,6 +88,17 @@                    -> SocketFlags                    -> IO Fd +-- Variant of c_unsafe_ptr_accept4 that uses Ptr instead of MutableByteArray.+-- Currently, we expect that the two pointers are set to NULL.+-- This is only used internally.+foreign import ccall unsafe "sys/socket.h accept4"+  c_unsafe_ptr_accept4 ::+        Fd+     -> Ptr Void -- SocketAddress+     -> Ptr Void -- Ptr CInt+     -> SocketFlags+     -> IO Fd+ foreign import ccall unsafe "HaskellPosix.h recvmmsg_sockaddr_in"   c_unsafe_recvmmsg_sockaddr_in ::        Fd@@ -366,6 +380,19 @@         else pure ()       sockAddr <- PM.unsafeFreezeByteArray sockAddrBuf       pure (Right (sz,SocketAddress sockAddr,r))+    else fmap Left getErrno++-- | Variant of 'uninterruptibleAccept4' that requests that the kernel not+-- include the socket address in its reponse.+uninterruptibleAccept4_ ::+     Fd -- ^ Listening socket+  -> SocketFlags -- ^ Set non-blocking and close-on-exec without extra syscall+  -> IO (Either Errno Fd) -- ^ Connected socket+{-# inline uninterruptibleAccept4_ #-}+uninterruptibleAccept4_ !sock !flags = do+  r <- c_unsafe_ptr_accept4 sock nullPtr nullPtr flags+  if r > (-1)+    then pure (Right r)     else fmap Left getErrno  cintToInt :: CInt -> Int
src/Posix/File.hs view
@@ -1,5 +1,6 @@ {-# language BangPatterns #-} {-# language BinaryLiterals #-}+{-# language LambdaCase #-} {-# language MagicHash #-} {-# language TypeApplications #-} {-# language UnliftedFFITypes #-}@@ -11,6 +12,8 @@   , uninterruptibleWriteByteArray   , uninterruptibleWriteBytes   , uninterruptibleWriteBytesCompletely+  , uninterruptibleWriteBytesCompletelyErrno+  , writeBytesCompletelyErrno   , uninterruptibleOpen   , uninterruptibleOpenMode   , writeByteArray@@ -44,7 +47,7 @@ import Assertion (assertByteArrayPinned,assertMutableByteArrayPinned) import Data.Bits ((.&.),(.|.)) import Data.Primitive (ByteArray(..))-import Foreign.C.Error (Errno,getErrno)+import Foreign.C.Error (Errno(Errno),getErrno,eOK) import Foreign.C.String.Managed (ManagedCString(..)) import Foreign.C.Types (CInt(..),CSize(..)) import GHC.Exts (ByteArray#,MutableByteArray#,RealWorld)@@ -76,8 +79,11 @@   c_unsafe_bytearray_write :: Fd -> ByteArray# -> Int -> CSize -> IO CSsize  foreign import ccall unsafe "HaskellPosix.h write_offset_loop"-  c_unsafe_bytearray_write_loop :: Fd -> ByteArray# -> Int -> CSize -> IO CInt+  c_unsafe_bytearray_write_loop :: Fd -> ByteArray# -> Int -> CSize -> IO Errno +foreign import ccall safe "HaskellPosix.h write_offset_loop"+  c_safe_bytearray_write_loop :: Fd -> ByteArray# -> Int -> CSize -> IO Errno+ foreign import ccall safe "HaskellPosix.h write_offset"   c_safe_bytearray_write :: Fd -> ByteArray# -> Int -> CSize -> IO CSsize @@ -137,11 +143,32 @@      Fd -- ^ File descriptor   -> Bytes -- ^ Source bytes   -> IO (Either Errno ())-uninterruptibleWriteBytesCompletely !fd (Bytes (ByteArray buf) off len) =+uninterruptibleWriteBytesCompletely !fd !b = do+  e <- uninterruptibleWriteBytesCompletelyErrno fd b+  if e == eOK+    then pure (Right ())+    else pure (Left e)++-- | Variant of 'uninterruptibleWriteBytesCompletely' that uses errno 0+-- to communicate success.+uninterruptibleWriteBytesCompletelyErrno ::+     Fd -- ^ File descriptor+  -> Bytes -- ^ Source bytes+  -> IO Errno+uninterruptibleWriteBytesCompletelyErrno !fd (Bytes (ByteArray buf) off len) =   c_unsafe_bytearray_write_loop fd buf off (fromIntegral @Int @CSize len)-    >>= errorsFromInt_  -- | Wrapper for @write(2)@ that takes a slice of bytes and an offset.+-- The byte array backing the slice must be pinned.+writeBytesCompletelyErrno ::+     Fd -- ^ File descriptor+  -> Bytes -- ^ Source bytes+  -> IO Errno+writeBytesCompletelyErrno !fd (Bytes buf0 off len) =+  let !(ByteArray buf1) = assertByteArrayPinned buf0+   in c_safe_bytearray_write_loop fd buf1 off (fromIntegral @Int @CSize len)++-- | Wrapper for @write(2)@ that takes a slice of bytes and an offset. -- The byte array backing the slice does not need to be pinned. uninterruptibleWriteBytes ::      Fd -- ^ File descriptor@@ -173,6 +200,8 @@ writeByteArray !fd !buf0 !off !len =   let !(ByteArray buf1) = assertByteArrayPinned buf0    in c_safe_bytearray_write fd buf1 off len >>= errorsFromSize++-- writeByteArrayCompletely ::  -- | Variant of 'writeByteArray' that operates on mutable byte array. -- Uses @safe@ FFI. The byte array must be pinned.