Skip to content
Open
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
10 changes: 6 additions & 4 deletions packages/shim-deno/src/deno/stable/classes/FsFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { read } from "../functions/read.js";
import { readSync } from "../functions/readSync.js";
import { write } from "../functions/write.js";
import { writeSync } from "../functions/writeSync.js";
import { seek } from "../functions/seek.js";
import { seekSync } from "../functions/seekSync.js";

(Symbol as any).dispose ??= Symbol("Symbol.dispose");
(Symbol as any).asyncDispose ??= Symbol("Symbol.asyncDispose");
Expand Down Expand Up @@ -51,12 +53,12 @@ export class FsFile implements Deno.FsFile {
return readSync(this.rid, p);
}

seek(_offset: number, _whence: Deno.SeekMode): Promise<number> {
throw new Error("Method not implemented.");
async seek(offset: number, whence: Deno.SeekMode): Promise<number> {
return await seek(this.rid, offset, whence);
}

seekSync(_offset: number, _whence: Deno.SeekMode): number {
throw new Error("Method not implemented.");
seekSync(offset: number, whence: Deno.SeekMode): number {
return seekSync(this.rid, offset, whence);
}

async stat(): Promise<Deno.FileInfo> {
Expand Down
8 changes: 7 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/close.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@

import * as fs from "fs";

export const close: typeof Deno.close = fs.closeSync;
import { appends, positions } from "./seekSync.js";

export const close: typeof Deno.close = function close(fd) {
fs.closeSync(fd);
positions.delete(fd);
appends.delete(fd);
};
5 changes: 5 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { open as _open } from "fs";
import { promisify } from "util";

import { File } from "../classes/FsFile.js";
import { appends, positions } from "../functions/seekSync.js";
import { getFsFlag } from "../../internal/fs_flags.js";
import mapError from "../../internal/errorMap.js";

Expand All @@ -25,6 +26,10 @@ export const open: typeof Deno.open = async function open(
});
try {
const fd = await nodeOpen(path, flagMode, mode);
positions.set(fd, 0);
if (append) {
appends.add(fd);
}
return new File(fd);
} catch (err) {
throw mapError(err);
Expand Down
5 changes: 5 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/openSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { openSync as nodeOpenSync } from "fs";

import { File } from "../classes/FsFile.js";
import { appends, positions } from "../functions/seekSync.js";
import { getFsFlag } from "../../internal/fs_flags.js";
import mapError from "../../internal/errorMap.js";

Expand All @@ -22,6 +23,10 @@ export const openSync: typeof Deno.openSync = function openSync(
});
try {
const fd = nodeOpenSync(path, flagMode, mode);
positions.set(fd, 0);
if (append) {
appends.add(fd);
}
return new File(fd);
} catch (err) {
throw mapError(err);
Expand Down
14 changes: 13 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import { promisify } from "util";
import { read as nodeRead } from "fs";

import { appends, positions } from "./seekSync.js";

const _read = promisify(nodeRead);

export const read: typeof Deno.read = async function read(rid, buffer) {
Expand All @@ -13,7 +15,17 @@ export const read: typeof Deno.read = async function read(rid, buffer) {
return 0;
}

const { bytesRead } = await _read(rid, buffer, 0, buffer.length, null);
const position = positions.get(rid) ?? null;
const { bytesRead } = await _read(
rid,
buffer,
0,
buffer.length,
appends.has(rid) ? null : position,
);
if (position !== null) {
positions.set(rid, position + bytesRead);
}
// node returns 0 on EOF, Deno expects null
return bytesRead === 0 ? null : bytesRead;
};
14 changes: 13 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/readSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,20 @@

import * as fs from "fs";

import { appends, positions } from "./seekSync.js";

export const readSync: typeof Deno.readSync = (fd, buffer) => {
const bytesRead = fs.readSync(fd, buffer);
const position = positions.get(fd) ?? null;
const bytesRead = fs.readSync(
fd,
buffer,
0,
buffer.length,
appends.has(fd) ? null : position,
);
if (position !== null) {
positions.set(fd, position + bytesRead);
}
// node returns 0 on EOF, Deno expects null
return bytesRead === 0 ? null : bytesRead;
};
30 changes: 30 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/seek.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
///<reference path="../lib.deno.d.ts" />

import { fstat } from "fs";
import { promisify } from "util";

import { positions } from "./seekSync.js";

const nodeFstat = promisify(fstat);

export const seek: typeof Deno.seek = async function (fd, offset, whence) {
let p = positions.get(fd);
if (p == null) {
throw new Error("Bad file descriptor");
}
switch (whence) {
case Deno.SeekMode.Start:
p = Number(offset);
break;
case Deno.SeekMode.Current:
p += Number(offset);
break;
case Deno.SeekMode.End:
p = (await nodeFstat(fd)).size + Number(offset);
break;
default:
throw new TypeError(`Invalid seek mode: ${whence}`);
}
positions.set(fd, p!);
return p!;
};
28 changes: 28 additions & 0 deletions packages/shim-deno/src/deno/stable/functions/seekSync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
///<reference path="../lib.deno.d.ts" />

import { fstatSync } from "fs";

export const appends = new Set<number>();
export const positions = new Map<number, number>();

export const seekSync: typeof Deno.seekSync = function (fd, offset, whence) {
let p = positions.get(fd);
if (p == null) {
throw new Error("Bad file descriptor");
}
switch (whence) {
case Deno.SeekMode.Start:
p = Number(offset);
break;
case Deno.SeekMode.Current:
p += Number(offset);
break;
case Deno.SeekMode.End:
p = fstatSync(fd).size + Number(offset);
break;
default:
throw new TypeError(`Invalid seek mode: ${whence}`);
}
positions.set(fd, p!);
return p!;
};
14 changes: 13 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,21 @@
import * as fs from "fs";
import { promisify } from "util";

import { appends, positions } from "./seekSync.js";

const nodeWrite = promisify(fs.write);

export const write: typeof Deno.write = async (fd, data) => {
const { bytesWritten } = await nodeWrite(fd, data);
const position = positions.get(fd) ?? null;
const { bytesWritten } = await nodeWrite(
fd,
data,
0,
data.length,
appends.has(fd) ? null : position,
);
if (position !== null) {
positions.set(fd, position + bytesWritten);
}
return bytesWritten;
};
17 changes: 16 additions & 1 deletion packages/shim-deno/src/deno/stable/functions/writeSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,19 @@

import * as fs from "fs";

export const writeSync: typeof Deno.writeSync = fs.writeSync;
import { appends, positions } from "./seekSync.js";

export const writeSync: typeof Deno.writeSync = (fd, data) => {
const position = positions.get(fd) ?? null;
const bytesWritten = fs.writeSync(
fd,
data,
0,
data.length,
appends.has(fd) ? null : position,
);
if (position !== null) {
positions.set(fd, position + bytesWritten);
}
return bytesWritten;
};
8 changes: 0 additions & 8 deletions packages/shim-deno/tools/run_tests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,6 @@ const testsToSkip = new Set([
"openNotFound", // includes full path in node.js
"openModeWriteRead", // not implemented
"readFileIsDirectoryErrorCode", // todo(https://github.com/denoland/deno/issues/18629): re-enable
"seekStart", // not implemented
"seekSyncStart", // not implemented
"seekCurrent", // not implemented
"seekStartBigInt", // not implemented
"seekSyncCurrent", // not implemented
"seekEnd", // not implemented
"seekSyncEnd", // not implemented
"seekMode", // not implemented

// mkdir_test
"mkdirMode", // depends on Deno.umask
Expand Down