Commit 0f27dcba authored by Mart Lubbers's avatar Mart Lubbers

Hello world example, orthogonal socketaddress

parent 19f4a27f
Pipeline #21274 failed with stage
in 2 minutes and 47 seconds
......@@ -5,14 +5,18 @@ import Data.Error
import Data.Maybe
import Network.IP
import System.Socket
import System.Socket.Ipv4
Start :: *World -> (MaybeOSError (), *World)
Start :: *World -> (MaybeOSError String, *World)
Start w
= case socket ST_Stream 0 w of
(Error e, w) = (Error e, w)
(Ok sockfd, w)
#! (merr, sockfd) = connect sockfd {sin_port=8124,sin_addr=Just (fromString "127.0.0.1")}
#! (merr, sockfd) = connect {sin_port=8124,sin_addr=Just (fromString "127.0.0.1")} sockfd
| isError merr = (liftError merr, w)
#! (merr, sockfd) = recv 128 0 sockfd
| isError merr = (merr, w)
# (Ok msg) = merr
# (merr, w) = close sockfd w
| isError merr = (merr, w)
= (Ok (), w)
| isError merr = (liftError merr, w)
= (Ok msg, w)
......@@ -6,19 +6,22 @@ import StdEnv
import Data.Error
import Data.Maybe
import System.Socket
import System.Socket.Ipv4
Start :: *World -> (MaybeOSError (), *World)
Start w
= case socket ST_Stream 0 w of
(Error e, w) = (Error e, w)
(Ok sockfd, w)
#! (merr, sockfd) = bind sockfd {sin_port=8124,sin_addr=Nothing}
#! (merr, sockfd) = bind {sin_port=8124,sin_addr=Nothing} sockfd
| isError merr = (merr, w)
#! (merr, sockfd) = listen sockfd 3
#! (merr, sockfd) = listen 3 sockfd
| isError merr = (merr, w)
= case accept sockfd of
(Error e, sockfd) = (Error e, w)
(Ok (sock, addr), sockfd)
# (merr, sock) = send "Hello world!" 0 sock
| isError merr = (liftError merr, w)
# (merr, w) = close sock w
| isError merr = (merr, w)
# (merr, w) = close sockfd w
......
definition module System.Socket
from StdOverloaded import class zero, class toString
from Data.Error import :: MaybeError, :: MaybeErrorString
from Network.IP import :: IPAddress
from StdMaybe import :: Maybe
from System.OSError import :: MaybeOSError, :: OSError, :: OSErrorMessage, :: OSErrorCode
from System._Pointer import :: Pointer
:: *Socket a (:== Int)
:: SaInet =
{ sin_port :: !Int
, sin_addr :: Maybe IPAddress
}
:: SaInet6 =
{ sin6_port :: !Int
, sin6_flowinfo :: !Int
......@@ -19,7 +12,6 @@ from System._Pointer import :: Pointer
, sin6_scope_id :: !Int
}
:: SocketDomain = SD_AfInet | SD_AfInet6
:: SocketType = ST_Stream | ST_DGram
class SocketAddress sa where
......@@ -28,19 +20,22 @@ class SocketAddress sa where
sa_deserialize :: !Pointer -> MaybeErrorString sa
sa_domain :: !sa -> Int
sa_null :: sa
instance SocketAddress SaInet
instance toString SaInet
socket :: !SocketType !Int !*e -> *(!MaybeOSError *(Socket sa), !*e) | SocketAddress sa
bind :: !*(Socket sa) !sa -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
listen :: !*(Socket sa) !Int -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
bind :: !sa !*(Socket sa) -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
listen :: !Int !*(Socket sa) -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
accept :: !*(Socket sa) -> *(!MaybeOSError (!*(Socket sa), !sa), !*(Socket sa)) | SocketAddress sa
close :: !*(Socket sa) !*e -> *(!MaybeOSError (), !*e) | SocketAddress sa
connect :: !*(Socket sa) !sa -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
connect :: !sa !*(Socket sa) -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
send :: !String !Int !*(Socket sa) -> *(!MaybeOSError Int, !*(Socket sa))
recv :: !Int !Int !*(Socket sa) -> *(!MaybeOSError String, !*(Socket sa))
/*
* Get access to the raw file descriptor
*/
getFd :: !*(Socket sa) -> *(!Int, !*(Socket sa))
ntohs :: !Int -> Int
htons :: !Int -> Int
implementation module System.Socket
import Network.IP
import StdEnv
import Data.Maybe
import Data.Error
import System.OSError
import System._Pointer
import System._Posix
import System._Unsafe
:: *Socket a :== Int
......@@ -15,25 +12,6 @@ instance toInt SocketType where
toInt ST_Stream = 1
toInt ST_DGram = 2
import StdDebug
derive gPrint MaybeError
instance SocketAddress SaInet where
sa_serialize sa p w
#! p = writeInt2 p 0 2
#! p = writeInt2 p 2 (htons sa.sin_port)
#! p = writeInt4 p 4 (maybe 0 toInt sa.sin_addr)
= (p, forceEvalPointer p w)
sa_deserialize p
= Ok {sin_port=ntohs (readInt2Z p 2),sin_addr=Just (fromInt (readInt4Z p 4))}
sa_length _ = 16
sa_domain _ = 2
sa_null = {sin_port=0, sin_addr=Nothing}
import Text.GenPrint
derive gPrint SaInet, Maybe
gPrint{|IPAddress|} a s = gPrint{|*|} (toString a) s
instance toString SaInet where toString s = printToString s
socket :: !SocketType !Int !*e -> *(!MaybeOSError *(Socket sa), !*e) | SocketAddress sa
socket type protocol w
#! (sockfd, w) = socket` (sa_domain msa) (toInt type) protocol w
......@@ -51,8 +29,8 @@ where
ccall socket "III:I:A"
}
bind :: !*(Socket sa) !sa -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
bind sockfd addr
bind :: !sa !*(Socket sa) -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
bind addr sockfd
#! p = malloc (sa_length addr)
| p == 0 = getLastOSError sockfd
#! (p, sockfd) = sa_serialize addr p sockfd
......@@ -69,8 +47,8 @@ where
ccall bind "IpI:I:A"
}
listen :: !*(Socket sa) !Int -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
listen sockfd backlog
listen :: !Int !*(Socket sa) -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
listen backlog sockfd
#! r = listen` sockfd backlog
| r == -1 = getLastOSError sockfd
= (Ok (), sockfd)
......@@ -102,8 +80,8 @@ where
ccall accept "IpI:I:A"
}
connect :: !*(Socket sa) !sa -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
connect sockfd addr
connect :: !sa !*(Socket sa) -> *(!MaybeOSError (), !*(Socket sa)) | SocketAddress sa
connect addr sockfd
#! (p, sockfd) = mallocSt (sa_length addr) sockfd
| p == 0 = getLastOSError sockfd
#! (p, sockfd) = sa_serialize addr p sockfd
......@@ -118,6 +96,34 @@ where
ccall connect "IpI:I:A"
}
send :: !String !Int !*(Socket sa) -> *(!MaybeOSError Int, !*(Socket sa))
send data flags sockfd
#! (fd, sockfd) = getFd sockfd
#! (r, sockfd) = send` fd (packString data) (size data) flags sockfd
| r == -1 = getLastOSError sockfd
= (Ok r, sockfd)
where
send` :: !Int !String !Int !Int !*e -> *(!Int, !*e)
send` _ _ _ _ _ = code {
ccall send "IsII:I:A"
}
recv :: !Int !Int !*(Socket sa) -> *(!MaybeOSError String, !*(Socket sa))
recv length flags sockfd
#! (p, sockfd) = mallocSt length sockfd
#! (fd, sockfd) = getFd sockfd
#! (r, sockfd) = recv` fd p length flags sockfd
| r == -1 = getLastOSError sockfd
#! (s, p) = readP derefString p
#! sockfd = freeSt p sockfd
= (Ok s, sockfd)
where
recv` :: !Int !Pointer !Int !Int !*e -> *(!Int, !*e)
recv` _ _ _ _ _ = code {
ccall recv "IpII:I:A"
}
close :: !*(Socket sa) !*e -> *(!MaybeOSError (), !*e) | SocketAddress sa
close sock w
# r = close` sock
......
definition module System.Socket.Ipv4
from StdOverloaded import class toString
//from Data.Error import :: MaybeError, :: MaybeErrorString
from Network.IP import :: IPAddress
from StdMaybe import :: Maybe
from System.Socket import class SocketAddress
//from System.OSError import :: MaybeOSError, :: OSError, :: OSErrorMessage, :: OSErrorCode
//from System._Pointer import :: Pointer
:: SaInet =
{ sin_port :: !Int
, sin_addr :: !Maybe IPAddress
}
instance SocketAddress SaInet
instance toString SaInet
implementation module System.Socket.Ipv4
import StdEnv
import Network.IP
import Data.Error
import System.Socket
import System._Pointer
import Text.GenPrint
instance SocketAddress SaInet where
sa_serialize sa p w
#! p = writeInt2 p 0 2
#! p = writeInt2 p 2 (htons sa.sin_port)
#! p = writeInt4 p 4 (maybe 0 toInt sa.sin_addr)
= (p, forceEvalPointer p w)
sa_deserialize p
= Ok {sin_port=ntohs (readInt2Z p 2),sin_addr=Just (fromInt (readInt4Z p 4))}
sa_length _ = 16
sa_domain _ = 2
sa_null = {sin_port=0, sin_addr=Nothing}
gPrint{|IPAddress|} a s = gPrint{|*|} (toString a) s
derive gPrint SaInet, Maybe
instance toString SaInet where toString s = printToString s
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment