x-lang

← Index

x/sys/socket

Blocking IPv4 TCP on the Socket class, over libc FFI.

First consumer: x/logo/serve.x (whose Darwin-only constants this replaces). Recv truncates at the first NUL byte (ptr->str) – fine for text protocols; recv-bytes is the lossless byte-list door (#374).

Class Socket

Blocking IPv4 TCP over libc FFI: listen/accept on the server side, connect on the client side, send/recv/close on both.

No DNS: hosts are dotted quads (“127.0.0.1”). Failures raise label ‘io Errs with errno detail; recv answers nil at orderly EOF (absence, not a sentinel).

(Socket tcp-listen ports . backlog)

Create a TCP server socket: socket + SO_REUSEADDR + bind(INADDR_ANY, port) + listen.

ports is walked as tcp-listen-on walks it; read the port bound with local-port.

Parameters:

Returns: INTEGER — The listening file descriptor

(Socket tcp-listen-on host ports . backlog)

Create a TCP server socket bound to one local address: what tcp-listen does, with bind(host, port) in place of INADDR_ANY, so only connections to that address reach it.

An INTEGER is the one port to bind. A list or a Gen is walked by Gen flatten, lazily, and each port is tried in turn until one binds; a port in use (eaddrinuse) moves on to the next, any other failure raises at once. When every candidate is in use the eaddrinuse Err carries the ports tried, in order, as its detail. 0 lets the kernel choose, so a list ending in 0 always binds; local-port reads the port bound.

An address no interface holds is a label ‘io Err from bind (eaddrnotavail); a host that is not a dotted quad, or a candidate that is not an INTEGER, raises ‘value before any syscall for it.

Parameters:

Returns: INTEGER — The listening file descriptor

(Socket accept fd)

Block until a client connects; the peer address is discarded (stat the fd’s peer later if wanted).

Parameters:

Returns: INTEGER — The connected client file descriptor

(Socket tcp-connect host port)

Open a TCP connection to host:port (no DNS – dotted quads only).

Parameters:

Returns: INTEGER — The connected file descriptor

(Socket send fd s)

Send the whole string; raises on failure, a peer that has closed among them (epipe), where libc would otherwise end the process with SIGPIPE.

Parameters:

Returns: INTEGER — Bytes sent

(Socket send-run fd s n)

Send the first n BYTES of s – the lossless door, as recv-run is: send measures its string to the first NUL, and a binary packet has NULs inside. THE COUNT IS YOUR CLAIM AND IS NOT CHECKED. Raises on failure, a peer that has closed among them (epipe), as send does.

Parameters:

Returns: INTEGER — Bytes sent

(Socket recv fd maxlen)

Receive up to maxlen bytes as a string; nil at orderly EOF (the peer closed); raises on failure.

Parameters:

Returns: ANY — The received string, or nil at EOF

(Socket resolve name)

The host’s first IPv4 address as a dotted quad, via getaddrinfo (#412) – the DNS door; every other Socket method still takes quads. Raises a label ‘io with the gai code when resolution fails, label ‘value when the name has no IPv4 address.

Parameters:

Returns: STRING — A dotted quad, e.g. “140.82.114.3”

(Socket recv-bytes fd maxlen)

Receive up to maxlen bytes as a BYTE LIST – the lossless door (recv’s string return truncates at the first NUL; this one carries binary intact, #374); nil at orderly EOF; raises on failure.

Parameters:

Returns: ANY — Byte list (0-255 values), or nil at EOF

(Socket recv-run fd maxlen)

Receive up to maxlen bytes as a RUN: (STRING . COUNT), the bytes in a string buffer and how many there are, NUL bytes included. No list is built, so a read costs a few objects whatever its size, where recv-bytes builds one pair a byte. Write a run with (File write fd (first r) (rest r)). nil at orderly EOF; raises on failure.

Parameters:

Returns: ANY — (STRING . COUNT), or nil at EOF

(Socket close fd)

Close a socket file descriptor.

Parameters:

Returns: ANY — nil

(Socket local-port fd)

The local port fd is bound to – the one the kernel chose when the bind asked for port 0. TCP and UDP alike.

Parameters:

Returns: INTEGER — The bound port, host order

(Socket shutdown fd . how)

Close one direction of a connection, through shutdown(2): after write, the peer reads end of input while what it sends still arrives – how a client says it has sent everything and waits for the answer. The descriptor stays open; close it after.

Parameters:

Returns: ANY — nil

(Socket peer fd)

The address at the other end of a connection, through getpeername(2): its dotted quad and port. What a server that accepted the connection says it came from.

Parameters:

Returns: PAIR — (QUAD . PORT)

(Socket udp-bind port)

Create a UDP socket bound to port on all interfaces – the receiving end. Read with (Socket recv-from fd n) for sender identity, or plain (Socket recv) when it does not matter.

Parameters:

Returns: INTEGER — The bound datagram file descriptor

(Socket udp-connect host port)

Create a CONNECTED UDP socket: the peer address is fixed once, and the plain (Socket send)/(Socket recv) pair then works datagram-wise – the request/reply pattern. For unconnected sends use (Socket send-to).

Parameters:

Returns: INTEGER — The connected datagram file descriptor

(Socket send-to fd s host port)

Send one datagram to host:port through an unconnected UDP socket.

Parameters:

Returns: INTEGER — Bytes sent

(Socket recv-from fd maxlen)

Block for one datagram; return it WITH the sender’s identity. Like recv, the payload string truncates at the first NUL byte (ptr->str) – fine for text protocols.

Parameters:

Returns: PAIR — (payload . (host . port))

(Socket send-to-run fd run host port)

Send one datagram of a run’s COUNT bytes to host:port – send-to for binary protocols, DNS and TFTP among them, whose packets carry NUL bytes a string’s length stops at.

Parameters:

Returns: INTEGER — Bytes sent

(Socket recv-from-run fd maxlen)

Block for one datagram; return it as a run, (STRING . COUNT), NUL bytes included, WITH the sender’s identity – recv-from for binary protocols. A reply goes back with (Socket send-to-run fd run host port).

Parameters:

Returns: PAIR — ((STRING . COUNT) . (host . port))

(Socket %sockaddr-un path)

Build a malloc’d sockaddr_un for path – the caller frees. Raises a label ‘value past 99 bytes (the struct’s path field is 104).

Parameters:

Returns: POINTER — The packed address (110 bytes)

(Socket unix-listen path . backlog)

Create a unix-domain stream server socket at path: socket + bind + listen. The path must not already exist (bind refuses) – unlink a stale one first; accept/send/recv/close are shared with TCP.

Parameters:

Returns: INTEGER — The listening file descriptor

(Socket unix-connect path)

Open a unix-domain stream connection to the socket at path.

Parameters:

Returns: INTEGER — The connected file descriptor

(Socket unix-dgram-bind path)

Create a unix-domain datagram socket bound at path – the receiving end, as a syslog daemon’s /dev/log is. The path must not already exist (bind refuses) – unlink a stale one first. Read with (Socket recv) or (Socket recv-run): each read takes one datagram.

Parameters:

Returns: INTEGER — The bound datagram file descriptor

(Socket unix-dgram-connect path)

Create a unix-domain datagram socket CONNECTED to path: (Socket send) or (Socket send-run) then delivers one datagram a call, as syslog(3) writes to /dev/log. Connecting where nothing is bound is a structured failure.

Parameters:

Returns: INTEGER — The connected datagram file descriptor