/** * Live pathconf: union and read-only mirror paths affect _PC_NO_TRUNC / _PC_CHOWN_RESTRICTED. */ import { readFile } from 'node:fs/promises' import path from 'node:path' import { fileURLToPath } from 'node:url' import test from 'brittle' import b4a from 'b4a' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor async function loadBin(name) { const runtime = await readFile( path.join(__dirname, '../lib/runtime.js'), 'utf8' ) const body = await readFile( path.join(__dirname, `../src/${name}.js`), 'utf8' ) return new AsyncFunction( 'ctx', 'argv', `${runtime}\n${body}\nif (typeof run === 'function') return await run(ctx, argv)\n` ) } function bareOsPathconfFromIndexLogic(shellEnv, vfs) { return (pathArg, name) => { const k = String(name || '').trim() const p = vfs.resolveLogical(String(pathArg || '/').trim() || '/') const rawUnion = String(shellEnv.BARE_OS_VFS_UNION_PREFIXES || '') const underUnion = rawUnion .split(',') .map((s) => s.trim()) .filter((x) => x.startsWith('/')) .some((pre) => p === pre || p.startsWith(pre + '/')) const underMirror = p === '/mirror' || p.startsWith('/mirror/') const acctOn = shellEnv.BARE_OS_PERSONAL_ACCT_PREFIX === '1' || shellEnv.BARE_OS_PERSONAL_ACCT_PREFIX === 'true' const underPersonalAcct = acctOn && (p === '/.bare-os/acct' || p.startsWith('/.bare-os/acct/')) const table = { _PC_NAME_MAX: 255, _PC_NO_TRUNC: 1, _PC_CHOWN_RESTRICTED: 1 } if (k === '_PC_CHOWN_RESTRICTED') { if (underMirror) return 0 return 1 } if (k === '_PC_NO_TRUNC' && (underMirror || (underUnion && !underPersonalAcct))) return 0 if (table[k] === undefined) throw new Error('unknown: ' + k) return table[k] } } test('getconf pathconf _PC_NO_TRUNC is 0 under union prefix', async (t) => { const run = await loadBin('getconf') const logs = [] const shellEnv = { BARE_OS_VFS_UNION_PREFIXES: '/system' } const vfs = { resolveLogical(p) { return String(p || '/') } } const ctx = { b4a, exitCode: 0, env: shellEnv, vfs, bareOsPathconf: bareOsPathconfFromIndexLogic(shellEnv, vfs), console: { log(s) { logs.push(String(s)) }, error(s) { logs.push(String(s)) } } } await run(ctx, ['getconf', '_PC_NO_TRUNC', '/system/bin/foo']) t.is(ctx.exitCode, 0) t.is(logs.pop(), '0') }) test('getconf pathconf _PC_CHOWN_RESTRICTED is 0 on mirror tree', async (t) => { const run = await loadBin('getconf') const logs = [] const shellEnv = {} const vfs = { resolveLogical(p) { return String(p || '/') } } const ctx = { b4a, exitCode: 0, env: shellEnv, vfs, bareOsPathconf: bareOsPathconfFromIndexLogic(shellEnv, vfs), console: { log(s) { logs.push(String(s)) }, error(s) { logs.push(String(s)) } } } await run(ctx, ['getconf', '_PC_CHOWN_RESTRICTED', '/mirror/aux0/x']) t.is(ctx.exitCode, 0) t.is(logs.pop(), '0') }) test('getconf _SC_NPROCESSORS_ONLN delegates to bareOsGetconfSysconf', async (t) => { const run = await loadBin('getconf') const logs = [] const ctx = { b4a, exitCode: 0, env: { BARE_OS_NPROC: '8' }, console: { log(s) { logs.push(String(s)) }, error(s) { logs.push(String(s)) } }, bareOsGetconfSysconf(name) { if (name === '_SC_NPROCESSORS_ONLN') return '8' return null } } await run(ctx, ['getconf', '_SC_NPROCESSORS_ONLN']) t.is(ctx.exitCode, 0) t.is(logs[0], '8') }) test('getconf _SC_BARE_OS_PIPELINE_MAX_BYTES uses bareOsGetconfSysconf', async (t) => { const run = await loadBin('getconf') const logs = [] const ctx = { b4a, exitCode: 0, env: {}, console: { log(s) { logs.push(String(s)) }, error(s) { logs.push(String(s)) } }, bareOsGetconfSysconf(name) { if (name === '_SC_BARE_OS_PIPELINE_MAX_BYTES') return '999999' return null } } await run(ctx, ['getconf', '_SC_BARE_OS_PIPELINE_MAX_BYTES']) t.is(ctx.exitCode, 0) t.is(logs[0], '999999') }) test('pathconf _PC_NO_TRUNC stays 1 under union when personal acct prefix path', async (t) => { const run = await loadBin('getconf') const logs = [] const shellEnv = { BARE_OS_VFS_UNION_PREFIXES: '/.bare-os', BARE_OS_PERSONAL_ACCT_PREFIX: '1' } const vfs = { resolveLogical(p) { return String(p || '/') } } const ctx = { b4a, exitCode: 0, env: shellEnv, vfs, bareOsPathconf: bareOsPathconfFromIndexLogic(shellEnv, vfs), console: { log(s) { logs.push(String(s)) }, error(s) { logs.push(String(s)) } } } await run(ctx, ['getconf', '_PC_NO_TRUNC', '/.bare-os/acct/x/home']) t.is(ctx.exitCode, 0) t.is(logs.pop(), '1') })