Orginize
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Env parsers and sendmsg/fcntl helpers used by the POSIX syscall facade.
|
||||
* Pure functions — no executeKernel closure.
|
||||
*/
|
||||
import b4a from 'b4a'
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown> | null | undefined} env
|
||||
*/
|
||||
export function wantPosixSocketFdBridge(env) {
|
||||
const v = String(env?.BARE_OS_POSIX_SOCKET_FD_BRIDGE ?? '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
return v === '1' || v === 'true'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown> | null | undefined} env
|
||||
*/
|
||||
export function wantPosixFcntlBlockingWait(env) {
|
||||
const v = String(env?.BARE_OS_POSIX_FCNTL_BLOCKING_WAIT ?? '')
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
return v === '1' || v === 'true' || v === 'yes'
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown> | null | undefined} env
|
||||
*/
|
||||
export function bareOsPosixDgramRecvQueueMax(env) {
|
||||
const raw = String(env?.BARE_OS_POSIX_DGRAM_RECVQ_MAX ?? '').trim()
|
||||
const n = Math.floor(Number(raw))
|
||||
if (Number.isFinite(n) && n > 0) return Math.min(65536, n)
|
||||
return 256
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown> | null | undefined} env
|
||||
*/
|
||||
export function bareOsPosixDgramRecvBlockMsMax(env) {
|
||||
const raw = String(env?.BARE_OS_POSIX_DGRAM_RECV_BLOCK_MS_MAX ?? '').trim()
|
||||
const n = Math.floor(Number(raw))
|
||||
if (Number.isFinite(n) && n > 0) return Math.min(300000, n)
|
||||
return 30000
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown> | null | undefined} env
|
||||
*/
|
||||
export function bareOsPosixAcceptQueueMax(env) {
|
||||
const n = Math.floor(
|
||||
Number(String(env?.BARE_OS_POSIX_ACCEPT_QUEUE_MAX ?? '').trim()) || 0
|
||||
)
|
||||
const v = n > 0 ? n : 64
|
||||
return Math.min(1024, Math.max(1, v))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown> | null | undefined} env
|
||||
*/
|
||||
export function bareOsPosixAcceptBlockMsMax(env) {
|
||||
return bareOsPosixDgramRecvBlockMsMax(env)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown> | null | undefined} env
|
||||
*/
|
||||
export function bareOsFcntlLockWaitMsMax(env) {
|
||||
const raw = String(env?.BARE_OS_FCNTL_LOCK_WAIT_MS_MAX ?? '').trim()
|
||||
const n = Math.floor(Number(raw))
|
||||
if (Number.isFinite(n) && n > 0) return Math.min(300000, n)
|
||||
return 30000
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Record<string, unknown>} args
|
||||
* @param {Record<string, unknown>} c
|
||||
*/
|
||||
export function bareOsResolveCooperativeLockPath(args, c) {
|
||||
const p = String(args.path || '').trim()
|
||||
if (p.startsWith('/')) return p
|
||||
const fd = Number(args.fd)
|
||||
if (!Number.isFinite(fd)) return ''
|
||||
const k = String(fd >>> 0)
|
||||
const fds = c.bareOsLogicalFds
|
||||
const t =
|
||||
fds && typeof fds === 'object' && fds[k] != null ? String(fds[k]) : ''
|
||||
if (t.startsWith('/')) return t
|
||||
return ''
|
||||
}
|
||||
|
||||
/**
|
||||
* Non-empty ancillary / control payloads are rejected with ENOTSUP (schema 3 contract).
|
||||
* @param {Record<string, unknown>} args
|
||||
* @returns {string | null} reject reason key for diagnostics, or null if absent/empty
|
||||
*/
|
||||
export function bareOsSendmsgAncillaryRejectReason(args) {
|
||||
if (!args || typeof args !== 'object') return null
|
||||
if (Array.isArray(args.cmsgs) && args.cmsgs.length > 0) return 'cmsgs'
|
||||
const ctl = args.control
|
||||
if (ctl instanceof Uint8Array && ctl.byteLength > 0) return 'control'
|
||||
const clen = Number(args.controllen)
|
||||
if (Number.isFinite(clen) && clen > 0) return 'controllen'
|
||||
const mh = args.msgHdr
|
||||
if (mh && typeof mh === 'object') {
|
||||
const mhc = /** @type {Record<string, unknown>} */ (mh).control
|
||||
if (mhc instanceof Uint8Array && mhc.byteLength > 0)
|
||||
return 'msgHdr.control'
|
||||
const c2 = /** @type {Record<string, unknown>} */ (mh).cmsgs
|
||||
if (Array.isArray(c2) && c2.length > 0) return 'msgHdr.cmsgs'
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Flatten sendmsg iovec list (bounded) for the SOCK_DGRAM bridge.
|
||||
* @param {Record<string, unknown>} args
|
||||
* @returns {{ ok: true, buf: Uint8Array } | { ok: false, err: Record<string, unknown> }}
|
||||
*/
|
||||
export function bareOsFlattenSendmsgIovs(args) {
|
||||
const maxIovs = 16
|
||||
const maxPer = 65536
|
||||
const maxTotal = 1024 * 1024
|
||||
const iovs = Array.isArray(args.iovs) ? args.iovs : []
|
||||
let total = 0
|
||||
/** @type {Uint8Array[]} */
|
||||
const parts = []
|
||||
for (const iov of iovs.slice(0, maxIovs)) {
|
||||
if (!iov || typeof iov !== 'object') continue
|
||||
const io = /** @type {Record<string, unknown>} */ (iov)
|
||||
let chunk = io.buf ?? io.buffer ?? io.data
|
||||
if (chunk == null) continue
|
||||
if (typeof chunk === 'string') chunk = b4a.from(chunk, 'utf8')
|
||||
if (!(chunk instanceof Uint8Array)) {
|
||||
return {
|
||||
ok: false,
|
||||
err: {
|
||||
ok: false,
|
||||
op: 'sendmsg',
|
||||
code: 'EINVAL',
|
||||
errnoHint: 'EINVAL',
|
||||
posixAlignment: 'ENOTSUP',
|
||||
note: 'sendmsg: each iov buf must be Uint8Array or string'
|
||||
}
|
||||
}
|
||||
}
|
||||
const slice = chunk.byteLength > maxPer ? chunk.slice(0, maxPer) : chunk
|
||||
if (total + slice.byteLength > maxTotal) {
|
||||
return {
|
||||
ok: false,
|
||||
err: {
|
||||
ok: false,
|
||||
op: 'sendmsg',
|
||||
code: 'EMSGSIZE',
|
||||
errnoHint: 'EMSGSIZE',
|
||||
posixAlignment: 'partial',
|
||||
note: 'sendmsg: total iov length exceeds cap'
|
||||
}
|
||||
}
|
||||
}
|
||||
parts.push(slice)
|
||||
total += slice.byteLength
|
||||
}
|
||||
if (parts.length === 0 && args.buf != null) {
|
||||
let chunk = args.buf
|
||||
if (typeof chunk === 'string') chunk = b4a.from(chunk, 'utf8')
|
||||
if (!(chunk instanceof Uint8Array)) {
|
||||
return {
|
||||
ok: false,
|
||||
err: {
|
||||
ok: false,
|
||||
op: 'sendmsg',
|
||||
code: 'EINVAL',
|
||||
errnoHint: 'EINVAL'
|
||||
}
|
||||
}
|
||||
}
|
||||
const buf = chunk.byteLength > maxTotal ? chunk.slice(0, maxTotal) : chunk
|
||||
return { ok: true, buf }
|
||||
}
|
||||
if (parts.length === 0) {
|
||||
return {
|
||||
ok: false,
|
||||
err: {
|
||||
ok: false,
|
||||
op: 'sendmsg',
|
||||
code: 'EINVAL',
|
||||
errnoHint: 'EINVAL',
|
||||
note: 'sendmsg: args.iovs or args.buf required'
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
ok: true,
|
||||
buf: parts.length === 1 ? parts[0] : b4a.concat(parts)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user