diff options
author | stolz <unknown> | 2003-06-06 12:49:00 +0000 |
---|---|---|
committer | stolz <unknown> | 2003-06-06 12:49:00 +0000 |
commit | 1c399d00524ed89eef163ec89c9311674e2cccbf (patch) | |
tree | eca9e69b31eafdcbc80c7a7299f2b87a1818f944 | |
parent | 9a3fcfc40fcbb60d61fd3eb4a6d9659d7e027932 (diff) |
[project @ 2003-06-06 12:49:00 by stolz]
Move System.Sendfile to Network.Sendfile:
- Linux can sendfile() to a fd, but BSD couldn't
- sendfile() on Linux is probably now disabled on most builds because of
the LARGEFILE issue
=> Change API to use type Socket
-rw-r--r-- | System/Sendfile.hsc | 133 | ||||
-rw-r--r-- | include/HsUnix.h | 13 |
2 files changed, 1 insertions, 145 deletions
diff --git a/System/Sendfile.hsc b/System/Sendfile.hsc deleted file mode 100644 index 03188ae..0000000 --- a/System/Sendfile.hsc +++ /dev/null @@ -1,133 +0,0 @@ -{-# OPTIONS -fglasgow-exts -cpp #-} ------------------------------------------------------------------------------ --- | --- Module : System.Sendfile --- Copyright : (c) Volker Stolz 2003 <vs@foldr.org> --- License : BSD-style (see the file libraries/core/LICENSE) --- --- Maintainer : vs@foldr.org --- Stability : provisional --- Portability : provides fallback --- --- 'System.Sendfile.sendfile' is a low-level method for efficently passing --- data from one file descriptor to another. --- The intended audience includes for example web server authors. Please --- note that this function is highly platform dependent. --- ------------------------------------------------------------------------------ - -module System.Sendfile ( - -- * Haskell wrappers - sendfile, - sendfileByName, - -- * Fallback implementation - squirt - -) where - -#include "HsUnix.h" - -import Foreign -import Foreign.C -import System.IO -import System.Posix.IO -import System.Posix.Types ( Fd, COff ) -import Control.Exception ( bracket ) -import Control.Monad ( unless) -import Data.Array.MArray -import Data.Array.IO - --- |'sendfile' transmits the contents of an open file to a stream socket --- opened for writing with as little overhead as possible. --- This function is not defined by any standard! Passing '0' will indeed --- transmit nothing at all. --- Caveats for 'handleToFd' apply. - -sendfile :: Fd -- ^ Input - -> Fd -- ^ Output - -> Int -- ^ Offset - -> Int -- ^ Nr. of bytes to transmit - -> IO () - -sendfile _inFd _outFd _startpos 0 = return () -sendfile inFd outFd startpos count = - -#if defined(HAVE_LINUX_SENDFILE) && !defined(__USE_FILE_OFFSET64) - do - offsetptr <- malloc - poke offsetptr (fromIntegral startpos) - throwErrnoIfMinus1_ "sendfile" $ c_sendfile outFd inFd offsetptr (fromIntegral count) - free offsetptr - return () - -foreign import ccall unsafe "sendfile" - c_sendfile :: Fd -> Fd -> Ptr COff -> CSize -> IO CSize - -#else /* Linux */ -# ifdef HAVE_BSD_SENDFILE - do - offsetptr <- malloc - rc <- sendfileLoop inFd outFd (fromIntegral startpos) (fromIntegral count) offsetptr - free offsetptr - return () - where - sendfileLoop :: Fd -> Fd -> COff -> CSize -> Ptr COff -> IO CInt - sendfileLoop inFd outFd start c offsetptr = do - rc <- c_sendfile inFd outFd start c nullPtr offsetptr 0 - if rc == -1 - then do - err <- getErrno - if err == eAGAIN - then do offset <- peek offsetptr -- now contains # of bytes written - sendfileLoop inFd outFd (start+offset) (c-(fromIntegral offset)) offsetptr - else throwErrno "sendfile" - else - return rc - -foreign import ccall unsafe "sendfile" - c_sendfile :: Fd -> Fd -> COff -> CSize -> Ptr a -> Ptr COff -> CInt -> IO CInt - -# else /* BSD */ - squirt inFd outFd startpos count -# endif /* no native */ -#endif - --- |'sendfileByName' sends a file to an already open descriptor --- using 'sendfile'. You can only use this function on regular --- files. -sendfileByName :: String -> Fd -> IO () -sendfileByName filename outFd = do - bracket - (openFile filename ReadMode) - (\handle -> hClose handle) - (\handle -> do - size <- hFileSize handle - inFd <- handleToFd handle - sendfile inFd outFd 0 (fromIntegral size)) - --- squirt data from 'rd' into 'wr' as fast as possible. We use a 4k --- single buffer. Stolen from Simon M.'s Haskell Web Server fptools/hws --- We have to revert the handleToFd. - --- |Fallback API. Exported in case somebody needs it. - -squirt :: Fd -- ^ Input - -> Fd -- ^ Output - -> Int -- ^ Offset - -> Int -- ^ Nr. of bytes to transmit - -> IO () -squirt inFd outFd startpos count = do - inH <- fdToHandle inFd - outH <- fdToHandle outFd - hSeek inH RelativeSeek (fromIntegral startpos) - arr <- Data.Array.MArray.newArray_ (0, bufsize-1) - let loop remaining = do - r <- hGetArray inH arr (min bufsize remaining) - unless (r == 0) $ - do if (r < bufsize) - then hPutArray outH arr r - else hPutArray outH arr bufsize >> loop (remaining-bufsize) - loop count - hFlush outH - -bufsize = 4 * 1024 :: Int diff --git a/include/HsUnix.h b/include/HsUnix.h index 9c60b1f..ad90050 100644 --- a/include/HsUnix.h +++ b/include/HsUnix.h @@ -1,5 +1,5 @@ /* ----------------------------------------------------------------------------- - * $Id: HsUnix.h,v 1.10 2003/05/28 12:36:29 stolz Exp $ + * $Id: HsUnix.h,v 1.11 2003/06/06 12:49:00 stolz Exp $ * * (c) The University of Glasgow 2002 * @@ -61,17 +61,6 @@ #include <grp.h> #endif -#ifdef HAVE_BSD_SENDFILE -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/uio.h> -#endif -#ifdef HAVE_LINUX_SENDFILE -#if !defined(__USE_FILE_OFFSET64) -#include <sys/sendfile.h> -#endif -#endif - #ifdef HAVE_FRAMEWORK_HASKELLSUPPORT #include <HaskellSupport/dlfcn.h> #else |