diff --git a/ext/node/polyfills/_fs/_fs_open.ts b/ext/node/polyfills/_fs/_fs_open.ts index 85628ddcef..12f8ed7035 100644 --- a/ext/node/polyfills/_fs/_fs_open.ts +++ b/ext/node/polyfills/_fs/_fs_open.ts @@ -153,7 +153,7 @@ export function openPromise( return new Promise((resolve, reject) => { open(path, flags, mode, (err, fd) => { if (err) reject(err); - else resolve(new FileHandle(fd)); + else resolve(new FileHandle(fd, path)); }); }); } diff --git a/ext/node/polyfills/internal/fs/handle.ts b/ext/node/polyfills/internal/fs/handle.ts index ace9a7635c..2d787a9f3b 100644 --- a/ext/node/polyfills/internal/fs/handle.ts +++ b/ext/node/polyfills/internal/fs/handle.ts @@ -5,7 +5,7 @@ import { EventEmitter } from "node:events"; import { Buffer } from "node:buffer"; -import { promises, read, write } from "node:fs"; +import { Mode, promises, read, write } from "node:fs"; export type { BigIntStats, Stats } from "ext:deno_node/_fs/_fs_stat.ts"; import { BinaryOptionsArgument, @@ -26,11 +26,15 @@ interface ReadResult { buffer: Buffer; } +type Path = string | Buffer | URL; export class FileHandle extends EventEmitter { #rid: number; - constructor(rid: number) { + #path: Path; + + constructor(rid: number, path: Path) { super(); this.#rid = rid; + this.#path = path; } get fd() { @@ -144,17 +148,24 @@ export class FileHandle extends EventEmitter { stat(options?: { bigint: boolean }): Promise { return fsCall(promises.fstat, this, options); } + chmod(mode: Mode): Promise { + assertNotClosed(this, promises.chmod.name); + return promises.chmod(this.#path, mode); + } } -function fsCall(fn, handle, ...args) { +function assertNotClosed(handle: FileHandle, syscall: string) { if (handle.fd === -1) { const err = new Error("file closed"); throw Object.assign(err, { code: "EBADF", - syscall: fn.name, + syscall, }); } +} +function fsCall(fn, handle, ...args) { + assertNotClosed(handle, fn.name); return fn(handle.fd, ...args); } diff --git a/tests/unit_node/_fs/_fs_handle_test.ts b/tests/unit_node/_fs/_fs_handle_test.ts index 61214bde26..e4a41f8ba7 100644 --- a/tests/unit_node/_fs/_fs_handle_test.ts +++ b/tests/unit_node/_fs/_fs_handle_test.ts @@ -199,3 +199,21 @@ Deno.test( assertEquals(data.length, 0); }, ); + +Deno.test({ + name: "[node/fs filehandle.chmod] Change the permissions of the file", + ignore: Deno.build.os === "windows", + async fn() { + const fileHandle = await fs.open(testData); + + const readOnly = 0o444; + await fileHandle.chmod(readOnly.toString(8)); + assertEquals(Deno.statSync(testData).mode! & 0o777, readOnly); + + const readWrite = 0o666; + await fileHandle.chmod(readWrite.toString(8)); + assertEquals(Deno.statSync(testData).mode! & 0o777, readWrite); + + await fileHandle.close(); + }, +});