Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions examples/run-example-output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { writeSync } from "fs";

export type WriteBytes = (
fd: number,
data: Uint8Array,
offset: number,
length: number,
) => number;

const writeBytes: WriteBytes = (fd, data, offset, length) =>
writeSync(fd, data, offset, length, null);

export function writeAllSync(
fd: number,
data: Uint8Array,
write: WriteBytes = writeBytes,
): void {
let offset = 0;
while (offset < data.byteLength) {
const written = write(fd, data, offset, data.byteLength - offset);
if (written <= 0) throw new Error("short write to guest output sink");
offset += written;
}
}
5 changes: 3 additions & 2 deletions examples/run-example.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
* npx tsx examples/run-example.ts /path/to/test.wasm
*/

import { closeSync, existsSync, openSync, readFileSync, statSync, writeSync } from "fs";
import { closeSync, existsSync, openSync, readFileSync, statSync } from "fs";
import { resolve, dirname, isAbsolute } from "path";
import { NodeKernelHost } from "../host/src/node-kernel-host";
import { tryResolveBinary } from "../host/src/binary-resolver";
import { writeAllSync } from "./run-example-output";
import { isWithinRealDirectory } from "./run-example-paths";

const repoRoot = resolve(dirname(new URL(import.meta.url).pathname), "..");
Expand Down Expand Up @@ -362,7 +363,7 @@ async function main() {
if (guestOutputFd === null) {
fallback.write(data);
} else {
writeSync(guestOutputFd, data);
writeAllSync(guestOutputFd, data);
}
};

Expand Down
26 changes: 26 additions & 0 deletions host/test/run-example-output.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, expect, it } from "vitest";
import { writeAllSync } from "../../examples/run-example-output";

describe("run-example guest output", () => {
it("preserves every byte across short synchronous writes", () => {
const chunks: Uint8Array[] = [];
const offsets: number[] = [];
const input = new Uint8Array([0, 255, 1, 128, 2]);

writeAllSync(7, input, (_fd, data, offset, length) => {
const written = Math.min(2, length);
offsets.push(offset);
chunks.push(new Uint8Array(data.subarray(offset, offset + written)));
return written;
});

expect(offsets).toEqual([0, 2, 4]);
expect(new Uint8Array(Buffer.concat(chunks))).toEqual(input);
});

it("fails instead of spinning when a write makes no progress", () => {
expect(() =>
writeAllSync(7, new Uint8Array([1]), () => 0),
).toThrow("short write to guest output sink");
});
});
Loading