59 lines
1.8 KiB
Nim
59 lines
1.8 KiB
Nim
import socket
|
|
|
|
proc console_write(p: pointer, len: csize_t) {.importc, cdecl.}
|
|
|
|
# Basic SockAddr struct match (IPv4)
|
|
type
|
|
SockAddrIn = object
|
|
sin_family: uint16
|
|
sin_port: uint16
|
|
sin_addr: uint32
|
|
sin_zero: array[8, char]
|
|
|
|
proc socket*(domain, sock_type, protocol: int): int {.exportc, cdecl.} =
|
|
# Domain=2 (AF_INET), Type=1 (SOCK_STREAM)
|
|
# We ignore them for now and just give a Nexus Socket
|
|
return new_socket()
|
|
|
|
proc connect*(fd: int, sock_addr: pointer, len: int): int {.exportc, cdecl.} =
|
|
if sock_addr == nil: return -1
|
|
|
|
# Cast raw pointer to SockAddrIn
|
|
let sin = cast[ptr SockAddrIn](sock_addr)
|
|
|
|
# Call the Shim
|
|
# Note: Linux sockaddr_in is Big Endian for Port/IP usually
|
|
# NPK is likely running the same endianness as Kernel (Little Endian on RISC-V/x86)
|
|
# But `connect` expects Network Byte Order (Big Endian).
|
|
# We pass it raw to connect_flow, which will store it.
|
|
|
|
return connect_flow(fd, sin.sin_addr, sin.sin_port)
|
|
|
|
proc write*(fd: cint, buf: pointer, count: csize_t): int {.exportc, cdecl.} =
|
|
if fd == 1 or fd == 2:
|
|
when defined(is_kernel):
|
|
# 1. Allocate a Console Slab
|
|
var pkt = ion_alloc()
|
|
if pkt.data == nil: return -1
|
|
|
|
# 2. Copy the string (Cap at SLAB_SIZE)
|
|
let safe_count = min(int(count), SLAB_SIZE)
|
|
copyMem(pkt.data, buf, safe_count)
|
|
pkt.len = uint16(safe_count)
|
|
|
|
# 3. Push to KERNEL CONSOLE (Port 0)
|
|
ion_egress_to_port(0, pkt)
|
|
|
|
return int(safe_count)
|
|
else:
|
|
# Membrane side: Direct to UART for Phase 7
|
|
console_write(buf, count)
|
|
return int(count)
|
|
|
|
# Handle Sockets (fd > 2)
|
|
return send_flow(int(fd), buf, int(count))
|
|
|
|
proc read*(fd: int, buf: pointer, count: int): int {.exportc, cdecl.} =
|
|
# TODO: Lookup socket, check RX ring
|
|
return -1 # EBADF
|