@php-wasm/node 3.1.41 → 3.1.42

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.
Files changed (3) hide show
  1. package/index.cjs +29 -22
  2. package/index.js +29 -22
  3. package/package.json +14 -14
package/index.cjs CHANGED
@@ -482,13 +482,18 @@ function bindUserSpace({ fileLockManager }, {
482
482
  }
483
483
  const locking = {
484
484
  /*
485
- * This is a set of possibly locked file descriptors.
485
+ * Possibly locked file descriptors and their last known native paths.
486
+ * The path must be captured when the lock succeeds because close-time
487
+ * cleanup may run after the file is unlinked.
486
488
  *
487
- * When a file descriptor is closed, we need to release any associated held by this process.
488
- * Instead of trying remember and forget file descriptors as they are locked and unlocked,
489
- * we just track file descriptors we have locked before and try an unlock when they are closed.
489
+ * WARNING: This fixes cleanup when a known path disappears before
490
+ * close, but it does not make path-keyed lock bookkeeping rename-safe.
491
+ * If a locked file is renamed, later lock operations may address the
492
+ * same underlying file through a different path than the one stored
493
+ * here. Correctly handling that requires stable file identity tracking,
494
+ * such as device/inode keys or rename-aware lock manager updates.
490
495
  */
491
- maybeLockedFds: /* @__PURE__ */ new Set(),
496
+ maybeLockedFdPaths: /* @__PURE__ */ new Map(),
492
497
  lockStateToFcntl: {
493
498
  shared: F_RDLCK,
494
499
  exclusive: F_WRLCK,
@@ -905,7 +910,10 @@ function bindUserSpace({ fileLockManager }, {
905
910
  waitForLock
906
911
  );
907
912
  if (succeeded) {
908
- locking.maybeLockedFds.add(nativeFd);
913
+ locking.maybeLockedFdPaths.set(
914
+ nativeFd,
915
+ nativeFilePath
916
+ );
909
917
  }
910
918
  js_wasm_trace(
911
919
  "fcntl(%d, F_SETLK) %s lockFileByteRange returned %d for range lock %s",
@@ -1024,7 +1032,7 @@ function bindUserSpace({ fileLockManager }, {
1024
1032
  succeeded
1025
1033
  );
1026
1034
  if (succeeded) {
1027
- locking.maybeLockedFds.add(nativeFd);
1035
+ locking.maybeLockedFdPaths.set(nativeFd, nativeFilePath);
1028
1036
  }
1029
1037
  return succeeded ? 0 : -EWOULDBLOCK;
1030
1038
  } catch (e) {
@@ -1042,6 +1050,7 @@ function bindUserSpace({ fileLockManager }, {
1042
1050
  }
1043
1051
  const [vfsPath, vfsPathResolutionErrno] = locking.get_vfs_path_from_fd(fd);
1044
1052
  const [nativeFd, nativeFdErrno] = locking.get_native_fd_from_emscripten_fd(fd);
1053
+ const nativeFilePath = nativeFdErrno === 0 ? locking.maybeLockedFdPaths.get(nativeFd) : void 0;
1045
1054
  const fdCloseResult = builtin_fd_close(fd);
1046
1055
  if (fdCloseResult !== 0) {
1047
1056
  js_wasm_trace(
@@ -1052,38 +1061,33 @@ function bindUserSpace({ fileLockManager }, {
1052
1061
  );
1053
1062
  return fdCloseResult;
1054
1063
  }
1055
- if (!locking.maybeLockedFds.has(nativeFd)) {
1064
+ if (nativeFdErrno !== 0) {
1056
1065
  js_wasm_trace(
1057
- "fd_close(%d) not in maybe-locked-list %s result %d",
1066
+ "fd_close(%d) %s get_native_fd_from_emscripten_fd error %d",
1058
1067
  fd,
1059
1068
  vfsPath,
1060
- fdCloseResult
1069
+ nativeFdErrno
1061
1070
  );
1062
1071
  return fdCloseResult;
1063
1072
  }
1064
- if (vfsPathResolutionErrno !== 0) {
1073
+ if (nativeFilePath === void 0) {
1065
1074
  js_wasm_trace(
1066
- "fd_close(%d) get_vfs_path_from_fd error %d",
1075
+ "fd_close(%d) not in maybe-locked-list %s result %d",
1067
1076
  fd,
1068
- vfsPathResolutionErrno
1077
+ vfsPath,
1078
+ fdCloseResult
1069
1079
  );
1070
1080
  return fdCloseResult;
1071
1081
  }
1072
- if (nativeFdErrno !== 0) {
1082
+ if (vfsPathResolutionErrno !== 0) {
1073
1083
  js_wasm_trace(
1074
- "fd_close(%d) %s get_native_fd_from_emscripten_fd error %d",
1084
+ "fd_close(%d) get_vfs_path_from_fd error %d",
1075
1085
  fd,
1076
- vfsPath,
1077
- nativeFdErrno
1086
+ vfsPathResolutionErrno
1078
1087
  );
1079
- return fdCloseResult;
1080
- }
1081
- if (!locking.is_path_to_shared_fs(vfsPath)) {
1082
- return fdCloseResult;
1083
1088
  }
1084
1089
  try {
1085
1090
  js_wasm_trace("fd_close(%d) %s release locks", fd, vfsPath);
1086
- const nativeFilePath = locking.get_native_path_from_vfs_path(vfsPath);
1087
1091
  fileLockManager.releaseLocksOnFdClose(
1088
1092
  pid,
1089
1093
  nativeFd,
@@ -1092,6 +1096,8 @@ function bindUserSpace({ fileLockManager }, {
1092
1096
  js_wasm_trace("fd_close(%d) %s release locks success", fd, vfsPath);
1093
1097
  } catch (e) {
1094
1098
  js_wasm_trace("fd_close(%d) %s error '%s'", fd, vfsPath, e);
1099
+ } finally {
1100
+ locking.maybeLockedFdPaths.delete(nativeFd);
1095
1101
  }
1096
1102
  return fdCloseResult;
1097
1103
  }
@@ -1109,6 +1115,7 @@ function bindUserSpace({ fileLockManager }, {
1109
1115
  }
1110
1116
  try {
1111
1117
  fileLockManager.releaseLocksForProcess(pid);
1118
+ locking.maybeLockedFdPaths.clear();
1112
1119
  js_wasm_trace("js_release_file_locks succeeded");
1113
1120
  } catch (e) {
1114
1121
  js_wasm_trace("js_release_file_locks error %s", e);
package/index.js CHANGED
@@ -457,13 +457,18 @@ function bindUserSpace({ fileLockManager }, {
457
457
  }
458
458
  const locking = {
459
459
  /*
460
- * This is a set of possibly locked file descriptors.
460
+ * Possibly locked file descriptors and their last known native paths.
461
+ * The path must be captured when the lock succeeds because close-time
462
+ * cleanup may run after the file is unlinked.
461
463
  *
462
- * When a file descriptor is closed, we need to release any associated held by this process.
463
- * Instead of trying remember and forget file descriptors as they are locked and unlocked,
464
- * we just track file descriptors we have locked before and try an unlock when they are closed.
464
+ * WARNING: This fixes cleanup when a known path disappears before
465
+ * close, but it does not make path-keyed lock bookkeeping rename-safe.
466
+ * If a locked file is renamed, later lock operations may address the
467
+ * same underlying file through a different path than the one stored
468
+ * here. Correctly handling that requires stable file identity tracking,
469
+ * such as device/inode keys or rename-aware lock manager updates.
465
470
  */
466
- maybeLockedFds: /* @__PURE__ */ new Set(),
471
+ maybeLockedFdPaths: /* @__PURE__ */ new Map(),
467
472
  lockStateToFcntl: {
468
473
  shared: F_RDLCK,
469
474
  exclusive: F_WRLCK,
@@ -880,7 +885,10 @@ function bindUserSpace({ fileLockManager }, {
880
885
  waitForLock
881
886
  );
882
887
  if (succeeded) {
883
- locking.maybeLockedFds.add(nativeFd);
888
+ locking.maybeLockedFdPaths.set(
889
+ nativeFd,
890
+ nativeFilePath
891
+ );
884
892
  }
885
893
  js_wasm_trace(
886
894
  "fcntl(%d, F_SETLK) %s lockFileByteRange returned %d for range lock %s",
@@ -999,7 +1007,7 @@ function bindUserSpace({ fileLockManager }, {
999
1007
  succeeded
1000
1008
  );
1001
1009
  if (succeeded) {
1002
- locking.maybeLockedFds.add(nativeFd);
1010
+ locking.maybeLockedFdPaths.set(nativeFd, nativeFilePath);
1003
1011
  }
1004
1012
  return succeeded ? 0 : -EWOULDBLOCK;
1005
1013
  } catch (e) {
@@ -1017,6 +1025,7 @@ function bindUserSpace({ fileLockManager }, {
1017
1025
  }
1018
1026
  const [vfsPath, vfsPathResolutionErrno] = locking.get_vfs_path_from_fd(fd);
1019
1027
  const [nativeFd, nativeFdErrno] = locking.get_native_fd_from_emscripten_fd(fd);
1028
+ const nativeFilePath = nativeFdErrno === 0 ? locking.maybeLockedFdPaths.get(nativeFd) : void 0;
1020
1029
  const fdCloseResult = builtin_fd_close(fd);
1021
1030
  if (fdCloseResult !== 0) {
1022
1031
  js_wasm_trace(
@@ -1027,38 +1036,33 @@ function bindUserSpace({ fileLockManager }, {
1027
1036
  );
1028
1037
  return fdCloseResult;
1029
1038
  }
1030
- if (!locking.maybeLockedFds.has(nativeFd)) {
1039
+ if (nativeFdErrno !== 0) {
1031
1040
  js_wasm_trace(
1032
- "fd_close(%d) not in maybe-locked-list %s result %d",
1041
+ "fd_close(%d) %s get_native_fd_from_emscripten_fd error %d",
1033
1042
  fd,
1034
1043
  vfsPath,
1035
- fdCloseResult
1044
+ nativeFdErrno
1036
1045
  );
1037
1046
  return fdCloseResult;
1038
1047
  }
1039
- if (vfsPathResolutionErrno !== 0) {
1048
+ if (nativeFilePath === void 0) {
1040
1049
  js_wasm_trace(
1041
- "fd_close(%d) get_vfs_path_from_fd error %d",
1050
+ "fd_close(%d) not in maybe-locked-list %s result %d",
1042
1051
  fd,
1043
- vfsPathResolutionErrno
1052
+ vfsPath,
1053
+ fdCloseResult
1044
1054
  );
1045
1055
  return fdCloseResult;
1046
1056
  }
1047
- if (nativeFdErrno !== 0) {
1057
+ if (vfsPathResolutionErrno !== 0) {
1048
1058
  js_wasm_trace(
1049
- "fd_close(%d) %s get_native_fd_from_emscripten_fd error %d",
1059
+ "fd_close(%d) get_vfs_path_from_fd error %d",
1050
1060
  fd,
1051
- vfsPath,
1052
- nativeFdErrno
1061
+ vfsPathResolutionErrno
1053
1062
  );
1054
- return fdCloseResult;
1055
- }
1056
- if (!locking.is_path_to_shared_fs(vfsPath)) {
1057
- return fdCloseResult;
1058
1063
  }
1059
1064
  try {
1060
1065
  js_wasm_trace("fd_close(%d) %s release locks", fd, vfsPath);
1061
- const nativeFilePath = locking.get_native_path_from_vfs_path(vfsPath);
1062
1066
  fileLockManager.releaseLocksOnFdClose(
1063
1067
  pid,
1064
1068
  nativeFd,
@@ -1067,6 +1071,8 @@ function bindUserSpace({ fileLockManager }, {
1067
1071
  js_wasm_trace("fd_close(%d) %s release locks success", fd, vfsPath);
1068
1072
  } catch (e) {
1069
1073
  js_wasm_trace("fd_close(%d) %s error '%s'", fd, vfsPath, e);
1074
+ } finally {
1075
+ locking.maybeLockedFdPaths.delete(nativeFd);
1070
1076
  }
1071
1077
  return fdCloseResult;
1072
1078
  }
@@ -1084,6 +1090,7 @@ function bindUserSpace({ fileLockManager }, {
1084
1090
  }
1085
1091
  try {
1086
1092
  fileLockManager.releaseLocksForProcess(pid);
1093
+ locking.maybeLockedFdPaths.clear();
1087
1094
  js_wasm_trace("js_release_file_locks succeeded");
1088
1095
  } catch (e) {
1089
1096
  js_wasm_trace("js_release_file_locks error %s", e);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@php-wasm/node",
3
- "version": "3.1.41",
3
+ "version": "3.1.42",
4
4
  "description": "PHP.wasm for Node.js",
5
5
  "repository": {
6
6
  "type": "git",
@@ -42,20 +42,20 @@
42
42
  "fs-ext-extra-prebuilt": "2.2.7",
43
43
  "wasm-feature-detect": "1.8.0",
44
44
  "ws": "8.21.0",
45
- "@php-wasm/universal": "3.1.41",
46
- "@php-wasm/node-8-5": "3.1.41",
47
- "@php-wasm/node-8-4": "3.1.41",
48
- "@php-wasm/node-8-3": "3.1.41",
49
- "@php-wasm/node-8-2": "3.1.41",
50
- "@php-wasm/node-8-1": "3.1.41",
51
- "@php-wasm/node-8-0": "3.1.41",
52
- "@php-wasm/node-7-4": "3.1.41",
53
- "@php-wasm/cli-util": "3.1.41",
54
- "@php-wasm/logger": "3.1.41",
55
- "@php-wasm/node-5-2": "3.1.41",
56
- "@php-wasm/util": "3.1.41"
45
+ "@php-wasm/universal": "3.1.42",
46
+ "@php-wasm/node-8-5": "3.1.42",
47
+ "@php-wasm/node-8-4": "3.1.42",
48
+ "@php-wasm/node-8-3": "3.1.42",
49
+ "@php-wasm/node-8-2": "3.1.42",
50
+ "@php-wasm/node-8-1": "3.1.42",
51
+ "@php-wasm/node-8-0": "3.1.42",
52
+ "@php-wasm/node-7-4": "3.1.42",
53
+ "@php-wasm/cli-util": "3.1.42",
54
+ "@php-wasm/logger": "3.1.42",
55
+ "@php-wasm/node-5-2": "3.1.42",
56
+ "@php-wasm/util": "3.1.42"
57
57
  },
58
- "gitHead": "d32ef94fc8b765bd0c6ed7d5ba32e2ebd34b8a75",
58
+ "gitHead": "827bc91f5d6022e5c3cae3b79edaa14101a4fced",
59
59
  "engines": {
60
60
  "node": ">=20.10.0",
61
61
  "npm": ">=10.2.3"