@componentor/fs 3.0.24 → 3.0.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,8 +40,8 @@ var INODE = {
40
40
  // uint32 - byte offset into path table
41
41
  PATH_LENGTH: 8,
42
42
  // uint16 - length of path string
43
- RESERVED_10: 10,
44
- // uint16
43
+ NLINK: 10,
44
+ // uint16 - hard link count
45
45
  MODE: 12,
46
46
  // uint32 - permissions (e.g. 0o100644)
47
47
  SIZE: 16,
@@ -415,6 +415,7 @@ var VFSEngine = class {
415
415
  type,
416
416
  pathOffset,
417
417
  pathLength,
418
+ nlink: inodeView.getUint16(off + INODE.NLINK, true) || 1,
418
419
  mode: inodeView.getUint32(off + INODE.MODE, true),
419
420
  size,
420
421
  firstBlock,
@@ -449,6 +450,7 @@ var VFSEngine = class {
449
450
  type: v.getUint8(INODE.TYPE),
450
451
  pathOffset: v.getUint32(INODE.PATH_OFFSET, true),
451
452
  pathLength: v.getUint16(INODE.PATH_LENGTH, true),
453
+ nlink: v.getUint16(INODE.NLINK, true) || 1,
452
454
  mode: v.getUint32(INODE.MODE, true),
453
455
  size: v.getFloat64(INODE.SIZE, true),
454
456
  firstBlock: v.getUint32(INODE.FIRST_BLOCK, true),
@@ -475,7 +477,7 @@ var VFSEngine = class {
475
477
  v.setUint8(INODE.FLAGS + 2, 0);
476
478
  v.setUint32(INODE.PATH_OFFSET, inode.pathOffset, true);
477
479
  v.setUint16(INODE.PATH_LENGTH, inode.pathLength, true);
478
- v.setUint16(INODE.RESERVED_10, 0, true);
480
+ v.setUint16(INODE.NLINK, inode.nlink, true);
479
481
  v.setUint32(INODE.MODE, inode.mode, true);
480
482
  v.setFloat64(INODE.SIZE, inode.size, true);
481
483
  v.setUint32(INODE.FIRST_BLOCK, inode.firstBlock, true);
@@ -717,6 +719,7 @@ var VFSEngine = class {
717
719
  type,
718
720
  pathOffset: pathOff,
719
721
  pathLength: pathLen,
722
+ nlink: type === INODE_TYPE.DIRECTORY ? 2 : 1,
720
723
  mode,
721
724
  size,
722
725
  firstBlock,
@@ -869,6 +872,7 @@ var VFSEngine = class {
869
872
  if (idx === void 0) return { status: CODE_TO_STATUS.ENOENT };
870
873
  const inode = this.readInode(idx);
871
874
  if (inode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EISDIR };
875
+ inode.nlink = Math.max(0, inode.nlink - 1);
872
876
  this.freeBlockRange(inode.firstBlock, inode.blockCount);
873
877
  inode.type = INODE_TYPE.FREE;
874
878
  this.writeInode(idx, inode);
@@ -893,7 +897,21 @@ var VFSEngine = class {
893
897
  }
894
898
  encodeStatResponse(idx) {
895
899
  const inode = this.readInode(idx);
896
- const buf = new Uint8Array(49);
900
+ let nlink = inode.nlink;
901
+ if (inode.type === INODE_TYPE.DIRECTORY) {
902
+ const path = this.readPath(inode.pathOffset, inode.pathLength);
903
+ const children = this.getDirectChildren(path);
904
+ let subdirCount = 0;
905
+ for (const child of children) {
906
+ const childIdx = this.pathIndex.get(child);
907
+ if (childIdx !== void 0) {
908
+ const childInode = this.readInode(childIdx);
909
+ if (childInode.type === INODE_TYPE.DIRECTORY) subdirCount++;
910
+ }
911
+ }
912
+ nlink = 2 + subdirCount;
913
+ }
914
+ const buf = new Uint8Array(53);
897
915
  const view = new DataView(buf.buffer);
898
916
  view.setUint8(0, inode.type);
899
917
  view.setUint32(1, inode.mode, true);
@@ -904,6 +922,7 @@ var VFSEngine = class {
904
922
  view.setUint32(37, inode.uid, true);
905
923
  view.setUint32(41, inode.gid, true);
906
924
  view.setUint32(45, idx, true);
925
+ view.setUint32(49, nlink, true);
907
926
  return { status: 0, data: buf };
908
927
  }
909
928
  // ---- MKDIR ----
@@ -1216,9 +1235,26 @@ var VFSEngine = class {
1216
1235
  const target = this.readData(inode.firstBlock, inode.blockCount, inode.size);
1217
1236
  return { status: 0, data: target };
1218
1237
  }
1219
- // ---- LINK (hard link — copies the file) ----
1238
+ // ---- LINK (hard link — copies the file data, tracks nlink) ----
1220
1239
  link(existingPath, newPath) {
1221
- return this.copy(existingPath, newPath);
1240
+ existingPath = this.normalizePath(existingPath);
1241
+ newPath = this.normalizePath(newPath);
1242
+ const srcIdx = this.resolvePathComponents(existingPath, true);
1243
+ if (srcIdx === void 0) return { status: CODE_TO_STATUS.ENOENT };
1244
+ const srcInode = this.readInode(srcIdx);
1245
+ if (srcInode.type === INODE_TYPE.DIRECTORY) return { status: CODE_TO_STATUS.EPERM };
1246
+ if (this.pathIndex.has(newPath)) return { status: CODE_TO_STATUS.EEXIST };
1247
+ const result = this.copy(existingPath, newPath);
1248
+ if (result.status !== 0) return result;
1249
+ srcInode.nlink++;
1250
+ this.writeInode(srcIdx, srcInode);
1251
+ const destIdx = this.pathIndex.get(newPath);
1252
+ if (destIdx !== void 0) {
1253
+ const destInode = this.readInode(destIdx);
1254
+ destInode.nlink = srcInode.nlink;
1255
+ this.writeInode(destIdx, destInode);
1256
+ }
1257
+ return { status: 0 };
1222
1258
  }
1223
1259
  // ---- OPEN (file descriptor) ----
1224
1260
  open(path, flags, tabId) {
@@ -1634,26 +1670,26 @@ function handleRequest(tabId, buffer) {
1634
1670
  break;
1635
1671
  }
1636
1672
  case OP.FREAD: {
1637
- if (!data || data.byteLength < 12) {
1673
+ if (!data || data.byteLength < 16) {
1638
1674
  result = { status: 7 };
1639
1675
  break;
1640
1676
  }
1641
1677
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
1642
1678
  const fd = dv.getUint32(0, true);
1643
1679
  const length = dv.getUint32(4, true);
1644
- const pos = dv.getInt32(8, true);
1680
+ const pos = dv.getFloat64(8, true);
1645
1681
  result = engine.fread(fd, length, pos === -1 ? null : pos);
1646
1682
  break;
1647
1683
  }
1648
1684
  case OP.FWRITE: {
1649
- if (!data || data.byteLength < 8) {
1685
+ if (!data || data.byteLength < 12) {
1650
1686
  result = { status: 7 };
1651
1687
  break;
1652
1688
  }
1653
1689
  const dv = new DataView(data.buffer, data.byteOffset, data.byteLength);
1654
1690
  const fd = dv.getUint32(0, true);
1655
- const pos = dv.getInt32(4, true);
1656
- const writeData = data.subarray(8);
1691
+ const pos = dv.getFloat64(4, true);
1692
+ const writeData = data.subarray(12);
1657
1693
  result = engine.fwrite(fd, writeData, pos === -1 ? null : pos);
1658
1694
  break;
1659
1695
  }