if=/dev/zero with finite count*bs now produces requested size directly (not limited by VFS 64KiB pseudo-file). Raw stdout now uses bareOsEmitRaw, improving pipeline correctness. Fixed pipeline capture path for FIFO-relevant commands echo and cat now emit via bareOsEmitRaw (packages/bare-os-coreutils/src/echo.js, packages/bare-os-coreutils/src/cat.js). Shell pipeline now injects bareOsBinWrite into child contexts when output is captured, so raw writes are captured (packages/bare-os-booter/lib/shell.js). Improved xattr behavior in packages/bare-os-coreutils/src/xattr.js Added -p/--print NAME. -w now logs written attribute name for visible success feedback. Roundtrip behaviors preserved with sidecar metadata format. Improved ACL UX in: packages/bare-os-coreutils/src/getfacl.js Explicit source header for sidecar and mode fallback (non-compact mode). packages/bare-os-coreutils/src/setfacl.js Added -m/--modify ENTRY in addition to stdin blob and -b. Implemented dynamic ulimit output in packages/bare-os-coreutils/src/ulimit.js Reads /proc/bare_os/rlimits.json when available. Supports -a, -n, -Sn, -Hn. Added shuf -e support in packages/bare-os-coreutils/src/shuf.js. Added split byte-suffix parsing (k/K/m/M/g/G) and attached -bSIZE support in packages/bare-os-coreutils/src/split.js.
112 lines
3.0 KiB
JavaScript
112 lines
3.0 KiB
JavaScript
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`
|
|
)
|
|
}
|
|
|
|
test('dd honors large /dev/zero count*bs output', async (t) => {
|
|
const run = await loadBin('dd')
|
|
/** @type {number[]} */
|
|
const rawChunks = []
|
|
const ctx = {
|
|
b4a,
|
|
exitCode: 0,
|
|
shellStdin: '',
|
|
bareOsBinWrite: (u8) => rawChunks.push(u8.byteLength),
|
|
console: { log: () => {}, error: () => {} },
|
|
vfs: {
|
|
async readFile(p) {
|
|
if (p === '/dev/zero') return new Uint8Array(65536)
|
|
return null
|
|
},
|
|
async writeFile() {}
|
|
}
|
|
}
|
|
await run(ctx, ['dd', 'if=/dev/zero', 'bs=1M', 'count=2', 'status=none'])
|
|
t.is(ctx.exitCode, 0)
|
|
t.is(rawChunks.reduce((a, b) => a + b, 0), 2 * 1024 * 1024)
|
|
})
|
|
|
|
test('shuf -e shuffles operands directly', async (t) => {
|
|
const run = await loadBin('shuf')
|
|
/** @type {string[]} */
|
|
const logs = []
|
|
const ctx = {
|
|
b4a,
|
|
exitCode: 0,
|
|
shellStdin: '',
|
|
console: { log: (m) => logs.push(String(m)), error: () => {} },
|
|
vfs: {
|
|
env: { BARE_OS_SHUF_SEED: 'seed' },
|
|
async readFile() {
|
|
return null
|
|
}
|
|
}
|
|
}
|
|
await run(ctx, ['shuf', '-e', 'a', 'b', 'c'])
|
|
t.is(ctx.exitCode, 0)
|
|
t.is(logs.length, 3)
|
|
t.alike([...logs].sort(), ['a', 'b', 'c'])
|
|
})
|
|
|
|
test('split accepts -b1k suffix', async (t) => {
|
|
const run = await loadBin('split')
|
|
/** @type {Record<string, Uint8Array>} */
|
|
const out = {}
|
|
const input = b4a.alloc(2050, 120)
|
|
const ctx = {
|
|
b4a,
|
|
exitCode: 0,
|
|
shellStdin: '',
|
|
console: { log: () => {}, error: () => {} },
|
|
vfs: {
|
|
env: {},
|
|
async readFile(p) {
|
|
return p === '/in' ? input : out[p] || null
|
|
},
|
|
async writeFile(p, body) {
|
|
out[p] = body instanceof Uint8Array ? body : b4a.from(body)
|
|
}
|
|
}
|
|
}
|
|
await run(ctx, ['split', '-b1k', '/in', '/tmp/x'])
|
|
t.is(ctx.exitCode, 0)
|
|
t.is(out['/tmp/xaa'].byteLength, 1024)
|
|
t.is(out['/tmp/xab'].byteLength, 1024)
|
|
t.is(out['/tmp/xac'].byteLength, 2)
|
|
})
|
|
|
|
test('ulimit -Sn reads runtime soft nofile when present', async (t) => {
|
|
const run = await loadBin('ulimit')
|
|
/** @type {string[]} */
|
|
const logs = []
|
|
const ctx = {
|
|
b4a,
|
|
exitCode: 0,
|
|
shellStdin: '',
|
|
console: { log: (m) => logs.push(String(m)), error: () => {} },
|
|
vfs: {
|
|
async readFile(p) {
|
|
if (p !== '/proc/bare_os/rlimits.json') return null
|
|
return b4a.from(JSON.stringify({ soft_nofile: 4096, hard_nofile: 8192 }))
|
|
}
|
|
}
|
|
}
|
|
await run(ctx, ['ulimit', '-Sn'])
|
|
t.is(ctx.exitCode, 0)
|
|
t.is(logs[0], '4096')
|
|
})
|