1    object Sys
2        val af_inet : u16 = 2
3    
4    type Address = struct
5        family : u16
6        port : u16
7        ip_address : u32 = 0
8        pad : [u8; 8] = memory@zero
9    
10   def htons (host : u16) : u16
11   let recv (fd : int
12             buf : MutPtr<CChar>
13             nbytes : int
14             flags : int) : int
15   let send (fd : int
16             buf : Ptr
17             n : usize
18             flags : int) : usize
19   let inet_pton (af : int
20                  cp : CString
21                  buf : MutPtr) : int
22   let connect (fd : int
23                addr : Ptr<Address>
24                len : usize) : int
25   def create_socket "kd_create_socket" : int
26   let shutdown "kd_shutdown" (fd : int)
27   
28   type TcpStream =
29       let fd : int
30   
31       def try_next : Option<String> =
32           let mut buffer : [CChar; 1024] = memory@zero
33           let length = recv fd buffer.as_mut_ptr (1024 - 1) 0
34   
35           if length > 0 then
36               let response = String.from buffer.as_ptr length.as<u32>
37               Some response
38           else
39               None
40   
41       def read_text = try_next.unwrap
42   
43       def discard =
44           close fd |> ignore
45   
46       def write (s : String) =
47           let c_s @owner = s.to_c_string
48           send fd c_s.unwrap s.length.as<usize> 0
49           shutdown fd
50   
51   object TcpStream =
52       def connect (address : String) : Option<TcpStream> =
53           let address_parts = address.split ':'
54           assert address_parts.size == 2
55           let ip_string = address_parts[0]
56           let port_string = address_parts[1]
57           let port = u32.parse port_string as u16
58           let client_fd = create_socket
59           if client_fd < 0 then
60               println "socket creation error"
61               return None
62   
63           let mut server_address = Address
64               family = Sys.af_inet
65               port = htons port
66   
67           let c_ip_string @owner = ip_string.to_c_string
68   
69           let result = inet_pton Sys.af_inet.as<int>
70                                  c_ip_string
71                                  server_address.ip_address@mut_ptr
72           if result <= 0 then
73               println "invalid address"
74               return None
75   
76           let status = connect client_fd server_address@ptr (sizeof Address as usize)
77           if status < 0 then
78               println "connection failed"
79               return None
80   
81           TcpStream client_fd |> Some
82