vfs: make lchown update symlink metadata · nodejs/node@4345185 · GitHub
Skip to content

Commit 4345185

Browse files
trivikraduh95
authored andcommitted
vfs: make lchown update symlink metadata
Route mounted lchown operations through VFS lchown handling and add memory provider support that does not follow the final symlink. Signed-off-by: Kamat, Trivikram <16024985+trivikr@users.noreply.github.com> Assisted-by: openai:gpt-5.5 PR-URL: #64573 Fixes: #64572 Reviewed-By: Aviv Keller <me@aviv.sh> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 3bc0ee0 commit 4345185

6 files changed

Lines changed: 75 additions & 2 deletions

File tree

doc/api/vfs.md

Lines changed: 1 addition & 0 deletions

lib/internal/vfs/file_system.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,11 @@ class VirtualFileSystem {
506506
this[kProvider].chownSync(providerPath, uid, gid);
507507
}
508508

509+
lchownSync(filePath, uid, gid) {
510+
const providerPath = this.#toProviderPath(filePath);
511+
this[kProvider].lchownSync(providerPath, uid, gid);
512+
}
513+
509514
utimesSync(filePath, atime, mtime) {
510515
const providerPath = this.#toProviderPath(filePath);
511516
this[kProvider].utimesSync(providerPath, atime, mtime);
@@ -1234,7 +1239,7 @@ class VirtualFileSystem {
12341239

12351240
async lchown(filePath, uid, gid) {
12361241
const providerPath = toProviderPath(filePath);
1237-
provider.chownSync(providerPath, uid, gid);
1242+
provider.lchownSync(providerPath, uid, gid);
12381243
},
12391244

12401245
async utimes(filePath, atime, mtime) {

lib/internal/vfs/provider.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,18 @@ class VirtualProvider {
235235
throw new ERR_METHOD_NOT_IMPLEMENTED('renameSync');
236236
}
237237

238+
/**
239+
* Changes ownership of a path without following the final symbolic link.
240+
* Providers with symlink support should override this.
241+
* @param {string} path The path
242+
* @param {number} uid The user id
243+
* @param {number} gid The group id
244+
* @returns {void}
245+
*/
246+
lchownSync(path, uid, gid) {
247+
return this.chownSync(path, uid, gid);
248+
}
249+
238250
// === DEFAULT IMPLEMENTATIONS (built on primitives) ===
239251

240252
/**

lib/internal/vfs/providers/memory.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,13 @@ class MemoryProvider extends VirtualProvider {
986986
entry.ctime = DateNow();
987987
}
988988

989+
lchownSync(path, uid, gid) {
990+
const entry = this.#getEntry(path, 'chown', false);
991+
if (uid >= 0) entry.uid = uid;
992+
if (gid >= 0) entry.gid = gid;
993+
entry.ctime = DateNow();
994+
}
995+
989996
utimesSync(path, atime, mtime) {
990997
const entry = this.#getEntry(path, 'utime', true);
991998
entry.atime = toMs(atime);

lib/internal/vfs/setup.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ function createVfsHandlers() {
343343
vfsOpVoid(path, (vfs, n) => vfs.symlinkSync(target, n, type)),
344344
chmodSync: (path, mode) => vfsOpVoid(path, (vfs, n) => vfs.chmodSync(n, mode)),
345345
chownSync: (path, uid, gid) => vfsOpVoid(path, (vfs, n) => vfs.chownSync(n, uid, gid)),
346-
lchownSync: (path, uid, gid) => vfsOpVoid(path, (vfs, n) => vfs.chownSync(n, uid, gid)),
346+
lchownSync: (path, uid, gid) => vfsOpVoid(path, (vfs, n) => vfs.lchownSync(n, uid, gid)),
347347
utimesSync: (path, atime, mtime) =>
348348
vfsOpVoid(path, (vfs, n) => vfs.utimesSync(n, atime, mtime)),
349349
lutimesSync: (path, atime, mtime) =>
Lines changed: 48 additions & 0 deletions

0 commit comments

Comments
 (0)