Socket library ghc 5.02.1
Sigbjorn Finne
sof@galois.com
Tue, 27 Nov 2001 09:30:04 -0800
This is a multi-part message in MIME format.
------=_NextPart_000_0804_01C17726.1850B6D0
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
>
> Conclusion: you're hosed with ghc-5.02.1 and its socket libs under
> Win32. Sorry.
>
If you don't mind getting your hands a (little) bit dirty, here's a story
that will work ghc-5.02.1:
* edit SocketPrim.hi (and SocketPrim.p_hi), to instead of saying
"Socket" in its __export section it says "Socket{MkSocket}"
(you'll find the .hi file in imports/net/ inside your 5.02.1 tree).
* compile up the attached NetExtra.hs as follows:
foo$ ghc -c NetExtra.hs -fvia-C -fglasgow-exts -package net
* import and include NetExtra with your socket code, e.g.,
main = Socket.withSocketsDo $ do
protNum <- getProtocolNumber "tcp"
s <- socket AF_INET Stream protNum
hostAddr <- inet_addr "127.0.0.1"
let sAddr = (SockAddrInet 80 hostAddr)
connect s sAddr
send s "GET / HTTP/1.0\r\n\r\n"
str <- recvAll s
putStr str
recvAll :: Socket -> IO String
recvAll sock = do
str <- catch (recv s 100) (\ _ -> return "")
case str of
"" -> return str
_ -> do
ls <- recvAll sock
return (str ++ ls)
hth
--sigbjorn
------=_NextPart_000_0804_01C17726.1850B6D0
Content-Type: application/octet-stream;
name="NetExtra.hs"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="NetExtra.hs"
{-# OPTIONS -#include "HsNet.h" #-}
module NetExtra=20
( fdSocket -- :: Socket -> CInt
, send -- :: Socket -> String -> IO Int
, recv -- :: Socket -> Int -> IO String
) where
import SocketPrim
import CForeign
import Foreign
import Concurrent ( threadWaitWrite, threadWaitRead )
import PrelCError
import CString
import CTypes
import Ptr
import Monad
fdSocket :: Socket -> CInt
fdSocket (MkSocket fd _ _ _ _) =3D fd
send :: Socket -> String -> IO Int
send sock xs =3D do
let fd =3D fdSocket sock
withCString xs $ \str -> do
liftM fromIntegral $
throwErrnoIfMinus1Retry_repeatOnBlock "send"
(threadWaitWrite (fromIntegral fd)) $
c_send fd str (fromIntegral $ length xs) 0{-flags-}=20
recv :: Socket -> Int -> IO String
recv sock nbytes =3D do
let fd =3D fdSocket sock
allocaBytes nbytes $ \ptr -> do
len <- throwErrnoIfMinus1Retry_repeatOnBlock "recv"=20
(threadWaitRead (fromIntegral fd)) $
c_recv fd ptr (fromIntegral nbytes) 0{-flags-}=20
let len' =3D fromIntegral len
peekCStringLen (ptr,len')
-- ripped straight out of SocketPrim.hsc
throwErrnoIfMinus1Retry_repeatOnBlock :: Num a =3D> String -> IO b -> IO =
a -> IO a
throwErrnoIfMinus1Retry_repeatOnBlock name on_block act =3D do
throwErrnoIfMinus1Retry_mayBlock name (on_block >> repeat) act
where repeat =3D throwErrnoIfMinus1Retry_repeatOnBlock name on_block =
act
throwErrnoIfMinus1Retry_mayBlock :: Num a =3D> String -> IO a -> IO a -> =
IO a
throwErrnoIfMinus1Retry_mayBlock name on_block act =3D do
res <- act
if res =3D=3D -1
then do
err <- getErrno
if err =3D=3D eINTR
then throwErrnoIfMinus1Retry_mayBlock name on_block act
else if err =3D=3D eWOULDBLOCK || err =3D=3D eAGAIN
then on_block
else throwErrno name
else return res
foreign import "send" unsafe
c_send :: CInt -> Ptr CChar -> CSize -> CInt -> IO CInt
foreign import "recv" unsafe
c_recv :: CInt -> Ptr CChar -> CSize -> CInt -> IO CInt
------=_NextPart_000_0804_01C17726.1850B6D0--