staload UNSAFE = "prelude/SATS/unsafe.sats"
staload "libc/SATS/errno.sats"
staload "libc/SATS/string.sats"
staload "libc/sys/SATS/sockaddr.sats"
staload "libc/sys/SATS/sockopt.sats"
staload "libc/sys/SATS/socket.sats"
staload "libc/sys/SATS/time.sats"
datatype OPTKIND = OPTKINDint | OPTKINDlinger | OPTKINDtimeval
fun show {fd:nat} (
skt: int fd
, level: int, option: int, name: string
, knd: OPTKIND
) : void =
case+ knd of
| OPTKINDint () => let
var n: int?
val err = getsockopt_err{int} (skt, level, option, n, sizeof<int>)
in
if err >= 0 then let
prval () = opt_unsome {int} (n) in printf ("%s = %d\n", @(name, n))
end else let
prval () = opt_unnone {int} (n)
val (fpf_str | str) = strerror (errno_get())
val () = printf ("%s FAILED (%s)\n", @(name, $UNSAFE.castvwtp1{string} (str)))
prval () = fpf_str (str)
in
end end
| OPTKINDlinger () => let
var lg: linger?
val err = getsockopt_err{linger} (skt, level, option, lg, sizeof<linger>)
in
if err >= 0 then let
prval () = opt_unsome {linger} (lg)
in
printf ("%s = %d(on/off) / %d sec(linger)\n", @(name, lg.l_onoff, lg.l_linger))
end else let
prval () = opt_unnone {linger} (lg)
val (fpf_str | str) = strerror (errno_get())
val () = printf ("%s FAILED (%s)\n", @(name, $UNSAFE.castvwtp1{string} (str)))
prval () = fpf_str (str)
in
end end
| OPTKINDtimeval () => let
var tv: timeval?
val err = getsockopt_err{timeval} (skt, level, option, tv, sizeof<timeval>)
in
if err >= 0 then let
prval () = opt_unsome {timeval} (tv)
in
printf ("%s = %ld sec / %ld usec\n",
@(name, $UNSAFE.cast2lint(tv.tv_sec), $UNSAFE.cast2lint(tv.tv_usec))
) end else let
prval () = opt_unnone {timeval} (tv)
val (fpf_str | str) = strerror (errno_get())
val () = printf ("%s FAILED (%s)\n", @(name, $UNSAFE.castvwtp1{string} (str)))
prval () = fpf_str (str)
in
end end
fun showall {fd:nat}
(skt: int fd, caption: string): void = () where {
val () = printf ("\n%s\n", @(caption))
val () = show (skt, SOL_SOCKET, SO_ACCEPTCONN, "SO_ACCEPTCONN", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_BROADCAST, "SO_BROADCAST", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_DEBUG, "SO_DEBUG", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_DONTROUTE, "SO_DONTROUTE", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_ERROR, "SO_ERROR", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_KEEPALIVE, "SO_KEEPALIVE", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_LINGER, "SO_LINGER", OPTKINDlinger)
val () = show (skt, SOL_SOCKET, SO_OOBINLINE, "SO_OOBINLINE", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_RCVBUF, "SO_RCVBUF", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_RCVLOWAT, "SO_RCVLOWAT", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_RCVTIMEO, "SO_RCVTIMEO", OPTKINDtimeval)
val () = show (skt, SOL_SOCKET, SO_REUSEADDR, "SO_REUSEADDR", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_SNDBUF, "SO_SNDBUF", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_SNDLOWAT, "SO_SNDLOWAT", OPTKINDint)
val () = show (skt, SOL_SOCKET, SO_SNDTIMEO, "SO_SNDTIMEO", OPTKINDtimeval)
val () = show (skt, SOL_SOCKET, SO_TYPE, "SO_TYPE", OPTKINDint)
}
implement
main () = () where {
val (pfskt | skt) = socket_family_type_exn (AF_INET, SOCK_STREAM)
val () = showall (skt, "AF_INET/SOCKET_STREAM")
val () = socket_close_exn (pfskt | skt)
val (pfskt | skt) = socket_family_type_exn (AF_INET, SOCK_DGRAM)
val () = showall (skt, "AF_INET/SOCKET_DGRAM")
val () = socket_close_exn (pfskt | skt)
}