@php-wasm/node 1.1.1 → 1.1.3

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.
@@ -3,26 +3,12 @@
3
3
  // this code in Node.js as an ES module.
4
4
  import { createRequire } from 'module';
5
5
  const require = createRequire(import.meta.url);
6
- import { fileURLToPath } from 'url';
7
-
8
- /**
9
- * __filename and __dirname are not available in ES modules, so we need to
10
- * polyfill them to ensure the debug command (npx nx debug playground-cli)
11
- * works.
12
- *
13
- * @see https://nodejs.org/api/esm.html#no-__filename-or-__dirname
14
- */
6
+ // Note: The path module is currently needed by code injected by the php-wasm Dockerfile.
15
7
  import path from 'path';
16
- if (typeof __filename === 'undefined') {
17
- var __filename = fileURLToPath(import.meta.url);
18
- }
19
- if (typeof __dirname === 'undefined') {
20
- var __dirname = path.dirname(__filename);
21
- }
22
8
 
23
9
  const dependencyFilename = path.join(__dirname, '7_4_33', 'php_7_4.wasm');
24
10
  export { dependencyFilename };
25
- export const dependenciesTotalSize = 18674777;
11
+ export const dependenciesTotalSize = 18675922;
26
12
  export function init(RuntimeName, PHPLoader) {
27
13
  // The rest of the code comes from the built php.js file and esm-suffix.js
28
14
  // include: shell.js
@@ -7016,6 +7002,44 @@ export function init(RuntimeName, PHPLoader) {
7016
7002
  // The files from the preload directory are preloaded using the
7017
7003
  // auto_prepend_file php.ini directive.
7018
7004
  FS.mkdir('/internal/shared/preload');
7005
+ // Create stdout and stderr devices. We can't just use Emscripten's
7006
+ // default stdout and stderr devices because they stop processing data
7007
+ // on the first null byte. However, when dealing with binary data,
7008
+ // null bytes are valid and common.
7009
+ FS.registerDevice(FS.makedev(64, 0), {
7010
+ open: () => {},
7011
+ close: () => {},
7012
+ read: () => 0,
7013
+ write: (stream, buffer, offset, length, pos) => {
7014
+ const chunk = buffer.subarray(offset, offset + length);
7015
+ PHPWASM.onStdout(chunk);
7016
+ return length;
7017
+ },
7018
+ });
7019
+ FS.mkdev('/internal/stdout', FS.makedev(64, 0));
7020
+ FS.registerDevice(FS.makedev(63, 0), {
7021
+ open: () => {},
7022
+ close: () => {},
7023
+ read: () => 0,
7024
+ write: (stream, buffer, offset, length, pos) => {
7025
+ const chunk = buffer.subarray(offset, offset + length);
7026
+ PHPWASM.onStderr(chunk);
7027
+ return length;
7028
+ },
7029
+ });
7030
+ FS.mkdev('/internal/stderr', FS.makedev(63, 0));
7031
+ FS.registerDevice(FS.makedev(62, 0), {
7032
+ open: () => {},
7033
+ close: () => {},
7034
+ read: () => 0,
7035
+ write: (stream, buffer, offset, length, pos) => {
7036
+ const chunk = buffer.subarray(offset, offset + length);
7037
+ PHPWASM.onHeaders(chunk);
7038
+ return length;
7039
+ },
7040
+ });
7041
+ FS.mkdev('/internal/headers', FS.makedev(62, 0));
7042
+ // Handle events.
7019
7043
  PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
7020
7044
  ? require('events').EventEmitter
7021
7045
  : class EventEmitter {
@@ -7056,9 +7080,71 @@ export function init(RuntimeName, PHPLoader) {
7056
7080
  }
7057
7081
  }
7058
7082
  };
7083
+ // Clean up the fd -> childProcess mapping when the fd is closed:
7084
+ const originalClose = FS.close;
7085
+ FS.close = function (stream) {
7086
+ originalClose(stream);
7087
+ delete PHPWASM.child_proc_by_fd[stream.fd];
7088
+ };
7059
7089
  PHPWASM.child_proc_by_fd = {};
7060
7090
  PHPWASM.child_proc_by_pid = {};
7061
7091
  PHPWASM.input_devices = {};
7092
+ const originalWrite = TTY.stream_ops.write;
7093
+ TTY.stream_ops.write = function (stream, ...rest) {
7094
+ const retval = originalWrite(stream, ...rest);
7095
+ // Implicit flush since PHP's fflush() doesn't seem to trigger the fsync event
7096
+ // @TODO: Fix this at the wasm level
7097
+ stream.tty.ops.fsync(stream.tty);
7098
+ return retval;
7099
+ };
7100
+ const originalPutChar = TTY.stream_ops.put_char;
7101
+ TTY.stream_ops.put_char = function (tty, val) {
7102
+ /**
7103
+ * Buffer newlines that Emscripten normally ignores.
7104
+ *
7105
+ * Emscripten doesn't do it by default because its default
7106
+ * print function is console.log that implicitly adds a newline. We are overwriting
7107
+ * it with an environment-specific function that outputs exaclty what it was given,
7108
+ * e.g. in Node.js it's process.stdout.write(). Therefore, we need to mak sure
7109
+ * all the newlines make it to the output buffer.
7110
+ */ if (val === 10) tty.output.push(val);
7111
+ return originalPutChar(tty, val);
7112
+ };
7113
+ },
7114
+ onHeaders: function (chunk) {
7115
+ if (Module['onHeaders']) {
7116
+ Module['onHeaders'](chunk);
7117
+ return;
7118
+ }
7119
+ console.log('headers', {
7120
+ chunk,
7121
+ });
7122
+ },
7123
+ onStdout: function (chunk) {
7124
+ if (Module['onStdout']) {
7125
+ Module['onStdout'](chunk);
7126
+ return;
7127
+ }
7128
+ if (ENVIRONMENT_IS_NODE) {
7129
+ process.stdout.write(chunk);
7130
+ } else {
7131
+ console.log('stdout', {
7132
+ chunk,
7133
+ });
7134
+ }
7135
+ },
7136
+ onStderr: function (chunk) {
7137
+ if (Module['onStderr']) {
7138
+ Module['onStderr'](chunk);
7139
+ return;
7140
+ }
7141
+ if (ENVIRONMENT_IS_NODE) {
7142
+ process.stderr.write(chunk);
7143
+ } else {
7144
+ console.warn('stderr', {
7145
+ chunk,
7146
+ });
7147
+ }
7062
7148
  },
