staload "libc/SATS/stdio.sats"
staload "libc/SATS/time.sats"
staload "libc/SATS/unistd.sats"
staload "libc/sys/SATS/socket.sats"
staload "libc/netinet/SATS/in.sats"
staload "libc/arpa/SATS/inet.sats"
#define LISTENQ 5 #define TIME_SERVER_PORT 13000
#if 0
%{
ats_void_type atslib_fork_cloptr_exn (ats_ptr_type f_child) {
pid_t pid ;
pid = fork () ;
if (pid < 0) {
ats_exit_errmsg (errno, "Exit: [fork] failed.\n") ;
}
/* this is the parent */
if (pid > 0) { ATS_FREE (f_child) ; return ; }
/* this is the child */
((ats_void_type (*)(ats_clo_ptr_type))((ats_clo_ptr_type)f_child)->closure_fun)(f_child) ;
_exit (0) ; /* no need to flush STDIN, STDOUT and STDERR */
return ; /* deadcode */
} /* end of [atslib_fork_cloptr] */
%}
#endif
implement main (argc, argv) = let
var nport: int = TIME_SERVER_PORT
val () = if argc > 1 then nport := int_of argv.[1]
val [fd_s:int] (pf_sock_s | fd_s) =
socket_family_type_exn (AF_INET, SOCK_STREAM)
var servaddr: sockaddr_in_struct_t val servport = in_port_nbo_of_int (nport)
val in4addr_any = in_addr_nbo_of_hbo (INADDR_ANY)
val () = sockaddr_ipv4_init (servaddr, AF_INET, in4addr_any, servport)
val () = bind_ipv4_exn (pf_sock_s | fd_s, servaddr)
val () = listen_exn (pf_sock_s | fd_s, LISTENQ)
val () = loop (pf_sock_s | fd_s) where {
fun loop (
pf_sock_s: !socket_v (fd_s, listen) | fd_s: int fd_s
) : void = let
val [fd_c:int] (pf_sock_c | fd_c) = accept_null_exn (pf_sock_s | fd_s)
viewdef V = @(socket_v (fd_s, listen), socket_v (fd_c, conn))
prval pf = @(pf_sock_s, pf_sock_c)
val f_child = lam (pf: V | ): void =<cloptr1> let
prval @(pf_sock_s, pf_sock_c) = pf
val () = socket_close_exn (pf_sock_s | fd_s)
var ntick = time_get ()
var !p_buf with pf_buf = @[byte][CTIME_BUFLEN]()
val _ = ctime_r (pf_buf | ntick, p_buf) val len = strbuf_length (!p_buf)
prval () = pf_buf := bytes_v_of_strbuf_v (pf_buf)
val _ = socket_write_loop_exn (pf_sock_c | fd_c, !p_buf, len)
val () = socket_close_exn (pf_sock_c | fd_c)
in
end val () = fork_exec_cloptr_exn {V} (pf | f_child)
prval () = pf_sock_s := pf.0 and () = pf_sock_c := pf.1
val () = socket_close_exn (pf_sock_c | fd_c)
in
loop (pf_sock_s | fd_s)
end } val () = socket_close_exn (pf_sock_s | fd_s)
in
end