mirror of
https://github.com/sbrow/zomq.git
synced 2026-08-26 10:53:32 -04:00
197 lines
6.1 KiB
Odin
197 lines
6.1 KiB
Odin
package zmq
|
|
|
|
import "core:c"
|
|
import "core:os"
|
|
|
|
// ZMQ_HAUSNUMERO — base offset for ZMQ's private error codes.
|
|
//
|
|
// zmq.h defines two ranges on top of this base:
|
|
// +1..18 — fallback POSIX errnos (ENOTSUP, EPROTONOSUPPORT, ... ENETRESET).
|
|
// Only used when the platform's C <errno.h> lacks the symbol
|
|
// (e.g. MSVC on Windows). On Linux/macOS the system's native
|
|
// errno values are used instead, so these never appear from
|
|
// zmq_errno() — but we normalize to them for portability (see
|
|
// normalize_to_zmq).
|
|
// +51..54 — ZMQ-native codes (EFSM, ENOCOMPATPROTO, ETERM, EMTHREAD).
|
|
// Always ZMQ-specific, defined unconditionally.
|
|
//
|
|
// The value is fixed by libzmq's ABI-stability promise (zmq.h): "the value
|
|
// of constants must not change, and old values may not be reused". A C
|
|
// #define is not a linkable symbol, so hardcoding is the only option.
|
|
HAUSNUMERO :: 156384712
|
|
|
|
ZMQ_Error :: enum c.int {
|
|
// Fallback POSIX errnos — ZMQ's own values for these errnos, used on
|
|
// platforms where the C <errno.h> doesn't define them. We normalize
|
|
// all platforms to these values via normalize_to_zmq so that the same
|
|
// logical error always has the same value and lands in ZMQ_Error
|
|
// regardless of platform.
|
|
ENOTSUP = HAUSNUMERO + 1,
|
|
EPROTONOSUPPORT = HAUSNUMERO + 2,
|
|
ENOBUFS = HAUSNUMERO + 3,
|
|
ENETDOWN = HAUSNUMERO + 4,
|
|
EADDRINUSE = HAUSNUMERO + 5,
|
|
EADDRNOTAVAIL = HAUSNUMERO + 6,
|
|
ECONNREFUSED = HAUSNUMERO + 7,
|
|
EINPROGRESS = HAUSNUMERO + 8,
|
|
ENOTSOCK = HAUSNUMERO + 9,
|
|
EMSGSIZE = HAUSNUMERO + 10,
|
|
EAFNOSUPPORT = HAUSNUMERO + 11,
|
|
ENETUNREACH = HAUSNUMERO + 12,
|
|
ECONNABORTED = HAUSNUMERO + 13,
|
|
ECONNRESET = HAUSNUMERO + 14,
|
|
ENOTCONN = HAUSNUMERO + 15,
|
|
ETIMEDOUT = HAUSNUMERO + 16,
|
|
EHOSTUNREACH = HAUSNUMERO + 17,
|
|
ENETRESET = HAUSNUMERO + 18,
|
|
|
|
// ZMQ-native error codes.
|
|
EFSM = HAUSNUMERO + 51,
|
|
ENOCOMPATPROTO = HAUSNUMERO + 52,
|
|
ETERM = HAUSNUMERO + 53,
|
|
EMTHREAD = HAUSNUMERO + 54,
|
|
}
|
|
|
|
// Map platform-native POSIX errnos to ZMQ fallback values.
|
|
//
|
|
// The 18 errnos below have different numeric values on different platforms
|
|
// (e.g. EADDRINUSE is 98 on Linux, 100 on Windows, 48 on macOS). By
|
|
// translating them to ZMQ's canonical fallback values (HAUSNUMERO+offset),
|
|
// the same logical error always lands in ZMQ_Error with the same value
|
|
// on every platform — enabling portable pattern matching.
|
|
//
|
|
// Errnos not in this list (EAGAIN, EINTR, EACCES, ...) pass through
|
|
// unchanged and are classified as Platform_Error.
|
|
normalize_to_zmq :: proc(raw: c.int) -> c.int {
|
|
#partial switch os.Platform_Error(raw) {
|
|
// ENOTSUP shares its value with EOPNOTSUPP on Linux/macOS (both are
|
|
// the same constant). On Windows they differ (129 vs 130), but MSVC-
|
|
// compiled libzmq uses the ZMQ fallback (HAUSNUMERO+1) anyway, so
|
|
// .EOPNOTSUPP here only needs to match the Linux/macOS value.
|
|
case .EOPNOTSUPP:
|
|
return HAUSNUMERO + 1
|
|
case .EPROTONOSUPPORT:
|
|
return HAUSNUMERO + 2
|
|
case .ENOBUFS:
|
|
return HAUSNUMERO + 3
|
|
case .ENETDOWN:
|
|
return HAUSNUMERO + 4
|
|
case .EADDRINUSE:
|
|
return HAUSNUMERO + 5
|
|
case .EADDRNOTAVAIL:
|
|
return HAUSNUMERO + 6
|
|
case .ECONNREFUSED:
|
|
return HAUSNUMERO + 7
|
|
case .EINPROGRESS:
|
|
return HAUSNUMERO + 8
|
|
case .ENOTSOCK:
|
|
return HAUSNUMERO + 9
|
|
case .EMSGSIZE:
|
|
return HAUSNUMERO + 10
|
|
case .EAFNOSUPPORT:
|
|
return HAUSNUMERO + 11
|
|
case .ENETUNREACH:
|
|
return HAUSNUMERO + 12
|
|
case .ECONNABORTED:
|
|
return HAUSNUMERO + 13
|
|
case .ECONNRESET:
|
|
return HAUSNUMERO + 14
|
|
case .ENOTCONN:
|
|
return HAUSNUMERO + 15
|
|
case .ETIMEDOUT:
|
|
return HAUSNUMERO + 16
|
|
case .EHOSTUNREACH:
|
|
return HAUSNUMERO + 17
|
|
case .ENETRESET:
|
|
return HAUSNUMERO + 18
|
|
case:
|
|
return raw
|
|
}
|
|
}
|
|
|
|
// Reverse of normalize_to_zmq: maps ZMQ fallback values back to
|
|
// platform-native errno values.
|
|
//
|
|
// zmq_strerror only has string entries for ZMQ-native codes (HAUSNUMERO+51..54)
|
|
// and delegates everything else to C's strerror, which only knows platform-native
|
|
// errno values. The ZMQ fallback values (HAUSNUMERO+1..18) are in a gap — neither
|
|
// ZMQ-native nor platform-native — so zmq_strerror returns "Unknown error" for them.
|
|
// This function reverses the normalization so strerror produces the correct string.
|
|
denormalize_from_zmq :: proc(zmq_val: c.int) -> c.int {
|
|
#partial switch ZMQ_Error(zmq_val) {
|
|
case .ENOTSUP:
|
|
return c.int(os.Platform_Error.EOPNOTSUPP)
|
|
case .EPROTONOSUPPORT:
|
|
return c.int(os.Platform_Error.EPROTONOSUPPORT)
|
|
case .ENOBUFS:
|
|
return c.int(os.Platform_Error.ENOBUFS)
|
|
case .ENETDOWN:
|
|
return c.int(os.Platform_Error.ENETDOWN)
|
|
case .EADDRINUSE:
|
|
return c.int(os.Platform_Error.EADDRINUSE)
|
|
case .EADDRNOTAVAIL:
|
|
return c.int(os.Platform_Error.EADDRNOTAVAIL)
|
|
case .ECONNREFUSED:
|
|
return c.int(os.Platform_Error.ECONNREFUSED)
|
|
case .EINPROGRESS:
|
|
return c.int(os.Platform_Error.EINPROGRESS)
|
|
case .ENOTSOCK:
|
|
return c.int(os.Platform_Error.ENOTSOCK)
|
|
case .EMSGSIZE:
|
|
return c.int(os.Platform_Error.EMSGSIZE)
|
|
case .EAFNOSUPPORT:
|
|
return c.int(os.Platform_Error.EAFNOSUPPORT)
|
|
case .ENETUNREACH:
|
|
return c.int(os.Platform_Error.ENETUNREACH)
|
|
case .ECONNABORTED:
|
|
return c.int(os.Platform_Error.ECONNABORTED)
|
|
case .ECONNRESET:
|
|
return c.int(os.Platform_Error.ECONNRESET)
|
|
case .ENOTCONN:
|
|
return c.int(os.Platform_Error.ENOTCONN)
|
|
case .ETIMEDOUT:
|
|
return c.int(os.Platform_Error.ETIMEDOUT)
|
|
case .EHOSTUNREACH:
|
|
return c.int(os.Platform_Error.EHOSTUNREACH)
|
|
case .ENETRESET:
|
|
return c.int(os.Platform_Error.ENETRESET)
|
|
case:
|
|
return zmq_val
|
|
}
|
|
}
|
|
|
|
|
|
last_error :: proc() -> Error {
|
|
raw := errno()
|
|
normalized := normalize_to_zmq(raw)
|
|
|
|
#partial switch ZMQ_Error(normalized) {
|
|
case .ENOTSUP,
|
|
.EPROTONOSUPPORT,
|
|
.ENOBUFS,
|
|
.ENETDOWN,
|
|
.EADDRINUSE,
|
|
.EADDRNOTAVAIL,
|
|
.ECONNREFUSED,
|
|
.EINPROGRESS,
|
|
.ENOTSOCK,
|
|
.EMSGSIZE,
|
|
.EAFNOSUPPORT,
|
|
.ENETUNREACH,
|
|
.ECONNABORTED,
|
|
.ECONNRESET,
|
|
.ENOTCONN,
|
|
.ETIMEDOUT,
|
|
.EHOSTUNREACH,
|
|
.ENETRESET,
|
|
.EFSM,
|
|
.ENOCOMPATPROTO,
|
|
.ETERM,
|
|
.EMTHREAD:
|
|
return ZMQ_Error(normalized)
|
|
case:
|
|
return os.Platform_Error(raw)
|
|
}
|
|
}
|
|
|