Skip to content

Commit 5cdda14

Browse files
authored
[FS] Make fstat work on file descriptors with no name in memfs (#23470)
This makes fstat work on anonymous memfs file descriptors. It is split off from #23058.
1 parent 738a20a commit 5cdda14

21 files changed

+70
-53
lines changed

src/lib/libfs.js

Lines changed: 49 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,13 @@ FS.staticInit();
487487
stream.stream_ops?.dup?.(stream);
488488
return stream;
489489
},
490+
doSetAttr(stream, node, attr) {
491+
var setattr = stream?.stream_ops.setattr;
492+
var arg = setattr ? stream : node;
493+
setattr ??= node.node_ops.setattr;
494+
FS.checkOpExists(setattr, {{{ cDefs.EPERM }}})
495+
setattr(arg, attr);
496+
},
490497

491498
//
492499
// devices
@@ -966,11 +973,24 @@ FS.staticInit();
966973
return getattr(node);
967974
},
968975
fstat(fd) {
969-
return FS.stat(FS.getStreamChecked(fd).path);
976+
var stream = FS.getStreamChecked(fd);
977+
var node = stream.node;
978+
var getattr = stream.stream_ops.getattr;
979+
var arg = getattr ? stream : node;
980+
getattr ??= node.node_ops.getattr;
981+
FS.checkOpExists(getattr, {{{ cDefs.EPERM }}})
982+
return getattr(arg);
970983
},
971984
lstat(path) {
972985
return FS.stat(path, true);
973986
},
987+
doChmod(stream, node, mode, dontFollow) {
988+
FS.doSetAttr(stream, node, {
989+
mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (node.mode & ~{{{ cDefs.S_IALLUGO }}}),
990+
ctime: Date.now(),
991+
dontFollow
992+
});
993+
},
974994
chmod(path, mode, dontFollow) {
975995
var node;
976996
if (typeof path == 'string') {
@@ -979,19 +999,21 @@ FS.staticInit();
979999
} else {
9801000
node = path;
9811001
}
982-
var setattr = FS.checkOpExists(node.node_ops.setattr, {{{ cDefs.EPERM }}});
983-
setattr(node, {
984-
mode: (mode & {{{ cDefs.S_IALLUGO }}}) | (node.mode & ~{{{ cDefs.S_IALLUGO }}}),
985-
ctime: Date.now(),
986-
dontFollow
987-
});
1002+
FS.doChmod(null, node, mode, dontFollow);
9881003
},
9891004
lchmod(path, mode) {
9901005
FS.chmod(path, mode, true);
9911006
},
9921007
fchmod(fd, mode) {
9931008
var stream = FS.getStreamChecked(fd);
994-
FS.chmod(stream.node, mode);
1009+
FS.doChmod(stream, stream.node, mode, false);
1010+
},
1011+
doChown(stream, node, dontFollow) {
1012+
FS.doSetAttr(stream, node, {
1013+
timestamp: Date.now(),
1014+
dontFollow
1015+
// we ignore the uid / gid for now
1016+
});
9951017
},
9961018
chown(path, uid, gid, dontFollow) {
9971019
var node;
@@ -1001,31 +1023,16 @@ FS.staticInit();
10011023
} else {
10021024
node = path;
10031025
}
1004-
var setattr = FS.checkOpExists(node.node_ops.setattr, {{{ cDefs.EPERM }}});
1005-
setattr(node, {
1006-
timestamp: Date.now(),
1007-
dontFollow
1008-
// we ignore the uid / gid for now
1009-
});
1026+
FS.doChown(null, node, dontFollow);
10101027
},
10111028
lchown(path, uid, gid) {
10121029
FS.chown(path, uid, gid, true);
10131030
},
10141031
fchown(fd, uid, gid) {
10151032
var stream = FS.getStreamChecked(fd);
1016-
FS.chown(stream.node, uid, gid);
1033+
FS.doChown(stream, stream.node, false);
10171034
},
1018-
truncate(path, len) {
1019-
if (len < 0) {
1020-
throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
1021-
}
1022-
var node;
1023-
if (typeof path == 'string') {
1024-
var lookup = FS.lookupPath(path, { follow: true });
1025-
node = lookup.node;
1026-
} else {
1027-
node = path;
1028-
}
1035+
doTruncate(stream, node, len) {
10291036
if (FS.isDir(node.mode)) {
10301037
throw new FS.ErrnoError({{{ cDefs.EISDIR }}});
10311038
}
@@ -1036,18 +1043,30 @@ FS.staticInit();
10361043
if (errCode) {
10371044
throw new FS.ErrnoError(errCode);
10381045
}
1039-
var setattr = FS.checkOpExists(node.node_ops.setattr, {{{ cDefs.EPERM }}});
1040-
setattr(node, {
1046+
FS.doSetAttr(stream, node, {
10411047
size: len,
10421048
timestamp: Date.now()
10431049
});
10441050
},
1051+
truncate(path, len) {
1052+
if (len < 0) {
1053+
throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
1054+
}
1055+
var node;
1056+
if (typeof path == 'string') {
1057+
var lookup = FS.lookupPath(path, { follow: true });
1058+
node = lookup.node;
1059+
} else {
1060+
node = path;
1061+
}
1062+
FS.doTruncate(null, node, len);
1063+
},
10451064
ftruncate(fd, len) {
10461065
var stream = FS.getStreamChecked(fd);
1047-
if ((stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) {
1066+
if (len < 0 || (stream.flags & {{{ cDefs.O_ACCMODE }}}) === {{{ cDefs.O_RDONLY}}}) {
10481067
throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
10491068
}
1050-
FS.truncate(stream.node, len);
1069+
FS.doTruncate(stream, stream.node, len);
10511070
},
10521071
utime(path, atime, mtime) {
10531072
var lookup = FS.lookupPath(path, { follow: true });
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8343
1+
8359
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20273
1+
20296
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8327
1+
8341
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20241
1+
20264
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9343
1+
9358
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
24041
1+
24064
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8294
1+
8303
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20166
1+
20189
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
8294
1+
8303

0 commit comments

Comments
 (0)