7063
7149
  getAllWebSockets: function (sock) {
7064
7150
  const webSockets = new Set();
@@ -7240,7 +7326,7 @@ export function init(RuntimeName, PHPLoader) {
7240
7326
  argsArray.push(UTF8ToString(HEAPU32[charPointer >> 2]));
7241
7327
  }
7242
7328
  }
7243
- const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : null;
7329
+ const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : FS.cwd();
7244
7330
  let envObject = null;
7245
7331
  if (envLength) {
7246
7332
  envObject = {};
@@ -7313,6 +7399,15 @@ export function init(RuntimeName, PHPLoader) {
7313
7399
  PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd] = ProcInfo;
7314
7400
  PHPWASM.child_proc_by_pid[ProcInfo.pid] = ProcInfo;
7315
7401
  cp.on('exit', function (code) {
7402
+ for (const fd of [
7403
+ // The child process exited. Let's clean up its output streams:
7404
+ ProcInfo.stdoutChildFd,
7405
+ ProcInfo.stderrChildFd,
7406
+ ]) {
7407
+ if (FS.streams[fd] && !FS.isClosed(FS.streams[fd])) {
7408
+ FS.close(FS.streams[fd]);
7409
+ }
7410
+ }
7316
7411
  ProcInfo.exitCode = code;
7317
7412
  ProcInfo.exited = true;
7318
7413
  // Emit events for the wasm_poll_socket function.
@@ -7363,12 +7458,52 @@ export function init(RuntimeName, PHPLoader) {
7363
7458
  * listen to the 'exit' event.
7364
7459
  */ try {
7365
7460
  await new Promise((resolve, reject) => {
7366
- cp.on('spawn', resolve);
7367
- cp.on('error', reject);
7461
+ /**
7462
+ * There was no `await` between the `spawnProcess` call
7463
+ * and the `await` below so the process haven't had a chance
7464
+ * to run any of the exit-related callbacks yet.
7465
+ *
7466
+ * Good.
7467
+ *
7468
+ * Let's listen to all the lifecycle events and resolve
7469
+ * the promise when the process starts or immediately crashes.
7470
+ */ let resolved = false;
7471
+ cp.on('spawn', () => {
7472
+ if (resolved) return;
7473
+ resolved = true;
7474
+ resolve();
7475
+ });
7476
+ cp.on('error', (e) => {
7477
+ if (resolved) return;
7478
+ resolved = true;
7479
+ reject(e);
7480
+ });
7481
+ cp.on('exit', function (code) {
7482
+ if (resolved) return;
7483
+ resolved = true;
7484
+ if (code === 0) {
7485
+ resolve();
7486
+ } else {
7487
+ reject(
7488
+ new Error(`Process exited with code ${code}`)
7489
+ );
7490
+ }
7491
+ });
7492
+ /**
7493
+ * If the process haven't even started after 5 seconds, something
7494
+ * is wrong. Perhaps we're missing an event listener, or perhaps
7495
+ * the `spawnProcess` implementation failed to dispatch the relevant
7496
+ * event. Either way, let's crash to avoid blocking the proc_open()
7497
+ * call indefinitely.
7498
+ */ setTimeout(() => {
7499
+ if (resolved) return;
7500
+ resolved = true;
7501
+ reject(new Error('Process timed out'));
7502
+ }, 5e3);
7368
7503
  });
7369
7504
  } catch (e) {
7370
7505
  console.error(e);
7371
- wakeUp(1);
7506
+ wakeUp(ProcInfo.pid);
7372
7507
  return;
7373
7508
  }
7374
7509
  // Now we want to pass data from the STDIN source supplied by PHP
@@ -8257,14 +8392,7 @@ export function init(RuntimeName, PHPLoader) {
8257
8392
  const POLLNVAL = 32;
8258
8393
  return returnCallback((wakeUp) => {
8259
8394
  const polls = [];
8260
- if (socketd in PHPWASM.child_proc_by_fd) {
8261
- const procInfo = PHPWASM.child_proc_by_fd[socketd];
8262
- if (procInfo.exited) {
8263
- wakeUp(0);
8264
- return;
8265
- }
8266
- polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
8267
- } else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
8395
+ if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
8268
8396
  const sock = getSocketFromFD(socketd);
8269
8397
  if (!sock) {
8270
8398
  wakeUp(0);
@@ -8298,7 +8426,12 @@ export function init(RuntimeName, PHPLoader) {
8298
8426
  polls.push(PHPWASM.awaitConnection(ws));
8299
8427
  lookingFor.add('POLLOUT');
8300
8428
  }
8301
- if (events & POLLHUP) {
8429
+ if (
8430
+ events & POLLHUP ||
8431
+ events & POLLIN ||
8432
+ events & POLLOUT ||
8433
+ events & POLLERR
8434
+ ) {
8302
8435
  polls.push(PHPWASM.awaitClose(ws));
8303
8436
  lookingFor.add('POLLHUP');
8304
8437
  }
@@ -8307,6 +8440,13 @@ export function init(RuntimeName, PHPLoader) {
8307
8440
  lookingFor.add('POLLERR');
8308
8441
  }
8309
8442
  }
8443
+ } else if (socketd in PHPWASM.child_proc_by_fd) {
8444
+ const procInfo = PHPWASM.child_proc_by_fd[socketd];
8445
+ if (procInfo.exited) {
8446
+ wakeUp(0);
8447
+ return;
8448
+ }
8449
+ polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
8310
8450
  } else {
8311
8451
  setTimeout(function () {
8312
8452
  wakeUp(1);
@@ -8612,21 +8752,21 @@ export function init(RuntimeName, PHPLoader) {
8612
8752
  a4
8613
8753
  ));
8614
8754
 
8615
- var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
8616
- (_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['rb'])(
8617
- a0
8618
- ));
8619
-
8620
- var _run_cli = (Module['_run_cli'] = () =>
8621
- (_run_cli = Module['_run_cli'] = wasmExports['sb'])());
8622
-
8623
8755
  var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
8624
8756
  (_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
8625
- wasmExports['tb'])(a0));
8757
+ wasmExports['rb'])(a0));
8626
8758
 
8627
8759
  var _wasm_set_phpini_path = (Module['_wasm_set_phpini_path'] = (a0) =>
8628
8760
  (_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
8629
- wasmExports['ub'])(a0));
8761
+ wasmExports['sb'])(a0));
8762
+
8763
+ var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
8764
+ (_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['tb'])(
8765
+ a0
8766
+ ));
8767
+
8768
+ var _run_cli = (Module['_run_cli'] = () =>
8769
+ (_run_cli = Module['_run_cli'] = wasmExports['ub'])());
8630
8770
 
8631
8771
  var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
8632
8772
  (_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
@@ -3,26 +3,12 @@
3
3
  // this code in Node.js as an ES module.
4
4
  import { createRequire } from 'module';
5
5
  const require = createRequire(import.meta.url);
6
- import { fileURLToPath } from 'url';
7
-
8
- /**
9
- * __filename and __dirname are not available in ES modules, so we need to
10
- * polyfill them to ensure the debug command (npx nx debug playground-cli)
11
- * works.
12
- *
13
- * @see https://nodejs.org/api/esm.html#no-__filename-or-__dirname
14
- */
6
+ // Note: The path module is currently needed by code injected by the php-wasm Dockerfile.
15
7
  import path from 'path';
16
- if (typeof __filename === 'undefined') {
17
- var __filename = fileURLToPath(import.meta.url);
18
- }
19
- if (typeof __dirname === 'undefined') {
20
- var __dirname = path.dirname(__filename);
21
- }
22
8
 
23
9
  const dependencyFilename = path.join(__dirname, '8_0_30', 'php_8_0.wasm');
24
10
  export { dependencyFilename };
25
- export const dependenciesTotalSize = 17379367;
11
+ export const dependenciesTotalSize = 17380177;
26
12
  export function init(RuntimeName, PHPLoader) {
27
13
  // The rest of the code comes from the built php.js file and esm-suffix.js
28
14
  // include: shell.js
@@ -7016,6 +7002,44 @@ export function init(RuntimeName, PHPLoader) {
7016
7002
  // The files from the preload directory are preloaded using the
7017
7003
  // auto_prepend_file php.ini directive.
7018
7004
  FS.mkdir('/internal/shared/preload');
7005
+ // Create stdout and stderr devices. We can't just use Emscripten's
7006
+ // default stdout and stderr devices because they stop processing data
7007
+ // on the first null byte. However, when dealing with binary data,
7008
+ // null bytes are valid and common.
7009
+ FS.registerDevice(FS.makedev(64, 0), {
7010
+ open: () => {},
7011
+ close: () => {},
7012
+ read: () => 0,
7013
+ write: (stream, buffer, offset, length, pos) => {
7014
+ const chunk = buffer.subarray(offset, offset + length);
7015
+ PHPWASM.onStdout(chunk);
7016
+ return length;
7017
+ },
7018
+ });
7019
+ FS.mkdev('/internal/stdout', FS.makedev(64, 0));
7020
+ FS.registerDevice(FS.makedev(63, 0), {
7021
+ open: () => {},
7022
+ close: () => {},
7023
+ read: () => 0,
7024
+ write: (stream, buffer, offset, length, pos) => {
7025
+ const chunk = buffer.subarray(offset, offset + length);
7026
+ PHPWASM.onStderr(chunk);
7027
+ return length;
7028
+ },
7029
+ });
7030
+ FS.mkdev('/internal/stderr', FS.makedev(63, 0));
7031
+ FS.registerDevice(FS.makedev(62, 0), {
7032
+ open: () => {},
7033
+ close: () => {},
7034
+ read: () => 0,
7035
+ write: (stream, buffer, offset, length, pos) => {
7036
+ const chunk = buffer.subarray(offset, offset + length);
7037
+ PHPWASM.onHeaders(chunk);
7038
+ return length;
7039
+ },
7040
+ });
7041
+ FS.mkdev('/internal/headers', FS.makedev(62, 0));
7042
+ // Handle events.
7019
7043
  PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
7020
7044
  ? require('events').EventEmitter
7021
7045
  : class EventEmitter {
@@ -7056,9 +7080,71 @@ export function init(RuntimeName, PHPLoader) {
7056
7080
  }
7057
7081
  }
7058
7082
  };
7083
+ // Clean up the fd -> childProcess mapping when the fd is closed:
7084
+ const originalClose = FS.close;
7085
+ FS.close = function (stream) {
7086
+ originalClose(stream);
7087
+ delete PHPWASM.child_proc_by_fd[stream.fd];
7088
+ };
7059
7089
  PHPWASM.child_proc_by_fd = {};
7060
7090
  PHPWASM.child_proc_by_pid = {};
7061
7091
  PHPWASM.input_devices = {};
7092
+ const originalWrite = TTY.stream_ops.write;
7093
+ TTY.stream_ops.write = function (stream, ...rest) {
7094
+ const retval = originalWrite(stream, ...rest);
7095
+ // Implicit flush since PHP's fflush() doesn't seem to trigger the fsync event
7096
+ // @TODO: Fix this at the wasm level
7097
+ stream.tty.ops.fsync(stream.tty);
7098
+ return retval;
7099
+ };
7100
+ const originalPutChar = TTY.stream_ops.put_char;
7101
+ TTY.stream_ops.put_char = function (tty, val) {
7102
+ /**
7103
+ * Buffer newlines that Emscripten normally ignores.
7104
+ *
7105
+ * Emscripten doesn't do it by default because its default
7106
+ * print function is console.log that implicitly adds a newline. We are overwriting
7107
+ * it with an environment-specific function that outputs exaclty what it was given,
7108
+ * e.g. in Node.js it's process.stdout.write(). Therefore, we need to mak sure
7109
+ * all the newlines make it to the output buffer.
7110
+ */ if (val === 10) tty.output.push(val);
7111
+ return originalPutChar(tty, val);
7112
+ };
7113
+ },
7114
+ onHeaders: function (chunk) {
7115
+ if (Module['onHeaders']) {
7116
+ Module['onHeaders'](chunk);
7117
+ return;
7118
+ }
7119
+ console.log('headers', {
7120
+ chunk,
7121
+ });
7122
+ },
7123
+ onStdout: function (chunk) {
7124
+ if (Module['onStdout']) {
7125
+ Module['onStdout'](chunk);
7126
+ return;
7127
+ }
7128
+ if (ENVIRONMENT_IS_NODE) {
7129
+ process.stdout.write(chunk);
7130
+ } else {
7131
+ console.log('stdout', {
7132
+ chunk,
7133
+ });
7134
+ }
7135
+ },
7136
+ onStderr: function (chunk) {
7137
+ if (Module['onStderr']) {
7138
+ Module['onStderr'](chunk);
7139
+ return;
7140
+ }
7141
+ if (ENVIRONMENT_IS_NODE) {
7142
+ process.stderr.write(chunk);
7143
+ } else {
7144
+ console.warn('stderr', {
7145
+ chunk,
7146
+ });
7147
+ }
7062
7148
  },
7063
7149
  getAllWebSockets: function (sock) {
7064
7150
  const webSockets = new Set();
@@ -7240,7 +7326,7 @@ export function init(RuntimeName, PHPLoader) {
7240
7326
  argsArray.push(UTF8ToString(HEAPU32[charPointer >> 2]));
7241
7327
  }
7242
7328
  }
7243
- const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : null;
7329
+ const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : FS.cwd();
7244
7330
  let envObject = null;
7245
7331
  if (envLength) {
7246
7332
  envObject = {};
@@ -7313,6 +7399,15 @@ export function init(RuntimeName, PHPLoader) {
7313
7399
  PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd] = ProcInfo;
7314
7400
  PHPWASM.child_proc_by_pid[ProcInfo.pid] = ProcInfo;
7315
7401
  cp.on('exit', function (code) {
7402
+ for (const fd of [
7403
+ // The child process exited. Let's clean up its output streams:
7404
+ ProcInfo.stdoutChildFd,
7405
+ ProcInfo.stderrChildFd,
7406
+ ]) {
7407
+ if (FS.streams[fd] && !FS.isClosed(FS.streams[fd])) {
7408
+ FS.close(FS.streams[fd]);
7409
+ }
7410
+ }
7316
7411
  ProcInfo.exitCode = code;
7317
7412
  ProcInfo.exited = true;
7318
7413
  // Emit events for the wasm_poll_socket function.
@@ -7363,12 +7458,52 @@ export function init(RuntimeName, PHPLoader) {
7363
7458
  * listen to the 'exit' event.
7364
7459
  */ try {
7365
7460
  await new Promise((resolve, reject) => {
7366
- cp.on('spawn', resolve);
7367
- cp.on('error', reject);
7461
+ /**
7462
+ * There was no `await` between the `spawnProcess` call
7463
+ * and the `await` below so the process haven't had a chance
7464
+ * to run any of the exit-related callbacks yet.
7465
+ *
7466
+ * Good.
7467
+ *
7468
+ * Let's listen to all the lifecycle events and resolve
7469
+ * the promise when the process starts or immediately crashes.
7470
+ */ let resolved = false;
7471
+ cp.on('spawn', () => {
7472
+ if (resolved) return;
7473
+ resolved = true;
7474
+ resolve();
7475
+ });
7476
+ cp.on('error', (e) => {
7477
+ if (resolved) return;
7478
+ resolved = true;
7479
+ reject(e);
7480
+ });
7481
+ cp.on('exit', function (code) {
7482
+ if (resolved) return;
7483
+ resolved = true;
7484
+ if (code === 0) {
7485
+ resolve();
7486
+ } else {
7487
+ reject(
7488
+ new Error(`Process exited with code ${code}`)
7489
+ );
7490
+ }
7491
+ });
7492
+ /**
7493
+ * If the process haven't even started after 5 seconds, something
7494
+ * is wrong. Perhaps we're missing an event listener, or perhaps
7495
+ * the `spawnProcess` implementation failed to dispatch the relevant
7496
+ * event. Either way, let's crash to avoid blocking the proc_open()
7497
+ * call indefinitely.
7498
+ */ setTimeout(() => {
7499
+ if (resolved) return;
7500
+ resolved = true;
7501
+ reject(new Error('Process timed out'));
7502
+ }, 5e3);
7368
7503
  });
7369
7504
  } catch (e) {
7370
7505
  console.error(e);
7371
- wakeUp(1);
7506
+ wakeUp(ProcInfo.pid);
7372
7507
  return;
7373
7508
  }
7374
7509
  // Now we want to pass data from the STDIN source supplied by PHP
@@ -8257,14 +8392,7 @@ export function init(RuntimeName, PHPLoader) {
8257
8392
  const POLLNVAL = 32;
8258
8393
  return returnCallback((wakeUp) => {
8259
8394
  const polls = [];
8260
- if (socketd in PHPWASM.child_proc_by_fd) {
8261
- const procInfo = PHPWASM.child_proc_by_fd[socketd];
8262
- if (procInfo.exited) {
8263
- wakeUp(0);
8264
- return;
8265
- }
8266
- polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
8267
- } else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
8395
+ if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
8268
8396
  const sock = getSocketFromFD(socketd);
8269
8397
  if (!sock) {
8270
8398
  wakeUp(0);
@@ -8298,7 +8426,12 @@ export function init(RuntimeName, PHPLoader) {
8298
8426
  polls.push(PHPWASM.awaitConnection(ws));
8299
8427
  lookingFor.add('POLLOUT');
8300
8428
  }
8301
- if (events & POLLHUP) {
8429
+ if (
8430
+ events & POLLHUP ||
8431
+ events & POLLIN ||
8432
+ events & POLLOUT ||
8433
+ events & POLLERR
8434
+ ) {
8302
8435
  polls.push(PHPWASM.awaitClose(ws));
8303
8436
  lookingFor.add('POLLHUP');
8304
8437
  }
@@ -8307,6 +8440,13 @@ export function init(RuntimeName, PHPLoader) {
8307
8440
  lookingFor.add('POLLERR');
8308
8441
  }
8309
8442
  }
8443
+ } else if (socketd in PHPWASM.child_proc_by_fd) {
8444
+ const procInfo = PHPWASM.child_proc_by_fd[socketd];
8445
+ if (procInfo.exited) {
8446
+ wakeUp(0);
8447
+ return;
8448
+ }
8449
+ polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
8310
8450
  } else {
8311
8451
  setTimeout(function () {
8312
8452
  wakeUp(1);
@@ -8614,21 +8754,21 @@ export function init(RuntimeName, PHPLoader) {
8614
8754
  a4
8615
8755
  ));
8616
8756
 
8617
- var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
8618
- (_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['tb'])(
8619
- a0
8620
- ));
8621
-
8622
- var _run_cli = (Module['_run_cli'] = () =>
8623
- (_run_cli = Module['_run_cli'] = wasmExports['ub'])());
8624
-
8625
8757
  var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
8626
8758
  (_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
8627
- wasmExports['vb'])(a0));
8759
+ wasmExports['tb'])(a0));
8628
8760
 
8629
8761
  var _wasm_set_phpini_path = (Module['_wasm_set_phpini_path'] = (a0) =>
8630
8762
  (_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
8631
- wasmExports['wb'])(a0));
8763
+ wasmExports['ub'])(a0));
8764
+
8765
+ var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
8766
+ (_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['vb'])(
8767
+ a0
8768
+ ));
8769
+
8770
+ var _run_cli = (Module['_run_cli'] = () =>
8771
+ (_run_cli = Module['_run_cli'] = wasmExports['wb'])());
8632
8772
 
8633
8773
  var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
8634
8774
  (_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =