Repository: denoland/deno
Pull request: fix(ext/node): add disabled process function stubs in worker threads

## Summary

- In worker threads, replace `process.abort`, `process.chdir`, `process.send`, `process.disconnect`, and uid/gid setters (`setuid`, `seteuid`, `setgid`, `setegid`, `setgroups`, `initgroups`) with stubs that have `.disabled = true` and throw `ERR_WORKER_UNSUPPORTED_OPERATION`
- Make `process.channel` and `process.connected` throw `ERR_WORKER_UNSUPPORTED_OPERATION` on access in workers
- Pass `runningOnMainThread` to `__bootstrapNodeProcess` so stubs are installed before `__initWorkerThreads` runs
- Enable `test-worker-unsupported-things.js` node compat test

Matches Node.js behavior from `lib/internal/bootstrap/switches/is_not_main_thread.js`.

## Test plan

- [x] `test-worker-unsupported-things.js` passes (newly enabled)
- [x] All existing worker compat tests pass
- [x] `./tools/format.js` and `./tools/lint.js --js` pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Changed files:
filename: ext/node/polyfills/02_init.js
patch: @@ -42,6 +42,8 @@ function initialize(args) {
       Deno.args,
       Deno.version,
       nodeDebug ?? "",
+      false,
+      runningOnMainThread,
     );
     internals.__initWorkerThreads(
       runningOnMainThread,

filename: ext/node/polyfills/process.ts
patch: @@ -1227,6 +1227,7 @@ internals.__bootstrapNodeProcess = function (
   denoVersions: Record<string, string>,
   nodeDebug: string,
   warmup = false,
+  runningOnMainThread = true,
 ) {
   if (!warmup) {
     argv0 = argv0Val || "";
@@ -1313,6 +1314,46 @@ internals.__bootstrapNodeProcess = function (
       stdin = process.stdin = newStdin;
     }
 
+    // In worker threads, replace certain process functions with stubs
+    // that throw ERR_WORKER_UNSUPPORTED_OPERATION and have .disabled = true.
+    // Ref: https://github.com/nodejs/node/blob/main/lib/internal/bootstrap/switches/is_not_main_thread.js
+    if (!runningOnMainThread) {
+      const disabledFns = [
+        "abort",
+        "chdir",
+        "send",
+        "disconnect",
+        "setuid",
+        "seteuid",
+        "setgid",
+        "setegid",
+        "setgroups",
+        "initgroups",
+      ];
+      for (const fn of disabledFns) {
+        const stub = function () {
+          throw new ERR_WORKER_UNSUPPORTED_OPERATION(
+            `process.${fn}()`,
+          );
+        };
+        stub.disabled = true;
+        process[fn] = stub;
+      }
+
+      Object.defineProperty(process, "channel", {
+        get() {
+          throw new ERR_WORKER_UNSUPPORTED_OPERATION("process.channel");
+        },
+        configurable: true,
+      });
+      Object.defineProperty(process, "connected", {
+        get() {
+          throw new ERR_WORKER_UNSUPPORTED_OPERATION("process.connected");
+        },
+        configurable: true,
+      });
+    }
+
     delete internals.__bootstrapNodeProcess;
   } else {
     // Warmup, assuming stdin/stdout/stderr are all terminals

filename: tests/node_compat/config.jsonc
patch: @@ -2377,6 +2377,7 @@
     "parallel/test-worker-unref-from-message-during-exit.js": {},
     "parallel/test-worker-unsupported-eval-on-url.mjs": {},
     "parallel/test-worker-unsupported-path.js": {},
+    "parallel/test-worker-unsupported-things.js": {},
     "parallel/test-worker-thread-name.js": {},
     "parallel/test-worker-voluntarily-exit-followed-by-addition.js": {},
     "parallel/test-worker-voluntarily-exit-followed-by-throw.js": {},