// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
#unsafe_skip_stub_check
fn make_tcp_socket_ffi(family : AddrFamily) -> @fd_util.Fd = "moonbitlang/async" "socket/make_tcp_socket"
///|
fn make_tcp_socket(family : AddrFamily, context~ : String) -> @fd_util.Fd raise {
let sock = make_tcp_socket_ffi(family)
if !@fd_util.fd_is_valid(sock) {
@os_error.check_errno(context)
}
if @event_loop.platform is Windows {
()
} else {
@fd_util.set_cloexec(sock, context~)
}
sock
}
///|
#unsafe_skip_stub_check
fn make_udp_socket_ffi(family : AddrFamily, multicast~ : Bool) -> @fd_util.Fd = "moonbitlang/async" "socket/make_udp_socket"
///|
fn make_udp_socket(
family : AddrFamily,
multicast~ : Bool,
context~ : String,
) -> @fd_util.Fd raise {
let sock = make_udp_socket_ffi(family, multicast~)
if !@fd_util.fd_is_valid(sock) {
@os_error.check_errno(context)
}
if @event_loop.platform is Windows {
()
} else {
@fd_util.set_cloexec(sock, context~)
}
sock
}
///|
#unsafe_skip_stub_check
#borrow(multi_addr, local_addr)
fn join_multicast_group_ffi(
sock : @fd_util.Fd,
multi_addr : Addr,
local_addr : Addr,
multi_addr_len? : Int = multi_addr.0.length(),
local_addr_len? : Int = local_addr.0.length(),
) -> Int = "moonbitlang/async" "socket/join_multicast_group"
///|
fn join_multicast_group(
sock : @fd_util.Fd,
multi_addr : Addr,
local_addr : Addr,
context~ : String,
) -> Unit raise {
if join_multicast_group_ffi(sock, multi_addr, local_addr) < 0 {
@os_error.check_errno(context)
}
}
///|
#unsafe_skip_stub_check
#borrow(multi_addr)
fn join_multicast_group_v6_ffi(
sock : @fd_util.Fd,
multi_addr : Addr,
interface_index : UInt,
multi_addr_len? : Int = multi_addr.0.length(),
) -> Int = "moonbitlang/async" "socket/join_multicast_group_v6"
///|
fn join_multicast_group_v6(
sock : @fd_util.Fd,
multi_addr : Addr,
interface_index : UInt,
context~ : String,
) -> Unit raise {
if join_multicast_group_v6_ffi(sock, multi_addr, interface_index) < 0 {
@os_error.check_errno(context)
}
}
///|
#unsafe_skip_stub_check
#borrow(local_addr)
fn set_multicast_interface_ffi(
sock : @fd_util.Fd,
local_addr : Addr,
local_addr_len? : Int = local_addr.0.length(),
) -> Int = "moonbitlang/async" "socket/set_multicast_interface"
///|
fn set_multicast_interface(
sock : @fd_util.Fd,
local_addr : Addr,
context~ : String,
) -> Unit raise {
if set_multicast_interface_ffi(sock, local_addr) < 0 {
@os_error.check_errno(context)
}
}
///|
#unsafe_skip_stub_check
fn set_multicast_interface_v6_ffi(
sock : @fd_util.Fd,
interface_index : UInt,
) -> Int = "moonbitlang/async" "socket/set_multicast_interface_v6"
///|
fn set_multicast_interface_v6(
sock : @fd_util.Fd,
interface_index : UInt,
context~ : String,
) -> Unit raise {
if set_multicast_interface_v6_ffi(sock, interface_index) < 0 {
@os_error.check_errno(context)
}
}
///|
#unsafe_skip_stub_check
fn set_multicast_ttl_ffi(
sock : @fd_util.Fd,
ttl : Int,
family~ : AddrFamily,
) -> Int = "moonbitlang/async" "socket/set_multicast_ttl"
///|
fn set_multicast_ttl(
sock : @fd_util.Fd,
ttl : Int,
family~ : AddrFamily,
context~ : String,
) -> Unit raise {
if set_multicast_ttl_ffi(sock, ttl, family~) < 0 {
@os_error.check_errno(context)
}
}
///|
#unsafe_skip_stub_check
fn set_multicast_loopback_ffi(
sock : @fd_util.Fd,
loopback : Bool,
family~ : AddrFamily,
) -> Int = "moonbitlang/async" "socket/set_multicast_loopback"
///|
fn set_multicast_loopback(
sock : @fd_util.Fd,
loopback : Bool,
family~ : AddrFamily,
context~ : String,
) -> Unit raise {
if set_multicast_loopback_ffi(sock, loopback, family~) < 0 {
@os_error.check_errno(context)
}
}
///|
#unsafe_skip_stub_check
fn set_ipv6_only(sock : @fd_util.Fd, ipv6_only : Bool) -> Int = "moonbitlang/async" "socket/set_ipv6_only"
///|
#unsafe_skip_stub_check
fn listen_ffi(sock : @fd_util.Fd) -> Int = "moonbitlang/async" "socket/listen"
///|
#unsafe_skip_stub_check
#borrow(addr)
fn connect_ffi(
sock : @fd_util.Fd,
addr : Addr,
addr_len? : Int = addr.0.length(),
) -> Int = "moonbitlang/async" "socket/udp_client_connect"
///|
#unsafe_skip_stub_check
fn disable_nagle(sock : @fd_util.Fd) -> Int = "moonbitlang/async" "socket/disable_nagle"
///|
#unsafe_skip_stub_check
fn allow_reuse_addr(sock : @fd_util.Fd) -> Int = "moonbitlang/async" "socket/allow_reuse_addr"
///|
#unsafe_skip_stub_check
fn enable_keepalive_ffi(
sock : @fd_util.Fd,
keep_idle : Int,
keep_count : Int,
keep_intv : Int,
) -> Int = "moonbitlang/async" "socket/enable_keepalive"
///|
#unsafe_skip_stub_check
#borrow(addr_out)
fn getsockname_ffi(
sock : @fd_util.Fd,
addr_out : Addr,
addr_len? : Int = addr_out.0.length(),
) -> Int = "moonbitlang/async" "socket/getsockname"
///|
fn getsockname(
sock : @fd_util.Fd,
family : AddrFamily,
context~ : String,
) -> Addr raise {
let addr = Addr::empty(family)
if getsockname_ffi(sock, addr) < 0 {
@os_error.check_errno(context)
}
addr
}