staload "libc/SATS/stdio.sats"
staload "libc/SATS/time.sats"
staload "libc/SATS/unistd.sats"
staload "libc/sys/SATS/socket.sats"
staload "libc/sys/SATS/sockaddr.sats"
staload "libc/netinet/SATS/in.sats"
staload "libc/sys/SATS/socket_in.sats"
staload "libc/arpa/SATS/inet.sats"
#define LISTENQ 5 #define TIME_SERVER_PORT 13000
implement main (argc, argv) = let
val nport = (if argc > 1 then int_of argv.[1] else TIME_SERVER_PORT): int
val [fd_s:int] (pfskt_s | fd_s) = socket_family_type_exn (AF_INET, SOCK_STREAM)
var servaddr: sockaddr_in_struct val servport = in_port_nbo_of_int (nport)
val in4addr_any = in_addr_nbo_of_hbo (INADDR_ANY)
val () = sockaddr_in_init (servaddr, AF_INET, in4addr_any, servport)
val () = bind_in_exn (pfskt_s | fd_s, servaddr)
val () = listen_exn (pfskt_s | fd_s, LISTENQ)
val () = loop (pfskt_s | fd_s) where {
fun loop (
pfskt_s: !socket_v (fd_s, listen) | fd_s: int fd_s
) : void = let
val [fd_c:int] (pfskt_c | fd_c) = accept_null_exn (pfskt_s | fd_s)
viewdef V = @(socket_v (fd_s, listen), socket_v (fd_c, conn))
prval pf = @(pfskt_s, pfskt_c)
val f_child = lam (pf: V | ): void =<cloptr1> let
prval @(pfskt_s, pfskt_c) = pf
val () = socket_close_exn (pfskt_s | fd_s)
var ntick = time_get ()
val [l:addr] (fpf_pstr | pstr) = ctime ntick val () = assert (strptr_isnot_null(pstr))
val () = () where {
val str = __cast (pstr) where {
extern castfn __cast {l>null} (x: !strptr l): string
} val str = string1_of_string (str)
val strlen = string1_length (str)
extern castfn __cast {n:nat}
(s: string n): [l:addr] (bytes n @ l, bytes n @ l -<lin,prf> void | ptr l)
val (pf, fpf | p) = __cast (str)
val _ = socket_write_all_exn (pfskt_c | fd_c, !p, strlen)
prval () = fpf (pf)
val () = socket_close_exn (pfskt_c | fd_c)
} prval () = fpf_pstr (pstr)
in
end val () = fork_exec_cloptr_exn {V} (pf | f_child)
prval () = pfskt_s := pf.0
prval () = pfskt_c := pf.1
val () = socket_close_exn (pfskt_c | fd_c)
in
loop (pfskt_s | fd_s)
end } val () = socket_close_exn (pfskt_s | fd_s)
in
end