select 0.4 → 0.4.0.1
raw patch · 9 files changed
+52/−55 lines, 9 files
Files
- TODO +7/−0
- example/TestStdin.hs +1/−1
- example/build.sh +6/−6
- select.cabal +7/−11
- src/System/Posix/IO/Select/FdSet.hs +1/−5
- src/System/Posix/IO/Select/FdSet/Internal.hsc +7/−4
- src/System/Posix/IO/Select/FdSet/cbits.c +0/−5
- src/System/Posix/IO/Select/FdSet/cbits.h +1/−1
- src/System/Posix/IO/Select/cbits.c +22/−22
+ TODO view
@@ -0,0 +1,7 @@+* Return the error code specified by errno if select fails. API change, slated+ for 0.5.+* Replace Timeout datatype with Maybe CTimeval. API change, slated for 0.5.+* Move the select EINTR retry code from C to Haskell. Separate out clock_gettime+ into a package of its own. Slated for 0.5?+* Reorder functions to make the documentation more logical.+* Move CTimeval, probably into a package of its own.
example/TestStdin.hs view
@@ -9,7 +9,7 @@ main :: IO () main = do fd <- handleToFd stdin- n <- select'' [fd] [] [] (finite 0 500)+ n <- select'' [fd] [] [] (finite 5 500000) case n of 0 -> print "timeout" -1 -> error "select failed"
example/build.sh view
@@ -6,14 +6,14 @@ cd ../src/System/Posix/IO/Select/FdSet/ hsc2hs Internal.hsc-gcc -DNDEBUG -Wall -std=c99 -c cbits.c+gcc -O2 -Wall -std=c99 -c cbits.c cd ..-gcc -Wall -std=c99 -lrt -c cbits.c+gcc -O2 -Wall -std=c99 -lrt -c cbits.c hsc2hs Types.hsc cd $p -ghc -fforce-recomp -threaded -o stdin-test --make TestStdin.hs -i../src $cobjs-ghc -fforce-recomp -threaded -o fdset-example --make FdSetExample.hs -i../src $cobjs-ghc -fforce-recomp -threaded -o select-example --make SelectExample.hs -i../src $cobjs-ghc -fforce-recomp -threaded -o select-example2 --make SelectExample2.hs -i../src $cobjs+ghc -O2 -fforce-recomp -threaded -o stdin-test --make TestStdin.hs -i../src $cobjs+ghc -O2 -fforce-recomp -threaded -o fdset-example --make FdSetExample.hs -i../src $cobjs+ghc -O2 -fforce-recomp -threaded -o select-example --make SelectExample.hs -i../src $cobjs+ghc -O2 -fforce-recomp -threaded -o select-example2 --make SelectExample2.hs -i../src $cobjs
select.cabal view
@@ -1,5 +1,5 @@ Name: select-Version: 0.4+Version: 0.4.0.1 Synopsis: Wrap the select(2) POSIX function Homepage: http://nonempty.org/software/haskell-select License: BSD3@@ -17,6 +17,12 @@ Description: While tinkering on a project, I frequently found myself having to make FFI calls to @select(2)@. This package provides an interface to that system call. .+ Changed in version 0.4.0.1:+ .+ * Minor internal cleanups.+ .+ * TODO moved to file.+ . Changes in version 0.4: . * Introduce an interface to @fd_set@.@@ -34,16 +40,6 @@ Feedback is welcome. . * This package is far from complete, and should be tested throughly before being relied upon.- .- TODO:- .- * Return the error code specified by errno if @select@ fails.- .- * Possibly move the select retry code from C to Haskell.- .- * Reorder functions to make the documentation more logical.- .- * Use hsc2hs's #const to get preprocessor constants (removes some of FdSet's cbits.c). . /NOTE/: I feel I'm occupying prime namespace realestate with a package name like select. I'll happily let myself be chased away if someone more qualified wants
src/System/Posix/IO/Select/FdSet.hs view
@@ -24,7 +24,6 @@ import Prelude hiding (elem) import qualified System.Posix.IO.Select.FdSet.Internal as I import Foreign-import qualified System.IO.Unsafe as UNSAFE import System.Posix.Types import Misc import Control.Monad@@ -82,10 +81,7 @@ -- | Test if a file descriptor is in range (see introduction). inRange :: Fd -> Bool-inRange fd = fd' >= 0 && fd' < limit- where- fd' = fromIntegral fd- limit = UNSAFE.unsafePerformIO I.c_fd_setsize_wrapper+inRange fd = fd >= 0 && fd < I.c_FD_SETSIZE -- | This file descriptor is at least as large as the largest in the -- set. If no file descriptors have ever been removed from the set,
src/System/Posix/IO/Select/FdSet/Internal.hsc view
@@ -1,8 +1,11 @@ {-# LANGUAGE ForeignFunctionInterface #-} +-- Primed functions work on ForeignPtrs, unprimed work on FdSets. module System.Posix.IO.Select.FdSet.Internal where -import Foreign+import Foreign.ForeignPtr.Safe+import Foreign.Ptr+import Foreign.Marshal.Utils import Foreign.C.Types import System.Posix.Types import Misc@@ -35,6 +38,9 @@ withForeignPtr ptr (\ptr' -> withForeignPtr newPtr (\newPtr' -> copyBytes newPtr' ptr' #{size fd_set})) >> return newPtr +c_FD_SETSIZE :: Fd+c_FD_SETSIZE = #{const FD_SETSIZE}+ foreign import ccall "cbits.h fd_zero_wrapper" c_fd_zero_wrapper :: Ptr () -> IO () @@ -46,6 +52,3 @@ foreign import ccall "cbits.h fd_isset_wrapper" c_fd_isset_wrapper :: CInt -> Ptr () -> IO CInt--foreign import ccall "cbits.h fd_setsize_wrapper"- c_fd_setsize_wrapper :: IO CInt
src/System/Posix/IO/Select/FdSet/cbits.c view
@@ -20,8 +20,3 @@ { FD_ZERO(set); }--int fd_setsize_wrapper()-{- return FD_SETSIZE;-}
src/System/Posix/IO/Select/FdSet/cbits.h view
@@ -6,4 +6,4 @@ int fd_isset_wrapper(int fd, fd_set* set); void fd_set_wrapper(int fd, fd_set* set); void fd_zero_wrapper(fd_set* set);-int fd_setsize_wrapper();+
src/System/Posix/IO/Select/cbits.c view
@@ -50,33 +50,33 @@ #endif if (timeout != NULL) // Case of finite timeouts. {- clock_gettime(CLOCK_MONOTONIC, ¤t);- remaining.tv_sec = stop.tv_sec - current.tv_sec;- remaining.tv_nsec = stop.tv_nsec - current.tv_nsec;+ clock_gettime(CLOCK_MONOTONIC, ¤t);+ remaining.tv_sec = stop.tv_sec - current.tv_sec;+ remaining.tv_nsec = stop.tv_nsec - current.tv_nsec; - while (remaining.tv_nsec > 1000000000)- {- remaining.tv_sec++;- remaining.tv_nsec -= 1000000000;- }- while (remaining.tv_nsec < 0)- {- remaining.tv_sec--;- remaining.tv_nsec += 1000000000;- }- if (remaining.tv_sec < 0)- {- remaining.tv_sec = 0;- remaining.tv_nsec = 0;- }+ while (remaining.tv_nsec > 1000000000)+ {+ remaining.tv_sec++;+ remaining.tv_nsec -= 1000000000;+ }+ while (remaining.tv_nsec < 0)+ {+ remaining.tv_sec--;+ remaining.tv_nsec += 1000000000;+ }+ if (remaining.tv_sec < 0)+ {+ remaining.tv_sec = 0;+ remaining.tv_nsec = 0;+ } #ifndef NDEBUG- printf("C: Was interrupted with %ld s, %ld ns remaining\n", remaining.tv_sec, remaining.tv_nsec);+ printf("C: Was interrupted with %ld s, %ld ns remaining\n", remaining.tv_sec, remaining.tv_nsec); #endif - // Set up for retry.- timeout->tv_sec = remaining.tv_sec;- timeout->tv_usec = remaining.tv_nsec/1000;+ // Set up for retry.+ timeout->tv_sec = remaining.tv_sec;+ timeout->tv_usec = remaining.tv_nsec/1000; } // Set up for retry (also in infinite case). *readfds = readfds_orig;