aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar stolz <unknown>2003-06-06 12:49:00 +0000
committerGravatar stolz <unknown>2003-06-06 12:49:00 +0000
commit1c399d00524ed89eef163ec89c9311674e2cccbf (patch)
treeeca9e69b31eafdcbc80c7a7299f2b87a1818f944
parent9a3fcfc40fcbb60d61fd3eb4a6d9659d7e027932 (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.hsc133
-rw-r--r--include/HsUnix.h13
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