@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.
- package/asyncify/7_2_34/php_7_2.wasm +0 -0
- package/asyncify/7_3_33/php_7_3.wasm +0 -0
- package/asyncify/7_4_33/php_7_4.wasm +0 -0
- package/asyncify/8_0_30/php_8_0.wasm +0 -0
- package/asyncify/8_1_23/php_8_1.wasm +0 -0
- package/asyncify/8_2_10/php_8_2.wasm +0 -0
- package/asyncify/8_3_0/php_8_3.wasm +0 -0
- package/asyncify/8_4_0/php_8_4.wasm +0 -0
- package/asyncify/php_7_2.js +179 -39
- package/asyncify/php_7_3.js +179 -39
- package/asyncify/php_7_4.js +179 -39
- package/asyncify/php_8_0.js +179 -39
- package/asyncify/php_8_1.js +179 -39
- package/asyncify/php_8_2.js +179 -39
- package/asyncify/php_8_3.js +179 -39
- package/asyncify/php_8_4.js +179 -39
- package/index.cjs +2710 -1213
- package/index.js +2710 -1213
- package/jspi/7_2_34/php_7_2.wasm +0 -0
- package/jspi/7_3_33/php_7_3.wasm +0 -0
- package/jspi/7_4_33/php_7_4.wasm +0 -0
- package/jspi/8_0_30/php_8_0.wasm +0 -0
- package/jspi/8_1_23/php_8_1.wasm +0 -0
- package/jspi/8_2_10/php_8_2.wasm +0 -0
- package/jspi/8_3_0/php_8_3.wasm +0 -0
- package/jspi/8_4_0/php_8_4.wasm +0 -0
- package/jspi/php_7_2.js +176 -36
- package/jspi/php_7_3.js +176 -36
- package/jspi/php_7_4.js +7703 -8484
- package/jspi/php_8_0.js +176 -36
- package/jspi/php_8_1.js +176 -36
- package/jspi/php_8_2.js +176 -36
- package/jspi/php_8_3.js +176 -36
- package/jspi/php_8_4.js +176 -36
- package/package.json +8 -8
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/asyncify/php_7_2.js
CHANGED
|
@@ -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
|
-
|
|
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_2_34', 'php_7_2.wasm');
|
|
24
10
|
export { dependencyFilename };
|
|
25
|
-
export const dependenciesTotalSize =
|
|
11
|
+
export const dependenciesTotalSize = 18094393;
|
|
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) :
|
|
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
|
-
|
|
7367
|
-
|
|
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(
|
|
7506
|
+
wakeUp(ProcInfo.pid);
|
|
7372
7507
|
return;
|
|
7373
7508
|
}
|
|
7374
7509
|
// Now we want to pass data from the STDIN source supplied by PHP
|
|
@@ -8253,14 +8388,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8253
8388
|
const POLLNVAL = 32;
|
|
8254
8389
|
return returnCallback((wakeUp) => {
|
|
8255
8390
|
const polls = [];
|
|
8256
|
-
if (socketd
|
|
8257
|
-
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8258
|
-
if (procInfo.exited) {
|
|
8259
|
-
wakeUp(0);
|
|
8260
|
-
return;
|
|
8261
|
-
}
|
|
8262
|
-
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8263
|
-
} else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8391
|
+
if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8264
8392
|
const sock = getSocketFromFD(socketd);
|
|
8265
8393
|
if (!sock) {
|
|
8266
8394
|
wakeUp(0);
|
|
@@ -8294,7 +8422,12 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8294
8422
|
polls.push(PHPWASM.awaitConnection(ws));
|
|
8295
8423
|
lookingFor.add('POLLOUT');
|
|
8296
8424
|
}
|
|
8297
|
-
if (
|
|
8425
|
+
if (
|
|
8426
|
+
events & POLLHUP ||
|
|
8427
|
+
events & POLLIN ||
|
|
8428
|
+
events & POLLOUT ||
|
|
8429
|
+
events & POLLERR
|
|
8430
|
+
) {
|
|
8298
8431
|
polls.push(PHPWASM.awaitClose(ws));
|
|
8299
8432
|
lookingFor.add('POLLHUP');
|
|
8300
8433
|
}
|
|
@@ -8303,6 +8436,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8303
8436
|
lookingFor.add('POLLERR');
|
|
8304
8437
|
}
|
|
8305
8438
|
}
|
|
8439
|
+
} else if (socketd in PHPWASM.child_proc_by_fd) {
|
|
8440
|
+
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8441
|
+
if (procInfo.exited) {
|
|
8442
|
+
wakeUp(0);
|
|
8443
|
+
return;
|
|
8444
|
+
}
|
|
8445
|
+
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8306
8446
|
} else {
|
|
8307
8447
|
setTimeout(function () {
|
|
8308
8448
|
wakeUp(1);
|
|
@@ -8607,21 +8747,21 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8607
8747
|
a4
|
|
8608
8748
|
));
|
|
8609
8749
|
|
|
8610
|
-
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8611
|
-
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['qb'])(
|
|
8612
|
-
a0
|
|
8613
|
-
));
|
|
8614
|
-
|
|
8615
|
-
var _run_cli = (Module['_run_cli'] = () =>
|
|
8616
|
-
(_run_cli = Module['_run_cli'] = wasmExports['rb'])());
|
|
8617
|
-
|
|
8618
8750
|
var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
|
|
8619
8751
|
(_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
|
|
8620
|
-
wasmExports['
|
|
8752
|
+
wasmExports['qb'])(a0));
|
|
8621
8753
|
|
|
8622
8754
|
var _wasm_set_phpini_path = (Module['_wasm_set_phpini_path'] = (a0) =>
|
|
8623
8755
|
(_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
|
|
8624
|
-
wasmExports['
|
|
8756
|
+
wasmExports['rb'])(a0));
|
|
8757
|
+
|
|
8758
|
+
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8759
|
+
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['sb'])(
|
|
8760
|
+
a0
|
|
8761
|
+
));
|
|
8762
|
+
|
|
8763
|
+
var _run_cli = (Module['_run_cli'] = () =>
|
|
8764
|
+
(_run_cli = Module['_run_cli'] = wasmExports['tb'])());
|
|
8625
8765
|
|
|
8626
8766
|
var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
|
|
8627
8767
|
(_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
|
package/asyncify/php_7_3.js
CHANGED
|
@@ -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
|
-
|
|
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_3_33', 'php_7_3.wasm');
|
|
24
10
|
export { dependencyFilename };
|
|
25
|
-
export const dependenciesTotalSize =
|
|
11
|
+
export const dependenciesTotalSize = 18173209;
|
|
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) :
|
|
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
|
-
|
|
7367
|
-
|
|
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(
|
|
7506
|
+
wakeUp(ProcInfo.pid);
|
|
7372
7507
|
return;
|
|
7373
7508
|
}
|
|
7374
7509
|
// Now we want to pass data from the STDIN source supplied by PHP
|
|
@@ -8253,14 +8388,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8253
8388
|
const POLLNVAL = 32;
|
|
8254
8389
|
return returnCallback((wakeUp) => {
|
|
8255
8390
|
const polls = [];
|
|
8256
|
-
if (socketd
|
|
8257
|
-
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8258
|
-
if (procInfo.exited) {
|
|
8259
|
-
wakeUp(0);
|
|
8260
|
-
return;
|
|
8261
|
-
}
|
|
8262
|
-
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8263
|
-
} else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8391
|
+
if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8264
8392
|
const sock = getSocketFromFD(socketd);
|
|
8265
8393
|
if (!sock) {
|
|
8266
8394
|
wakeUp(0);
|
|
@@ -8294,7 +8422,12 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8294
8422
|
polls.push(PHPWASM.awaitConnection(ws));
|
|
8295
8423
|
lookingFor.add('POLLOUT');
|
|
8296
8424
|
}
|
|
8297
|
-
if (
|
|
8425
|
+
if (
|
|
8426
|
+
events & POLLHUP ||
|
|
8427
|
+
events & POLLIN ||
|
|
8428
|
+
events & POLLOUT ||
|
|
8429
|
+
events & POLLERR
|
|
8430
|
+
) {
|
|
8298
8431
|
polls.push(PHPWASM.awaitClose(ws));
|
|
8299
8432
|
lookingFor.add('POLLHUP');
|
|
8300
8433
|
}
|
|
@@ -8303,6 +8436,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8303
8436
|
lookingFor.add('POLLERR');
|
|
8304
8437
|
}
|
|
8305
8438
|
}
|
|
8439
|
+
} else if (socketd in PHPWASM.child_proc_by_fd) {
|
|
8440
|
+
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8441
|
+
if (procInfo.exited) {
|
|
8442
|
+
wakeUp(0);
|
|
8443
|
+
return;
|
|
8444
|
+
}
|
|
8445
|
+
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8306
8446
|
} else {
|
|
8307
8447
|
setTimeout(function () {
|
|
8308
8448
|
wakeUp(1);
|
|
@@ -8607,21 +8747,21 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8607
8747
|
a4
|
|
8608
8748
|
));
|
|
8609
8749
|
|
|
8610
|
-
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8611
|
-
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['qb'])(
|
|
8612
|
-
a0
|
|
8613
|
-
));
|
|
8614
|
-
|
|
8615
|
-
var _run_cli = (Module['_run_cli'] = () =>
|
|
8616
|
-
(_run_cli = Module['_run_cli'] = wasmExports['rb'])());
|
|
8617
|
-
|
|
8618
8750
|
var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
|
|
8619
8751
|
(_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
|
|
8620
|
-
wasmExports['
|
|
8752
|
+
wasmExports['qb'])(a0));
|
|
8621
8753
|
|
|
8622
8754
|
var _wasm_set_phpini_path = (Module['_wasm_set_phpini_path'] = (a0) =>
|
|
8623
8755
|
(_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
|
|
8624
|
-
wasmExports['
|
|
8756
|
+
wasmExports['rb'])(a0));
|
|
8757
|
+
|
|
8758
|
+
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8759
|
+
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] = wasmExports['sb'])(
|
|
8760
|
+
a0
|
|
8761
|
+
));
|
|
8762
|
+
|
|
8763
|
+
var _run_cli = (Module['_run_cli'] = () =>
|
|
8764
|
+
(_run_cli = Module['_run_cli'] = wasmExports['tb'])());
|
|
8625
8765
|
|
|
8626
8766
|
var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
|
|
8627
8767
|
(_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
|