@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
package/jspi/7_2_34/php_7_2.wasm
CHANGED
|
Binary file
|
package/jspi/7_3_33/php_7_3.wasm
CHANGED
|
Binary file
|
package/jspi/7_4_33/php_7_4.wasm
CHANGED
|
Binary file
|
package/jspi/8_0_30/php_8_0.wasm
CHANGED
|
Binary file
|
package/jspi/8_1_23/php_8_1.wasm
CHANGED
|
Binary file
|
package/jspi/8_2_10/php_8_2.wasm
CHANGED
|
Binary file
|
package/jspi/8_3_0/php_8_3.wasm
CHANGED
|
Binary file
|
package/jspi/8_4_0/php_8_4.wasm
CHANGED
|
Binary file
|
package/jspi/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 = 17819364;
|
|
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
|
|
@@ -6964,6 +6950,44 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
6964
6950
|
// The files from the preload directory are preloaded using the
|
|
6965
6951
|
// auto_prepend_file php.ini directive.
|
|
6966
6952
|
FS.mkdir('/internal/shared/preload');
|
|
6953
|
+
// Create stdout and stderr devices. We can't just use Emscripten's
|
|
6954
|
+
// default stdout and stderr devices because they stop processing data
|
|
6955
|
+
// on the first null byte. However, when dealing with binary data,
|
|
6956
|
+
// null bytes are valid and common.
|
|
6957
|
+
FS.registerDevice(FS.makedev(64, 0), {
|
|
6958
|
+
open: () => {},
|
|
6959
|
+
close: () => {},
|
|
6960
|
+
read: () => 0,
|
|
6961
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
6962
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
6963
|
+
PHPWASM.onStdout(chunk);
|
|
6964
|
+
return length;
|
|
6965
|
+
},
|
|
6966
|
+
});
|
|
6967
|
+
FS.mkdev('/internal/stdout', FS.makedev(64, 0));
|
|
6968
|
+
FS.registerDevice(FS.makedev(63, 0), {
|
|
6969
|
+
open: () => {},
|
|
6970
|
+
close: () => {},
|
|
6971
|
+
read: () => 0,
|
|
6972
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
6973
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
6974
|
+
PHPWASM.onStderr(chunk);
|
|
6975
|
+
return length;
|
|
6976
|
+
},
|
|
6977
|
+
});
|
|
6978
|
+
FS.mkdev('/internal/stderr', FS.makedev(63, 0));
|
|
6979
|
+
FS.registerDevice(FS.makedev(62, 0), {
|
|
6980
|
+
open: () => {},
|
|
6981
|
+
close: () => {},
|
|
6982
|
+
read: () => 0,
|
|
6983
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
6984
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
6985
|
+
PHPWASM.onHeaders(chunk);
|
|
6986
|
+
return length;
|
|
6987
|
+
},
|
|
6988
|
+
});
|
|
6989
|
+
FS.mkdev('/internal/headers', FS.makedev(62, 0));
|
|
6990
|
+
// Handle events.
|
|
6967
6991
|
PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
|
|
6968
6992
|
? require('events').EventEmitter
|
|
6969
6993
|
: class EventEmitter {
|
|
@@ -7004,9 +7028,71 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7004
7028
|
}
|
|
7005
7029
|
}
|
|
7006
7030
|
};
|
|
7031
|
+
// Clean up the fd -> childProcess mapping when the fd is closed:
|
|
7032
|
+
const originalClose = FS.close;
|
|
7033
|
+
FS.close = function (stream) {
|
|
7034
|
+
originalClose(stream);
|
|
7035
|
+
delete PHPWASM.child_proc_by_fd[stream.fd];
|
|
7036
|
+
};
|
|
7007
7037
|
PHPWASM.child_proc_by_fd = {};
|
|
7008
7038
|
PHPWASM.child_proc_by_pid = {};
|
|
7009
7039
|
PHPWASM.input_devices = {};
|
|
7040
|
+
const originalWrite = TTY.stream_ops.write;
|
|
7041
|
+
TTY.stream_ops.write = function (stream, ...rest) {
|
|
7042
|
+
const retval = originalWrite(stream, ...rest);
|
|
7043
|
+
// Implicit flush since PHP's fflush() doesn't seem to trigger the fsync event
|
|
7044
|
+
// @TODO: Fix this at the wasm level
|
|
7045
|
+
stream.tty.ops.fsync(stream.tty);
|
|
7046
|
+
return retval;
|
|
7047
|
+
};
|
|
7048
|
+
const originalPutChar = TTY.stream_ops.put_char;
|
|
7049
|
+
TTY.stream_ops.put_char = function (tty, val) {
|
|
7050
|
+
/**
|
|
7051
|
+
* Buffer newlines that Emscripten normally ignores.
|
|
7052
|
+
*
|
|
7053
|
+
* Emscripten doesn't do it by default because its default
|
|
7054
|
+
* print function is console.log that implicitly adds a newline. We are overwriting
|
|
7055
|
+
* it with an environment-specific function that outputs exaclty what it was given,
|
|
7056
|
+
* e.g. in Node.js it's process.stdout.write(). Therefore, we need to mak sure
|
|
7057
|
+
* all the newlines make it to the output buffer.
|
|
7058
|
+
*/ if (val === 10) tty.output.push(val);
|
|
7059
|
+
return originalPutChar(tty, val);
|
|
7060
|
+
};
|
|
7061
|
+
},
|
|
7062
|
+
onHeaders: function (chunk) {
|
|
7063
|
+
if (Module['onHeaders']) {
|
|
7064
|
+
Module['onHeaders'](chunk);
|
|
7065
|
+
return;
|
|
7066
|
+
}
|
|
7067
|
+
console.log('headers', {
|
|
7068
|
+
chunk,
|
|
7069
|
+
});
|
|
7070
|
+
},
|
|
7071
|
+
onStdout: function (chunk) {
|
|
7072
|
+
if (Module['onStdout']) {
|
|
7073
|
+
Module['onStdout'](chunk);
|
|
7074
|
+
return;
|
|
7075
|
+
}
|
|
7076
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7077
|
+
process.stdout.write(chunk);
|
|
7078
|
+
} else {
|
|
7079
|
+
console.log('stdout', {
|
|
7080
|
+
chunk,
|
|
7081
|
+
});
|
|
7082
|
+
}
|
|
7083
|
+
},
|
|
7084
|
+
onStderr: function (chunk) {
|
|
7085
|
+
if (Module['onStderr']) {
|
|
7086
|
+
Module['onStderr'](chunk);
|
|
7087
|
+
return;
|
|
7088
|
+
}
|
|
7089
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7090
|
+
process.stderr.write(chunk);
|
|
7091
|
+
} else {
|
|
7092
|
+
console.warn('stderr', {
|
|
7093
|
+
chunk,
|
|
7094
|
+
});
|
|
7095
|
+
}
|
|
7010
7096
|
},
|
|
7011
7097
|
getAllWebSockets: function (sock) {
|
|
7012
7098
|
const webSockets = new Set();
|
|
@@ -7188,7 +7274,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7188
7274
|
argsArray.push(UTF8ToString(HEAPU32[charPointer >> 2]));
|
|
7189
7275
|
}
|
|
7190
7276
|
}
|
|
7191
|
-
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) :
|
|
7277
|
+
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : FS.cwd();
|
|
7192
7278
|
let envObject = null;
|
|
7193
7279
|
if (envLength) {
|
|
7194
7280
|
envObject = {};
|
|
@@ -7261,6 +7347,15 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7261
7347
|
PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd] = ProcInfo;
|
|
7262
7348
|
PHPWASM.child_proc_by_pid[ProcInfo.pid] = ProcInfo;
|
|
7263
7349
|
cp.on('exit', function (code) {
|
|
7350
|
+
for (const fd of [
|
|
7351
|
+
// The child process exited. Let's clean up its output streams:
|
|
7352
|
+
ProcInfo.stdoutChildFd,
|
|
7353
|
+
ProcInfo.stderrChildFd,
|
|
7354
|
+
]) {
|
|
7355
|
+
if (FS.streams[fd] && !FS.isClosed(FS.streams[fd])) {
|
|
7356
|
+
FS.close(FS.streams[fd]);
|
|
7357
|
+
}
|
|
7358
|
+
}
|
|
7264
7359
|
ProcInfo.exitCode = code;
|
|
7265
7360
|
ProcInfo.exited = true;
|
|
7266
7361
|
// Emit events for the wasm_poll_socket function.
|
|
@@ -7311,12 +7406,52 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7311
7406
|
* listen to the 'exit' event.
|
|
7312
7407
|
*/ try {
|
|
7313
7408
|
await new Promise((resolve, reject) => {
|
|
7314
|
-
|
|
7315
|
-
|
|
7409
|
+
/**
|
|
7410
|
+
* There was no `await` between the `spawnProcess` call
|
|
7411
|
+
* and the `await` below so the process haven't had a chance
|
|
7412
|
+
* to run any of the exit-related callbacks yet.
|
|
7413
|
+
*
|
|
7414
|
+
* Good.
|
|
7415
|
+
*
|
|
7416
|
+
* Let's listen to all the lifecycle events and resolve
|
|
7417
|
+
* the promise when the process starts or immediately crashes.
|
|
7418
|
+
*/ let resolved = false;
|
|
7419
|
+
cp.on('spawn', () => {
|
|
7420
|
+
if (resolved) return;
|
|
7421
|
+
resolved = true;
|
|
7422
|
+
resolve();
|
|
7423
|
+
});
|
|
7424
|
+
cp.on('error', (e) => {
|
|
7425
|
+
if (resolved) return;
|
|
7426
|
+
resolved = true;
|
|
7427
|
+
reject(e);
|
|
7428
|
+
});
|
|
7429
|
+
cp.on('exit', function (code) {
|
|
7430
|
+
if (resolved) return;
|
|
7431
|
+
resolved = true;
|
|
7432
|
+
if (code === 0) {
|
|
7433
|
+
resolve();
|
|
7434
|
+
} else {
|
|
7435
|
+
reject(
|
|
7436
|
+
new Error(`Process exited with code ${code}`)
|
|
7437
|
+
);
|
|
7438
|
+
}
|
|
7439
|
+
});
|
|
7440
|
+
/**
|
|
7441
|
+
* If the process haven't even started after 5 seconds, something
|
|
7442
|
+
* is wrong. Perhaps we're missing an event listener, or perhaps
|
|
7443
|
+
* the `spawnProcess` implementation failed to dispatch the relevant
|
|
7444
|
+
* event. Either way, let's crash to avoid blocking the proc_open()
|
|
7445
|
+
* call indefinitely.
|
|
7446
|
+
*/ setTimeout(() => {
|
|
7447
|
+
if (resolved) return;
|
|
7448
|
+
resolved = true;
|
|
7449
|
+
reject(new Error('Process timed out'));
|
|
7450
|
+
}, 5e3);
|
|
7316
7451
|
});
|
|
7317
7452
|
} catch (e) {
|
|
7318
7453
|
console.error(e);
|
|
7319
|
-
wakeUp(
|
|
7454
|
+
wakeUp(ProcInfo.pid);
|
|
7320
7455
|
return;
|
|
7321
7456
|
}
|
|
7322
7457
|
// Now we want to pass data from the STDIN source supplied by PHP
|
|
@@ -8022,14 +8157,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8022
8157
|
const POLLNVAL = 32;
|
|
8023
8158
|
return returnCallback((wakeUp) => {
|
|
8024
8159
|
const polls = [];
|
|
8025
|
-
if (socketd
|
|
8026
|
-
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8027
|
-
if (procInfo.exited) {
|
|
8028
|
-
wakeUp(0);
|
|
8029
|
-
return;
|
|
8030
|
-
}
|
|
8031
|
-
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8032
|
-
} else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8160
|
+
if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8033
8161
|
const sock = getSocketFromFD(socketd);
|
|
8034
8162
|
if (!sock) {
|
|
8035
8163
|
wakeUp(0);
|
|
@@ -8063,7 +8191,12 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8063
8191
|
polls.push(PHPWASM.awaitConnection(ws));
|
|
8064
8192
|
lookingFor.add('POLLOUT');
|
|
8065
8193
|
}
|
|
8066
|
-
if (
|
|
8194
|
+
if (
|
|
8195
|
+
events & POLLHUP ||
|
|
8196
|
+
events & POLLIN ||
|
|
8197
|
+
events & POLLOUT ||
|
|
8198
|
+
events & POLLERR
|
|
8199
|
+
) {
|
|
8067
8200
|
polls.push(PHPWASM.awaitClose(ws));
|
|
8068
8201
|
lookingFor.add('POLLHUP');
|
|
8069
8202
|
}
|
|
@@ -8072,6 +8205,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8072
8205
|
lookingFor.add('POLLERR');
|
|
8073
8206
|
}
|
|
8074
8207
|
}
|
|
8208
|
+
} else if (socketd in PHPWASM.child_proc_by_fd) {
|
|
8209
|
+
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8210
|
+
if (procInfo.exited) {
|
|
8211
|
+
wakeUp(0);
|
|
8212
|
+
return;
|
|
8213
|
+
}
|
|
8214
|
+
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8075
8215
|
} else {
|
|
8076
8216
|
setTimeout(function () {
|
|
8077
8217
|
wakeUp(1);
|
|
@@ -8357,13 +8497,6 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8357
8497
|
(___wrap_select = Module['___wrap_select'] =
|
|
8358
8498
|
wasmExports['__wrap_select'])(a0, a1, a2, a3, a4));
|
|
8359
8499
|
|
|
8360
|
-
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8361
|
-
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] =
|
|
8362
|
-
wasmExports['wasm_add_cli_arg'])(a0));
|
|
8363
|
-
|
|
8364
|
-
var _run_cli = (Module['_run_cli'] = () =>
|
|
8365
|
-
(_run_cli = Module['_run_cli'] = wasmExports['run_cli'])());
|
|
8366
|
-
|
|
8367
8500
|
var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
|
|
8368
8501
|
(_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
|
|
8369
8502
|
wasmExports['wasm_set_sapi_name'])(a0));
|
|
@@ -8372,6 +8505,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8372
8505
|
(_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
|
|
8373
8506
|
wasmExports['wasm_set_phpini_path'])(a0));
|
|
8374
8507
|
|
|
8508
|
+
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8509
|
+
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] =
|
|
8510
|
+
wasmExports['wasm_add_cli_arg'])(a0));
|
|
8511
|
+
|
|
8512
|
+
var _run_cli = (Module['_run_cli'] = () =>
|
|
8513
|
+
(_run_cli = Module['_run_cli'] = wasmExports['run_cli'])());
|
|
8514
|
+
|
|
8375
8515
|
var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
|
|
8376
8516
|
(_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
|
|
8377
8517
|
wasmExports['wasm_add_SERVER_entry'])(a0, a1));
|
package/jspi/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 = 17913929;
|
|
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
|
|
@@ -6964,6 +6950,44 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
6964
6950
|
// The files from the preload directory are preloaded using the
|
|
6965
6951
|
// auto_prepend_file php.ini directive.
|
|
6966
6952
|
FS.mkdir('/internal/shared/preload');
|
|
6953
|
+
// Create stdout and stderr devices. We can't just use Emscripten's
|
|
6954
|
+
// default stdout and stderr devices because they stop processing data
|
|
6955
|
+
// on the first null byte. However, when dealing with binary data,
|
|
6956
|
+
// null bytes are valid and common.
|
|
6957
|
+
FS.registerDevice(FS.makedev(64, 0), {
|
|
6958
|
+
open: () => {},
|
|
6959
|
+
close: () => {},
|
|
6960
|
+
read: () => 0,
|
|
6961
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
6962
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
6963
|
+
PHPWASM.onStdout(chunk);
|
|
6964
|
+
return length;
|
|
6965
|
+
},
|
|
6966
|
+
});
|
|
6967
|
+
FS.mkdev('/internal/stdout', FS.makedev(64, 0));
|
|
6968
|
+
FS.registerDevice(FS.makedev(63, 0), {
|
|
6969
|
+
open: () => {},
|
|
6970
|
+
close: () => {},
|
|
6971
|
+
read: () => 0,
|
|
6972
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
6973
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
6974
|
+
PHPWASM.onStderr(chunk);
|
|
6975
|
+
return length;
|
|
6976
|
+
},
|
|
6977
|
+
});
|
|
6978
|
+
FS.mkdev('/internal/stderr', FS.makedev(63, 0));
|
|
6979
|
+
FS.registerDevice(FS.makedev(62, 0), {
|
|
6980
|
+
open: () => {},
|
|
6981
|
+
close: () => {},
|
|
6982
|
+
read: () => 0,
|
|
6983
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
6984
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
6985
|
+
PHPWASM.onHeaders(chunk);
|
|
6986
|
+
return length;
|
|
6987
|
+
},
|
|
6988
|
+
});
|
|
6989
|
+
FS.mkdev('/internal/headers', FS.makedev(62, 0));
|
|
6990
|
+
// Handle events.
|
|
6967
6991
|
PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
|
|
6968
6992
|
? require('events').EventEmitter
|
|
6969
6993
|
: class EventEmitter {
|
|
@@ -7004,9 +7028,71 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7004
7028
|
}
|
|
7005
7029
|
}
|
|
7006
7030
|
};
|
|
7031
|
+
// Clean up the fd -> childProcess mapping when the fd is closed:
|
|
7032
|
+
const originalClose = FS.close;
|
|
7033
|
+
FS.close = function (stream) {
|
|
7034
|
+
originalClose(stream);
|
|
7035
|
+
delete PHPWASM.child_proc_by_fd[stream.fd];
|
|
7036
|
+
};
|
|
7007
7037
|
PHPWASM.child_proc_by_fd = {};
|
|
7008
7038
|
PHPWASM.child_proc_by_pid = {};
|
|
7009
7039
|
PHPWASM.input_devices = {};
|
|
7040
|
+
const originalWrite = TTY.stream_ops.write;
|
|
7041
|
+
TTY.stream_ops.write = function (stream, ...rest) {
|
|
7042
|
+
const retval = originalWrite(stream, ...rest);
|
|
7043
|
+
// Implicit flush since PHP's fflush() doesn't seem to trigger the fsync event
|
|
7044
|
+
// @TODO: Fix this at the wasm level
|
|
7045
|
+
stream.tty.ops.fsync(stream.tty);
|
|
7046
|
+
return retval;
|
|
7047
|
+
};
|
|
7048
|
+
const originalPutChar = TTY.stream_ops.put_char;
|
|
7049
|
+
TTY.stream_ops.put_char = function (tty, val) {
|
|
7050
|
+
/**
|
|
7051
|
+
* Buffer newlines that Emscripten normally ignores.
|
|
7052
|
+
*
|
|
7053
|
+
* Emscripten doesn't do it by default because its default
|
|
7054
|
+
* print function is console.log that implicitly adds a newline. We are overwriting
|
|
7055
|
+
* it with an environment-specific function that outputs exaclty what it was given,
|
|
7056
|
+
* e.g. in Node.js it's process.stdout.write(). Therefore, we need to mak sure
|
|
7057
|
+
* all the newlines make it to the output buffer.
|
|
7058
|
+
*/ if (val === 10) tty.output.push(val);
|
|
7059
|
+
return originalPutChar(tty, val);
|
|
7060
|
+
};
|
|
7061
|
+
},
|
|
7062
|
+
onHeaders: function (chunk) {
|
|
7063
|
+
if (Module['onHeaders']) {
|
|
7064
|
+
Module['onHeaders'](chunk);
|
|
7065
|
+
return;
|
|
7066
|
+
}
|
|
7067
|
+
console.log('headers', {
|
|
7068
|
+
chunk,
|
|
7069
|
+
});
|
|
7070
|
+
},
|
|
7071
|
+
onStdout: function (chunk) {
|
|
7072
|
+
if (Module['onStdout']) {
|
|
7073
|
+
Module['onStdout'](chunk);
|
|
7074
|
+
return;
|
|
7075
|
+
}
|
|
7076
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7077
|
+
process.stdout.write(chunk);
|
|
7078
|
+
} else {
|
|
7079
|
+
console.log('stdout', {
|
|
7080
|
+
chunk,
|
|
7081
|
+
});
|
|
7082
|
+
}
|
|
7083
|
+
},
|
|
7084
|
+
onStderr: function (chunk) {
|
|
7085
|
+
if (Module['onStderr']) {
|
|
7086
|
+
Module['onStderr'](chunk);
|
|
7087
|
+
return;
|
|
7088
|
+
}
|
|
7089
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
7090
|
+
process.stderr.write(chunk);
|
|
7091
|
+
} else {
|
|
7092
|
+
console.warn('stderr', {
|
|
7093
|
+
chunk,
|
|
7094
|
+
});
|
|
7095
|
+
}
|
|
7010
7096
|
},
|
|
7011
7097
|
getAllWebSockets: function (sock) {
|
|
7012
7098
|
const webSockets = new Set();
|
|
@@ -7188,7 +7274,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7188
7274
|
argsArray.push(UTF8ToString(HEAPU32[charPointer >> 2]));
|
|
7189
7275
|
}
|
|
7190
7276
|
}
|
|
7191
|
-
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) :
|
|
7277
|
+
const cwdstr = cwdPtr ? UTF8ToString(cwdPtr) : FS.cwd();
|
|
7192
7278
|
let envObject = null;
|
|
7193
7279
|
if (envLength) {
|
|
7194
7280
|
envObject = {};
|
|
@@ -7261,6 +7347,15 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7261
7347
|
PHPWASM.child_proc_by_fd[ProcInfo.stderrParentFd] = ProcInfo;
|
|
7262
7348
|
PHPWASM.child_proc_by_pid[ProcInfo.pid] = ProcInfo;
|
|
7263
7349
|
cp.on('exit', function (code) {
|
|
7350
|
+
for (const fd of [
|
|
7351
|
+
// The child process exited. Let's clean up its output streams:
|
|
7352
|
+
ProcInfo.stdoutChildFd,
|
|
7353
|
+
ProcInfo.stderrChildFd,
|
|
7354
|
+
]) {
|
|
7355
|
+
if (FS.streams[fd] && !FS.isClosed(FS.streams[fd])) {
|
|
7356
|
+
FS.close(FS.streams[fd]);
|
|
7357
|
+
}
|
|
7358
|
+
}
|
|
7264
7359
|
ProcInfo.exitCode = code;
|
|
7265
7360
|
ProcInfo.exited = true;
|
|
7266
7361
|
// Emit events for the wasm_poll_socket function.
|
|
@@ -7311,12 +7406,52 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7311
7406
|
* listen to the 'exit' event.
|
|
7312
7407
|
*/ try {
|
|
7313
7408
|
await new Promise((resolve, reject) => {
|
|
7314
|
-
|
|
7315
|
-
|
|
7409
|
+
/**
|
|
7410
|
+
* There was no `await` between the `spawnProcess` call
|
|
7411
|
+
* and the `await` below so the process haven't had a chance
|
|
7412
|
+
* to run any of the exit-related callbacks yet.
|
|
7413
|
+
*
|
|
7414
|
+
* Good.
|
|
7415
|
+
*
|
|
7416
|
+
* Let's listen to all the lifecycle events and resolve
|
|
7417
|
+
* the promise when the process starts or immediately crashes.
|
|
7418
|
+
*/ let resolved = false;
|
|
7419
|
+
cp.on('spawn', () => {
|
|
7420
|
+
if (resolved) return;
|
|
7421
|
+
resolved = true;
|
|
7422
|
+
resolve();
|
|
7423
|
+
});
|
|
7424
|
+
cp.on('error', (e) => {
|
|
7425
|
+
if (resolved) return;
|
|
7426
|
+
resolved = true;
|
|
7427
|
+
reject(e);
|
|
7428
|
+
});
|
|
7429
|
+
cp.on('exit', function (code) {
|
|
7430
|
+
if (resolved) return;
|
|
7431
|
+
resolved = true;
|
|
7432
|
+
if (code === 0) {
|
|
7433
|
+
resolve();
|
|
7434
|
+
} else {
|
|
7435
|
+
reject(
|
|
7436
|
+
new Error(`Process exited with code ${code}`)
|
|
7437
|
+
);
|
|
7438
|
+
}
|
|
7439
|
+
});
|
|
7440
|
+
/**
|
|
7441
|
+
* If the process haven't even started after 5 seconds, something
|
|
7442
|
+
* is wrong. Perhaps we're missing an event listener, or perhaps
|
|
7443
|
+
* the `spawnProcess` implementation failed to dispatch the relevant
|
|
7444
|
+
* event. Either way, let's crash to avoid blocking the proc_open()
|
|
7445
|
+
* call indefinitely.
|
|
7446
|
+
*/ setTimeout(() => {
|
|
7447
|
+
if (resolved) return;
|
|
7448
|
+
resolved = true;
|
|
7449
|
+
reject(new Error('Process timed out'));
|
|
7450
|
+
}, 5e3);
|
|
7316
7451
|
});
|
|
7317
7452
|
} catch (e) {
|
|
7318
7453
|
console.error(e);
|
|
7319
|
-
wakeUp(
|
|
7454
|
+
wakeUp(ProcInfo.pid);
|
|
7320
7455
|
return;
|
|
7321
7456
|
}
|
|
7322
7457
|
// Now we want to pass data from the STDIN source supplied by PHP
|
|
@@ -8022,14 +8157,7 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8022
8157
|
const POLLNVAL = 32;
|
|
8023
8158
|
return returnCallback((wakeUp) => {
|
|
8024
8159
|
const polls = [];
|
|
8025
|
-
if (socketd
|
|
8026
|
-
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8027
|
-
if (procInfo.exited) {
|
|
8028
|
-
wakeUp(0);
|
|
8029
|
-
return;
|
|
8030
|
-
}
|
|
8031
|
-
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8032
|
-
} else if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8160
|
+
if (FS.isSocket(FS.getStream(socketd)?.node.mode)) {
|
|
8033
8161
|
const sock = getSocketFromFD(socketd);
|
|
8034
8162
|
if (!sock) {
|
|
8035
8163
|
wakeUp(0);
|
|
@@ -8063,7 +8191,12 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8063
8191
|
polls.push(PHPWASM.awaitConnection(ws));
|
|
8064
8192
|
lookingFor.add('POLLOUT');
|
|
8065
8193
|
}
|
|
8066
|
-
if (
|
|
8194
|
+
if (
|
|
8195
|
+
events & POLLHUP ||
|
|
8196
|
+
events & POLLIN ||
|
|
8197
|
+
events & POLLOUT ||
|
|
8198
|
+
events & POLLERR
|
|
8199
|
+
) {
|
|
8067
8200
|
polls.push(PHPWASM.awaitClose(ws));
|
|
8068
8201
|
lookingFor.add('POLLHUP');
|
|
8069
8202
|
}
|
|
@@ -8072,6 +8205,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8072
8205
|
lookingFor.add('POLLERR');
|
|
8073
8206
|
}
|
|
8074
8207
|
}
|
|
8208
|
+
} else if (socketd in PHPWASM.child_proc_by_fd) {
|
|
8209
|
+
const procInfo = PHPWASM.child_proc_by_fd[socketd];
|
|
8210
|
+
if (procInfo.exited) {
|
|
8211
|
+
wakeUp(0);
|
|
8212
|
+
return;
|
|
8213
|
+
}
|
|
8214
|
+
polls.push(PHPWASM.awaitEvent(procInfo.stdout, 'data'));
|
|
8075
8215
|
} else {
|
|
8076
8216
|
setTimeout(function () {
|
|
8077
8217
|
wakeUp(1);
|
|
@@ -8357,13 +8497,6 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8357
8497
|
(___wrap_select = Module['___wrap_select'] =
|
|
8358
8498
|
wasmExports['__wrap_select'])(a0, a1, a2, a3, a4));
|
|
8359
8499
|
|
|
8360
|
-
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8361
|
-
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] =
|
|
8362
|
-
wasmExports['wasm_add_cli_arg'])(a0));
|
|
8363
|
-
|
|
8364
|
-
var _run_cli = (Module['_run_cli'] = () =>
|
|
8365
|
-
(_run_cli = Module['_run_cli'] = wasmExports['run_cli'])());
|
|
8366
|
-
|
|
8367
8500
|
var _wasm_set_sapi_name = (Module['_wasm_set_sapi_name'] = (a0) =>
|
|
8368
8501
|
(_wasm_set_sapi_name = Module['_wasm_set_sapi_name'] =
|
|
8369
8502
|
wasmExports['wasm_set_sapi_name'])(a0));
|
|
@@ -8372,6 +8505,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8372
8505
|
(_wasm_set_phpini_path = Module['_wasm_set_phpini_path'] =
|
|
8373
8506
|
wasmExports['wasm_set_phpini_path'])(a0));
|
|
8374
8507
|
|
|
8508
|
+
var _wasm_add_cli_arg = (Module['_wasm_add_cli_arg'] = (a0) =>
|
|
8509
|
+
(_wasm_add_cli_arg = Module['_wasm_add_cli_arg'] =
|
|
8510
|
+
wasmExports['wasm_add_cli_arg'])(a0));
|
|
8511
|
+
|
|
8512
|
+
var _run_cli = (Module['_run_cli'] = () =>
|
|
8513
|
+
(_run_cli = Module['_run_cli'] = wasmExports['run_cli'])());
|
|
8514
|
+
|
|
8375
8515
|
var _wasm_add_SERVER_entry = (Module['_wasm_add_SERVER_entry'] = (a0, a1) =>
|
|
8376
8516
|
(_wasm_add_SERVER_entry = Module['_wasm_add_SERVER_entry'] =
|
|
8377
8517
|
wasmExports['wasm_add_SERVER_entry'])(a0, a1));
|