Skip to content

Commit

Permalink
feat(node/fs): Add a chmod method to the FileHandle class (#27522)
Browse files Browse the repository at this point in the history
Add the chmod method to the FileHandle class in node compat as part of
#25554
  • Loading branch information
nkaradzhov authored and dsherret committed Jan 9, 2025
1 parent cae818a commit fa20ffb
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
2 changes: 1 addition & 1 deletion ext/node/polyfills/_fs/_fs_open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
});
});
}
Expand Down
19 changes: 15 additions & 4 deletions ext/node/polyfills/internal/fs/handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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() {
Expand Down Expand Up @@ -144,17 +148,24 @@ export class FileHandle extends EventEmitter {
stat(options?: { bigint: boolean }): Promise<Stats | BigIntStats> {
return fsCall(promises.fstat, this, options);
}
chmod(mode: Mode): Promise<void> {
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);
}

Expand Down
18 changes: 18 additions & 0 deletions tests/unit_node/_fs/_fs_handle_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
},
});

0 comments on commit fa20ffb

Please sign in to comment.