@php-wasm/node 1.1.3 → 1.1.4
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 +178 -138
- package/asyncify/php_7_3.js +177 -137
- package/asyncify/php_7_4.js +176 -136
- package/asyncify/php_8_0.js +180 -140
- package/asyncify/php_8_1.js +179 -139
- package/asyncify/php_8_2.js +180 -140
- package/asyncify/php_8_3.js +180 -140
- package/asyncify/php_8_4.js +179 -139
- package/fs_ext.node +0 -0
- package/index.cjs +9170 -3617
- package/index.js +9054 -3617
- 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 +1922 -1286
- package/jspi/php_7_3.js +1922 -1286
- package/jspi/php_7_4.js +9262 -7705
- package/jspi/php_8_0.js +1922 -1286
- package/jspi/php_8_1.js +2434 -1798
- package/jspi/php_8_2.js +2414 -1778
- package/jspi/php_8_3.js +2414 -1778
- package/jspi/php_8_4.js +2414 -1778
- package/lib/file-lock-manager-for-node.d.ts +149 -0
- package/lib/file-lock-manager.d.ts +96 -0
- package/lib/index.d.ts +2 -0
- package/lib/load-runtime.d.ts +31 -2
- package/package.json +10 -9
package/jspi/php_7_3.js
CHANGED
|
@@ -8,7 +8,7 @@ import path from 'path';
|
|
|
8
8
|
|
|
9
9
|
const dependencyFilename = path.join(__dirname, '7_3_33', 'php_7_3.wasm');
|
|
10
10
|
export { dependencyFilename };
|
|
11
|
-
export const dependenciesTotalSize =
|
|
11
|
+
export const dependenciesTotalSize = 17915848;
|
|
12
12
|
export function init(RuntimeName, PHPLoader) {
|
|
13
13
|
// The rest of the code comes from the built php.js file and esm-suffix.js
|
|
14
14
|
// include: shell.js
|
|
@@ -5209,7 +5209,360 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
5209
5209
|
|
|
5210
5210
|
var syscallGetVarargP = syscallGetVarargI;
|
|
5211
5211
|
|
|
5212
|
-
|
|
5212
|
+
var stringToUTF8 = (str, outPtr, maxBytesToWrite) =>
|
|
5213
|
+
stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
|
|
5214
|
+
|
|
5215
|
+
Module['stringToUTF8'] = stringToUTF8;
|
|
5216
|
+
|
|
5217
|
+
var stackAlloc = (sz) => __emscripten_stack_alloc(sz);
|
|
5218
|
+
|
|
5219
|
+
/** @suppress {duplicate } */ var stringToUTF8OnStack = (str) => {
|
|
5220
|
+
var size = lengthBytesUTF8(str) + 1;
|
|
5221
|
+
var ret = stackAlloc(size);
|
|
5222
|
+
stringToUTF8(str, ret, size);
|
|
5223
|
+
return ret;
|
|
5224
|
+
};
|
|
5225
|
+
|
|
5226
|
+
var allocateUTF8OnStack = stringToUTF8OnStack;
|
|
5227
|
+
|
|
5228
|
+
var PHPWASM = {
|
|
5229
|
+
init: function () {
|
|
5230
|
+
// The /internal directory is required by the C module. It's where the
|
|
5231
|
+
// stdout, stderr, and headers information are written for the JavaScript
|
|
5232
|
+
// code to read later on.
|
|
5233
|
+
FS.mkdir('/internal');
|
|
5234
|
+
// The files from the shared directory are shared between all the
|
|
5235
|
+
// PHP processes managed by PHPProcessManager.
|
|
5236
|
+
FS.mkdir('/internal/shared');
|
|
5237
|
+
// The files from the preload directory are preloaded using the
|
|
5238
|
+
// auto_prepend_file php.ini directive.
|
|
5239
|
+
FS.mkdir('/internal/shared/preload');
|
|
5240
|
+
// Create stdout and stderr devices. We can't just use Emscripten's
|
|
5241
|
+
// default stdout and stderr devices because they stop processing data
|
|
5242
|
+
// on the first null byte. However, when dealing with binary data,
|
|
5243
|
+
// null bytes are valid and common.
|
|
5244
|
+
FS.registerDevice(FS.makedev(64, 0), {
|
|
5245
|
+
open: () => {},
|
|
5246
|
+
close: () => {},
|
|
5247
|
+
read: () => 0,
|
|
5248
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
5249
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
5250
|
+
PHPWASM.onStdout(chunk);
|
|
5251
|
+
return length;
|
|
5252
|
+
},
|
|
5253
|
+
});
|
|
5254
|
+
FS.mkdev('/internal/stdout', FS.makedev(64, 0));
|
|
5255
|
+
FS.registerDevice(FS.makedev(63, 0), {
|
|
5256
|
+
open: () => {},
|
|
5257
|
+
close: () => {},
|
|
5258
|
+
read: () => 0,
|
|
5259
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
5260
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
5261
|
+
PHPWASM.onStderr(chunk);
|
|
5262
|
+
return length;
|
|
5263
|
+
},
|
|
5264
|
+
});
|
|
5265
|
+
FS.mkdev('/internal/stderr', FS.makedev(63, 0));
|
|
5266
|
+
FS.registerDevice(FS.makedev(62, 0), {
|
|
5267
|
+
open: () => {},
|
|
5268
|
+
close: () => {},
|
|
5269
|
+
read: () => 0,
|
|
5270
|
+
write: (stream, buffer, offset, length, pos) => {
|
|
5271
|
+
const chunk = buffer.subarray(offset, offset + length);
|
|
5272
|
+
PHPWASM.onHeaders(chunk);
|
|
5273
|
+
return length;
|
|
5274
|
+
},
|
|
5275
|
+
});
|
|
5276
|
+
FS.mkdev('/internal/headers', FS.makedev(62, 0));
|
|
5277
|
+
// Handle events.
|
|
5278
|
+
PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
|
|
5279
|
+
? require('events').EventEmitter
|
|
5280
|
+
: class EventEmitter {
|
|
5281
|
+
constructor() {
|
|
5282
|
+
this.listeners = {};
|
|
5283
|
+
}
|
|
5284
|
+
emit(eventName, data) {
|
|
5285
|
+
if (this.listeners[eventName]) {
|
|
5286
|
+
this.listeners[eventName].forEach(
|
|
5287
|
+
(callback) => {
|
|
5288
|
+
callback(data);
|
|
5289
|
+
}
|
|
5290
|
+
);
|
|
5291
|
+
}
|
|
5292
|
+
}
|
|
5293
|
+
once(eventName, callback) {
|
|
5294
|
+
const self = this;
|
|
5295
|
+
function removedCallback() {
|
|
5296
|
+
callback(...arguments);
|
|
5297
|
+
self.removeListener(eventName, removedCallback);
|
|
5298
|
+
}
|
|
5299
|
+
this.on(eventName, removedCallback);
|
|
5300
|
+
}
|
|
5301
|
+
removeAllListeners(eventName) {
|
|
5302
|
+
if (eventName) {
|
|
5303
|
+
delete this.listeners[eventName];
|
|
5304
|
+
} else {
|
|
5305
|
+
this.listeners = {};
|
|
5306
|
+
}
|
|
5307
|
+
}
|
|
5308
|
+
removeListener(eventName, callback) {
|
|
5309
|
+
if (this.listeners[eventName]) {
|
|
5310
|
+
const idx =
|
|
5311
|
+
this.listeners[eventName].indexOf(callback);
|
|
5312
|
+
if (idx !== -1) {
|
|
5313
|
+
this.listeners[eventName].splice(idx, 1);
|
|
5314
|
+
}
|
|
5315
|
+
}
|
|
5316
|
+
}
|
|
5317
|
+
};
|
|
5318
|
+
// Clean up the fd -> childProcess mapping when the fd is closed:
|
|
5319
|
+
const originalClose = FS.close;
|
|
5320
|
+
FS.close = function (stream) {
|
|
5321
|
+
originalClose(stream);
|
|
5322
|
+
delete PHPWASM.child_proc_by_fd[stream.fd];
|
|
5323
|
+
};
|
|
5324
|
+
PHPWASM.child_proc_by_fd = {};
|
|
5325
|
+
PHPWASM.child_proc_by_pid = {};
|
|
5326
|
+
PHPWASM.input_devices = {};
|
|
5327
|
+
const originalWrite = TTY.stream_ops.write;
|
|
5328
|
+
TTY.stream_ops.write = function (stream, ...rest) {
|
|
5329
|
+
const retval = originalWrite(stream, ...rest);
|
|
5330
|
+
// Implicit flush since PHP's fflush() doesn't seem to trigger the fsync event
|
|
5331
|
+
// @TODO: Fix this at the wasm level
|
|
5332
|
+
stream.tty.ops.fsync(stream.tty);
|
|
5333
|
+
return retval;
|
|
5334
|
+
};
|
|
5335
|
+
const originalPutChar = TTY.stream_ops.put_char;
|
|
5336
|
+
TTY.stream_ops.put_char = function (tty, val) {
|
|
5337
|
+
/**
|
|
5338
|
+
* Buffer newlines that Emscripten normally ignores.
|
|
5339
|
+
*
|
|
5340
|
+
* Emscripten doesn't do it by default because its default
|
|
5341
|
+
* print function is console.log that implicitly adds a newline. We are overwriting
|
|
5342
|
+
* it with an environment-specific function that outputs exaclty what it was given,
|
|
5343
|
+
* e.g. in Node.js it's process.stdout.write(). Therefore, we need to mak sure
|
|
5344
|
+
* all the newlines make it to the output buffer.
|
|
5345
|
+
*/ if (val === 10) tty.output.push(val);
|
|
5346
|
+
return originalPutChar(tty, val);
|
|
5347
|
+
};
|
|
5348
|
+
},
|
|
5349
|
+
onHeaders: function (chunk) {
|
|
5350
|
+
if (Module['onHeaders']) {
|
|
5351
|
+
Module['onHeaders'](chunk);
|
|
5352
|
+
return;
|
|
5353
|
+
}
|
|
5354
|
+
console.log('headers', {
|
|
5355
|
+
chunk,
|
|
5356
|
+
});
|
|
5357
|
+
},
|
|
5358
|
+
onStdout: function (chunk) {
|
|
5359
|
+
if (Module['onStdout']) {
|
|
5360
|
+
Module['onStdout'](chunk);
|
|
5361
|
+
return;
|
|
5362
|
+
}
|
|
5363
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
5364
|
+
process.stdout.write(chunk);
|
|
5365
|
+
} else {
|
|
5366
|
+
console.log('stdout', {
|
|
5367
|
+
chunk,
|
|
5368
|
+
});
|
|
5369
|
+
}
|
|
5370
|
+
},
|
|
5371
|
+
onStderr: function (chunk) {
|
|
5372
|
+
if (Module['onStderr']) {
|
|
5373
|
+
Module['onStderr'](chunk);
|
|
5374
|
+
return;
|
|
5375
|
+
}
|
|
5376
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
5377
|
+
process.stderr.write(chunk);
|
|
5378
|
+
} else {
|
|
5379
|
+
console.warn('stderr', {
|
|
5380
|
+
chunk,
|
|
5381
|
+
});
|
|
5382
|
+
}
|
|
5383
|
+
},
|
|
5384
|
+
getAllWebSockets: function (sock) {
|
|
5385
|
+
const webSockets = new Set();
|
|
5386
|
+
if (sock.server) {
|
|
5387
|
+
sock.server.clients.forEach((ws) => {
|
|
5388
|
+
webSockets.add(ws);
|
|
5389
|
+
});
|
|
5390
|
+
}
|
|
5391
|
+
for (const peer of PHPWASM.getAllPeers(sock)) {
|
|
5392
|
+
webSockets.add(peer.socket);
|
|
5393
|
+
}
|
|
5394
|
+
return Array.from(webSockets);
|
|
5395
|
+
},
|
|
5396
|
+
getAllPeers: function (sock) {
|
|
5397
|
+
const peers = new Set();
|
|
5398
|
+
if (sock.server) {
|
|
5399
|
+
sock.pending
|
|
5400
|
+
.filter((pending) => pending.peers)
|
|
5401
|
+
.forEach((pending) => {
|
|
5402
|
+
for (const peer of Object.values(pending.peers)) {
|
|
5403
|
+
peers.add(peer);
|
|
5404
|
+
}
|
|
5405
|
+
});
|
|
5406
|
+
}
|
|
5407
|
+
if (sock.peers) {
|
|
5408
|
+
for (const peer of Object.values(sock.peers)) {
|
|
5409
|
+
peers.add(peer);
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
return Array.from(peers);
|
|
5413
|
+
},
|
|
5414
|
+
awaitData: function (ws) {
|
|
5415
|
+
return PHPWASM.awaitEvent(ws, 'message');
|
|
5416
|
+
},
|
|
5417
|
+
awaitConnection: function (ws) {
|
|
5418
|
+
if (ws.OPEN === ws.readyState) {
|
|
5419
|
+
return [Promise.resolve(), PHPWASM.noop];
|
|
5420
|
+
}
|
|
5421
|
+
return PHPWASM.awaitEvent(ws, 'open');
|
|
5422
|
+
},
|
|
5423
|
+
awaitClose: function (ws) {
|
|
5424
|
+
if ([ws.CLOSING, ws.CLOSED].includes(ws.readyState)) {
|
|
5425
|
+
return [Promise.resolve(), PHPWASM.noop];
|
|
5426
|
+
}
|
|
5427
|
+
return PHPWASM.awaitEvent(ws, 'close');
|
|
5428
|
+
},
|
|
5429
|
+
awaitError: function (ws) {
|
|
5430
|
+
if ([ws.CLOSING, ws.CLOSED].includes(ws.readyState)) {
|
|
5431
|
+
return [Promise.resolve(), PHPWASM.noop];
|
|
5432
|
+
}
|
|
5433
|
+
return PHPWASM.awaitEvent(ws, 'error');
|
|
5434
|
+
},
|
|
5435
|
+
awaitEvent: function (ws, event) {
|
|
5436
|
+
let resolve;
|
|
5437
|
+
const listener = () => {
|
|
5438
|
+
resolve();
|
|
5439
|
+
};
|
|
5440
|
+
const promise = new Promise(function (_resolve) {
|
|
5441
|
+
resolve = _resolve;
|
|
5442
|
+
ws.once(event, listener);
|
|
5443
|
+
});
|
|
5444
|
+
const cancel = () => {
|
|
5445
|
+
ws.removeListener(event, listener);
|
|
5446
|
+
// Rejecting the promises bubbles up and kills the entire
|
|
5447
|
+
// node process. Let's resolve them on the next tick instead
|
|
5448
|
+
// to give the caller some space to unbind any handlers.
|
|
5449
|
+
setTimeout(resolve);
|
|
5450
|
+
};
|
|
5451
|
+
return [promise, cancel];
|
|
5452
|
+
},
|
|
5453
|
+
noop: function () {},
|
|
5454
|
+
spawnProcess: function (command, args, options) {
|
|
5455
|
+
if (Module['spawnProcess']) {
|
|
5456
|
+
const spawnedPromise = Module['spawnProcess'](
|
|
5457
|
+
command,
|
|
5458
|
+
args,
|
|
5459
|
+
options
|
|
5460
|
+
);
|
|
5461
|
+
return Promise.resolve(spawnedPromise).then(function (spawned) {
|
|
5462
|
+
if (!spawned || !spawned.on) {
|
|
5463
|
+
throw new Error(
|
|
5464
|
+
'spawnProcess() must return an EventEmitter but returned a different type.'
|
|
5465
|
+
);
|
|
5466
|
+
}
|
|
5467
|
+
return spawned;
|
|
5468
|
+
});
|
|
5469
|
+
}
|
|
5470
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
5471
|
+
return require('child_process').spawn(command, args, {
|
|
5472
|
+
...options,
|
|
5473
|
+
shell: true,
|
|
5474
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
5475
|
+
timeout: 100,
|
|
5476
|
+
});
|
|
5477
|
+
}
|
|
5478
|
+
const e = new Error(
|
|
5479
|
+
'popen(), proc_open() etc. are unsupported in the browser. Call php.setSpawnHandler() ' +
|
|
5480
|
+
'and provide a callback to handle spawning processes, or disable a popen(), proc_open() ' +
|
|
5481
|
+
'and similar functions via php.ini.'
|
|
5482
|
+
);
|
|
5483
|
+
e.code = 'SPAWN_UNSUPPORTED';
|
|
5484
|
+
throw e;
|
|
5485
|
+
},
|
|
5486
|
+
shutdownSocket: function (socketd, how) {
|
|
5487
|
+
// This implementation only supports websockets at the moment
|
|
5488
|
+
const sock = getSocketFromFD(socketd);
|
|
5489
|
+
const peer = Object.values(sock.peers)[0];
|
|
5490
|
+
if (!peer) {
|
|
5491
|
+
return -1;
|
|
5492
|
+
}
|
|
5493
|
+
try {
|
|
5494
|
+
peer.socket.close();
|
|
5495
|
+
SOCKFS.websocket_sock_ops.removePeer(sock, peer);
|
|
5496
|
+
return 0;
|
|
5497
|
+
} catch (e) {
|
|
5498
|
+
console.log('Socket shutdown error', e);
|
|
5499
|
+
return -1;
|
|
5500
|
+
}
|
|
5501
|
+
},
|
|
5502
|
+
};
|
|
5503
|
+
|
|
5504
|
+
function _js_getpid() {
|
|
5505
|
+
return PHPLoader.processId ?? 42;
|
|
5506
|
+
}
|
|
5507
|
+
|
|
5508
|
+
function _js_wasm_trace(format, ...args) {
|
|
5509
|
+
if (PHPLoader.trace instanceof Function) {
|
|
5510
|
+
PHPLoader.trace(_js_getpid(), format, ...args);
|
|
5511
|
+
}
|
|
5512
|
+
}
|
|
5513
|
+
|
|
5514
|
+
function _fd_close(fd) {
|
|
5515
|
+
_js_wasm_trace('fd_close(%d)', fd);
|
|
5516
|
+
const [vfsPath, pathResolutionErrno] = locking.get_vfs_path_from_fd(fd);
|
|
5517
|
+
if (pathResolutionErrno !== 0) {
|
|
5518
|
+
_js_wasm_trace(
|
|
5519
|
+
'fd_close(%d) get_vfs_path_from_fd error %d',
|
|
5520
|
+
fd,
|
|
5521
|
+
pathResolutionErrno
|
|
5522
|
+
);
|
|
5523
|
+
return -ERRNO_CODES.EBADF;
|
|
5524
|
+
}
|
|
5525
|
+
const result = _builtin_fd_close(fd);
|
|
5526
|
+
if (result === 0 && locking.maybeLockedFds.has(fd)) {
|
|
5527
|
+
const nativeFilePath =
|
|
5528
|
+
locking.get_native_path_from_vfs_path(vfsPath);
|
|
5529
|
+
return PHPLoader.fileLockManager
|
|
5530
|
+
.releaseLocksForProcessFd(
|
|
5531
|
+
PHPLoader.processId,
|
|
5532
|
+
fd,
|
|
5533
|
+
nativeFilePath
|
|
5534
|
+
)
|
|
5535
|
+
.then(() => {
|
|
5536
|
+
_js_wasm_trace('fd_close(%d) release locks success', fd);
|
|
5537
|
+
})
|
|
5538
|
+
.catch((e) => {
|
|
5539
|
+
_js_wasm_trace("fd_close(%d) error '%s'", fd, e);
|
|
5540
|
+
})
|
|
5541
|
+
.then(() => {
|
|
5542
|
+
_js_wasm_trace('fd_close(%d) result %d', fd, result);
|
|
5543
|
+
return result;
|
|
5544
|
+
})
|
|
5545
|
+
.finally(() => {
|
|
5546
|
+
locking.maybeLockedFds.delete(fd);
|
|
5547
|
+
});
|
|
5548
|
+
} else {
|
|
5549
|
+
_js_wasm_trace('fd_close(%d) result %d', fd, result);
|
|
5550
|
+
return result;
|
|
5551
|
+
}
|
|
5552
|
+
}
|
|
5553
|
+
|
|
5554
|
+
function _builtin_fd_close(fd) {
|
|
5555
|
+
try {
|
|
5556
|
+
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
5557
|
+
FS.close(stream);
|
|
5558
|
+
return 0;
|
|
5559
|
+
} catch (e) {
|
|
5560
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5561
|
+
return e.errno;
|
|
5562
|
+
}
|
|
5563
|
+
}
|
|
5564
|
+
|
|
5565
|
+
function _builtin_fcntl64(fd, cmd, varargs) {
|
|
5213
5566
|
SYSCALLS.varargs = varargs;
|
|
5214
5567
|
try {
|
|
5215
5568
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
@@ -5257,13 +5610,446 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
5257
5610
|
// See https://github.com/emscripten-core/emscripten/issues/23697
|
|
5258
5611
|
return 0;
|
|
5259
5612
|
}
|
|
5260
|
-
return -28;
|
|
5261
|
-
} catch (e) {
|
|
5262
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5263
|
-
return -e.errno;
|
|
5613
|
+
return -28;
|
|
5614
|
+
} catch (e) {
|
|
5615
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5616
|
+
return -e.errno;
|
|
5617
|
+
}
|
|
5618
|
+
}
|
|
5619
|
+
|
|
5620
|
+
var locking = {
|
|
5621
|
+
maybeLockedFds: new Set(),
|
|
5622
|
+
F_RDLCK: 0,
|
|
5623
|
+
F_WRLCK: 1,
|
|
5624
|
+
F_UNLCK: 2,
|
|
5625
|
+
lockStateToFcntl: {
|
|
5626
|
+
shared: 0,
|
|
5627
|
+
exclusive: 1,
|
|
5628
|
+
unlocked: 2,
|
|
5629
|
+
},
|
|
5630
|
+
fcntlToLockState: {
|
|
5631
|
+
0: 'shared',
|
|
5632
|
+
1: 'exclusive',
|
|
5633
|
+
2: 'unlocked',
|
|
5634
|
+
},
|
|
5635
|
+
is_shared_fs_node(node) {
|
|
5636
|
+
if (node?.isSharedFS) {
|
|
5637
|
+
return true;
|
|
5638
|
+
}
|
|
5639
|
+
// Handle PROXYFS nodes which wrap other nodes.
|
|
5640
|
+
if (!node?.mount?.opts?.fs?.lookupPath) {
|
|
5641
|
+
return false;
|
|
5642
|
+
}
|
|
5643
|
+
const vfsPath = NODEFS.realPath(node);
|
|
5644
|
+
const underlyingNode = node.mount.opts.fs.lookupPath(vfsPath)?.node;
|
|
5645
|
+
return !!underlyingNode?.isSharedFS;
|
|
5646
|
+
},
|
|
5647
|
+
is_path_to_shared_fs(path) {
|
|
5648
|
+
const { node } = FS.lookupPath(path);
|
|
5649
|
+
return locking.is_shared_fs_node(node);
|
|
5650
|
+
},
|
|
5651
|
+
get_fd_access_mode(fd) {
|
|
5652
|
+
const emscripten_F_GETFL = Number('3');
|
|
5653
|
+
const emscripten_O_ACCMODE = Number('2097155');
|
|
5654
|
+
return (
|
|
5655
|
+
_builtin_fcntl64(fd, emscripten_F_GETFL) & emscripten_O_ACCMODE
|
|
5656
|
+
);
|
|
5657
|
+
},
|
|
5658
|
+
get_vfs_path_from_fd(fd) {
|
|
5659
|
+
try {
|
|
5660
|
+
return [FS.readlink(`/proc/self/fd/${fd}`), 0];
|
|
5661
|
+
} catch (error) {
|
|
5662
|
+
return [null, ERRNO_CODES.EBADF];
|
|
5663
|
+
}
|
|
5664
|
+
},
|
|
5665
|
+
get_native_path_from_vfs_path(vfsPath) {
|
|
5666
|
+
const { node } = FS.lookupPath(vfsPath);
|
|
5667
|
+
return NODEFS.realPath(node);
|
|
5668
|
+
},
|
|
5669
|
+
check_lock_params(fd, l_type) {
|
|
5670
|
+
const emscripten_O_RDONLY = Number('0');
|
|
5671
|
+
const emscripten_O_WRONLY = Number('1');
|
|
5672
|
+
const accessMode = locking.get_fd_access_mode(fd);
|
|
5673
|
+
if (
|
|
5674
|
+
(l_type === locking.F_WRLCK &&
|
|
5675
|
+
accessMode === emscripten_O_RDONLY) ||
|
|
5676
|
+
(l_type === locking.F_RDLCK &&
|
|
5677
|
+
accessMode === emscripten_O_WRONLY)
|
|
5678
|
+
) {
|
|
5679
|
+
return ERRNO_CODES.EBADF;
|
|
5680
|
+
}
|
|
5681
|
+
return 0;
|
|
5682
|
+
},
|
|
5683
|
+
};
|
|
5684
|
+
|
|
5685
|
+
async function ___syscall_fcntl64(fd, cmd, varargs) {
|
|
5686
|
+
// Necessary to use varargs accessor
|
|
5687
|
+
SYSCALLS.varargs = varargs;
|
|
5688
|
+
// These constants are replaced by Emscripten during the build process
|
|
5689
|
+
const emscripten_F_GETLK = Number('12');
|
|
5690
|
+
const emscripten_F_SETLK = Number('13');
|
|
5691
|
+
const emscripten_F_SETLKW = Number('14');
|
|
5692
|
+
const emscripten_SEEK_SET = Number('0');
|
|
5693
|
+
// NOTE: With the exception of l_type, these offsets are not exposed to
|
|
5694
|
+
// JS by Emscripten, so we hardcode them here.
|
|
5695
|
+
const emscripten_flock_l_type_offset = 0;
|
|
5696
|
+
const emscripten_flock_l_whence_offset = 2;
|
|
5697
|
+
const emscripten_flock_l_start_offset = 8;
|
|
5698
|
+
const emscripten_flock_l_len_offset = 16;
|
|
5699
|
+
const emscripten_flock_l_pid_offset = 24;
|
|
5700
|
+
/**
|
|
5701
|
+
* Read the flock struct at the given address.
|
|
5702
|
+
*
|
|
5703
|
+
* @param {bigint} flockStructAddress - the address of the flock struct
|
|
5704
|
+
* @returns the flock struct
|
|
5705
|
+
*/ function read_flock_struct(flockStructAddress) {
|
|
5706
|
+
/*
|
|
5707
|
+
* NOTE: Since we are using HEAP<WORD_SIZE> vars like HEAP16 and HEAP64,
|
|
5708
|
+
* we need to adjust offsets to address the word size of each HEAP.
|
|
5709
|
+
*
|
|
5710
|
+
* For example, an offset of 64 bytes is the following for each HEAP:
|
|
5711
|
+
* - HEAP8: 64 (the 64th byte)
|
|
5712
|
+
* - HEAP16: 32 (the 32nd 16-bit word)
|
|
5713
|
+
* - HEAP32: 16 (the 16th 32-bit word)
|
|
5714
|
+
* - HEAP64: 8 (the 8th 64-bit word)
|
|
5715
|
+
*
|
|
5716
|
+
* We get a word offset by dividing the byte offset by the word size.
|
|
5717
|
+
*/ return {
|
|
5718
|
+
l_type: HEAP16[ // Shift right by 1 to divide by 2^1.
|
|
5719
|
+
(flockStructAddress + emscripten_flock_l_type_offset) >> 1
|
|
5720
|
+
],
|
|
5721
|
+
l_whence:
|
|
5722
|
+
HEAP16[ // Shift right by 1 to divide by 2^1.
|
|
5723
|
+
(flockStructAddress +
|
|
5724
|
+
emscripten_flock_l_whence_offset) >>
|
|
5725
|
+
1
|
|
5726
|
+
],
|
|
5727
|
+
l_start:
|
|
5728
|
+
HEAP64[ // Shift right by 3 to divide by 2^3.
|
|
5729
|
+
(flockStructAddress +
|
|
5730
|
+
emscripten_flock_l_start_offset) >>
|
|
5731
|
+
3
|
|
5732
|
+
],
|
|
5733
|
+
l_len: HEAP64[ // Shift right by 3 to divide by 2^3.
|
|
5734
|
+
(flockStructAddress + emscripten_flock_l_len_offset) >> 3
|
|
5735
|
+
],
|
|
5736
|
+
l_pid: HEAP32[ // Shift right by 2 to divide by 2^2.
|
|
5737
|
+
(flockStructAddress + emscripten_flock_l_pid_offset) >> 2
|
|
5738
|
+
],
|
|
5739
|
+
};
|
|
5740
|
+
}
|
|
5741
|
+
/**
|
|
5742
|
+
* Update the flock struct at the given address with the given fields.
|
|
5743
|
+
*
|
|
5744
|
+
* @param {bigint} flockStructAddress - the address of the flock struct
|
|
5745
|
+
* @param {object} fields - the fields to update
|
|
5746
|
+
*/ function update_flock_struct(flockStructAddress, fields) {
|
|
5747
|
+
/*
|
|
5748
|
+
* NOTE: Since we are using HEAP<WORD_SIZE> vars like HEAP16 and HEAP64,
|
|
5749
|
+
* we need to adjust offsets to address the word size of each HEAP.
|
|
5750
|
+
*
|
|
5751
|
+
* For example, an offset of 64 bytes is the following for each HEAP:
|
|
5752
|
+
* - HEAP8: 64 (the 64th byte)
|
|
5753
|
+
* - HEAP16: 32 (the 32nd 16-bit word)
|
|
5754
|
+
* - HEAP32: 16 (the 16th 32-bit word)
|
|
5755
|
+
* - HEAP64: 8 (the 8th 64-bit word)
|
|
5756
|
+
*
|
|
5757
|
+
* We get a word offset by dividing the byte offset by the word size.
|
|
5758
|
+
*/ if (fields.l_type !== undefined) {
|
|
5759
|
+
HEAP16[ // Shift right by 1 to divide by 2^1.
|
|
5760
|
+
(flockStructAddress + emscripten_flock_l_type_offset) >> 1
|
|
5761
|
+
] = fields.l_type;
|
|
5762
|
+
}
|
|
5763
|
+
if (fields.l_whence !== undefined) {
|
|
5764
|
+
HEAP16[ // Shift right by 1 to divide by 2^1.
|
|
5765
|
+
(flockStructAddress + emscripten_flock_l_whence_offset) >> 1
|
|
5766
|
+
] = fields.l_whence;
|
|
5767
|
+
}
|
|
5768
|
+
if (fields.l_start !== undefined) {
|
|
5769
|
+
HEAP64[ // Shift right by 3 to divide by 2^3.
|
|
5770
|
+
(flockStructAddress + emscripten_flock_l_start_offset) >> 3
|
|
5771
|
+
] = fields.l_start;
|
|
5772
|
+
}
|
|
5773
|
+
if (fields.l_len !== undefined) {
|
|
5774
|
+
HEAP64[ // Shift right by 3 to divide by 2^3.
|
|
5775
|
+
(flockStructAddress + emscripten_flock_l_len_offset) >> 3
|
|
5776
|
+
] = fields.l_len;
|
|
5777
|
+
}
|
|
5778
|
+
if (fields.l_pid !== undefined) {
|
|
5779
|
+
HEAP32[ // Shift right by 2 to divide by 2^2.
|
|
5780
|
+
(flockStructAddress + emscripten_flock_l_pid_offset) >> 2
|
|
5781
|
+
] = fields.l_pid;
|
|
5782
|
+
}
|
|
5783
|
+
}
|
|
5784
|
+
/**
|
|
5785
|
+
* Resolve the base address of the range depending on the whence and start offset.
|
|
5786
|
+
*
|
|
5787
|
+
* @param {number} fd - the file descriptor
|
|
5788
|
+
* @param {number} whence - what the start offset is relative to
|
|
5789
|
+
* @param {bigint} startOffset - the offset from the whence
|
|
5790
|
+
* @returns The resolved offset and the errno. If there is an error,
|
|
5791
|
+
* the resolved offset is null, and the errno is non-zero.
|
|
5792
|
+
*/ function get_base_address(fd, whence, startOffset) {
|
|
5793
|
+
let baseAddress;
|
|
5794
|
+
switch (whence) {
|
|
5795
|
+
case emscripten_SEEK_SET:
|
|
5796
|
+
baseAddress = 0n;
|
|
5797
|
+
break;
|
|
5798
|
+
|
|
5799
|
+
case emscripten_SEEK_CUR:
|
|
5800
|
+
baseAddress = FS.lseek(fd, 0, whence);
|
|
5801
|
+
break;
|
|
5802
|
+
|
|
5803
|
+
case emscripten_SEEK_END:
|
|
5804
|
+
baseAddress = _wasm_get_end_offset(fd);
|
|
5805
|
+
break;
|
|
5806
|
+
|
|
5807
|
+
default:
|
|
5808
|
+
return [null, ERRNO_CODES.EINVAL];
|
|
5809
|
+
}
|
|
5810
|
+
if (baseAddress == -1) {
|
|
5811
|
+
// We cannot resolve the offset within the file.
|
|
5812
|
+
// Let's treat this as a problem with the file descriptor.
|
|
5813
|
+
return [null, ERRNO_CODES.EBADF];
|
|
5814
|
+
}
|
|
5815
|
+
const resolvedOffset = baseAddress + startOffset;
|
|
5816
|
+
if (resolvedOffset < 0) {
|
|
5817
|
+
// This is not a valid offset. Report args as invalid.
|
|
5818
|
+
return [null, ERRNO_CODES.EINVAL];
|
|
5819
|
+
}
|
|
5820
|
+
return [resolvedOffset, 0];
|
|
5821
|
+
}
|
|
5822
|
+
const pid = PHPLoader.processId;
|
|
5823
|
+
switch (cmd) {
|
|
5824
|
+
case emscripten_F_GETLK: {
|
|
5825
|
+
_js_wasm_trace('fcntl(%d, F_GETLK)', fd);
|
|
5826
|
+
let vfsPath;
|
|
5827
|
+
let errno;
|
|
5828
|
+
[vfsPath, errno] = locking.get_vfs_path_from_fd(fd);
|
|
5829
|
+
if (errno !== 0) {
|
|
5830
|
+
_js_wasm_trace(
|
|
5831
|
+
'fcntl(%d, F_GETLK) %s get_vfs_path_from_fd errno %d',
|
|
5832
|
+
fd,
|
|
5833
|
+
vfsPath,
|
|
5834
|
+
errno
|
|
5835
|
+
);
|
|
5836
|
+
return -ERRNO_CODES.EBADF;
|
|
5837
|
+
}
|
|
5838
|
+
if (!locking.is_path_to_shared_fs(vfsPath)) {
|
|
5839
|
+
_js_wasm_trace(
|
|
5840
|
+
"fcntl(%d, F_GETLK) locking is not implemented for non-NodeFS path '%s'",
|
|
5841
|
+
fd,
|
|
5842
|
+
vfsPath
|
|
5843
|
+
);
|
|
5844
|
+
// If not a NodeFS path, we can't lock it.
|
|
5845
|
+
// Default to succeeding as Emscripten does.
|
|
5846
|
+
update_flock_struct(flockStructAddr, {
|
|
5847
|
+
l_type: F_UNLCK,
|
|
5848
|
+
});
|
|
5849
|
+
return 0;
|
|
5850
|
+
}
|
|
5851
|
+
const flockStructAddr = syscallGetVarargP();
|
|
5852
|
+
const flockStruct = read_flock_struct(flockStructAddr);
|
|
5853
|
+
if (!(flockStruct.l_type in locking.fcntlToLockState)) {
|
|
5854
|
+
return -ERRNO_CODES.EINVAL;
|
|
5855
|
+
}
|
|
5856
|
+
errno = locking.check_lock_params(fd, flockStruct.l_type);
|
|
5857
|
+
if (errno !== 0) {
|
|
5858
|
+
_js_wasm_trace(
|
|
5859
|
+
'fcntl(%d, F_GETLK) %s check_lock_params errno %d',
|
|
5860
|
+
fd,
|
|
5861
|
+
vfsPath,
|
|
5862
|
+
errno
|
|
5863
|
+
);
|
|
5864
|
+
return -ERRNO_CODES.EINVAL;
|
|
5865
|
+
}
|
|
5866
|
+
const requestedLockType =
|
|
5867
|
+
locking.fcntlToLockState[flockStruct.l_type];
|
|
5868
|
+
let absoluteStartOffset;
|
|
5869
|
+
[absoluteStartOffset, errno] = get_base_address(
|
|
5870
|
+
fd,
|
|
5871
|
+
flockStruct.l_whence,
|
|
5872
|
+
flockStruct.l_start
|
|
5873
|
+
);
|
|
5874
|
+
if (errno !== 0) {
|
|
5875
|
+
_js_wasm_trace(
|
|
5876
|
+
'fcntl(%d, F_GETLK) %s get_base_address errno %d',
|
|
5877
|
+
fd,
|
|
5878
|
+
vfsPath,
|
|
5879
|
+
errno
|
|
5880
|
+
);
|
|
5881
|
+
return -ERRNO_CODES.EINVAL;
|
|
5882
|
+
}
|
|
5883
|
+
const nativeFilePath =
|
|
5884
|
+
locking.get_native_path_from_vfs_path(vfsPath);
|
|
5885
|
+
return PHPLoader.fileLockManager
|
|
5886
|
+
.findFirstConflictingByteRangeLock(nativeFilePath, {
|
|
5887
|
+
type: requestedLockType,
|
|
5888
|
+
start: absoluteStartOffset,
|
|
5889
|
+
end: absoluteStartOffset + flockStruct.l_len,
|
|
5890
|
+
pid,
|
|
5891
|
+
})
|
|
5892
|
+
.then((conflictingLock) => {
|
|
5893
|
+
if (conflictingLock === undefined) {
|
|
5894
|
+
_js_wasm_trace(
|
|
5895
|
+
'fcntl(%d, F_GETLK) %s findFirstConflictingByteRangeLock type=unlocked start=0x%x end=0x%x',
|
|
5896
|
+
fd,
|
|
5897
|
+
vfsPath,
|
|
5898
|
+
absoluteStartOffset,
|
|
5899
|
+
absoluteStartOffset + flockStruct.l_len
|
|
5900
|
+
);
|
|
5901
|
+
update_flock_struct(flockStructAddr, {
|
|
5902
|
+
l_type: F_UNLCK,
|
|
5903
|
+
});
|
|
5904
|
+
return 0;
|
|
5905
|
+
}
|
|
5906
|
+
_js_wasm_trace(
|
|
5907
|
+
'fcntl(%d, F_GETLK) %s findFirstConflictingByteRangeLock type=%s start=0x%x end=0x%x conflictingLock %d',
|
|
5908
|
+
fd,
|
|
5909
|
+
vfsPath,
|
|
5910
|
+
conflictingLock.type,
|
|
5911
|
+
conflictingLock.start,
|
|
5912
|
+
conflictingLock.end,
|
|
5913
|
+
conflictingLock.pid
|
|
5914
|
+
);
|
|
5915
|
+
const fcntlLockState =
|
|
5916
|
+
locking.lockStateToFcntl[conflictingLock.type];
|
|
5917
|
+
update_flock_struct(flockStructAddr, {
|
|
5918
|
+
l_type: fcntlLockState,
|
|
5919
|
+
l_whence: emscripten_SEEK_SET,
|
|
5920
|
+
l_start: conflictingLock.start,
|
|
5921
|
+
l_len: conflictingLock.end - conflictingLock.start,
|
|
5922
|
+
l_pid: conflictingLock.pid,
|
|
5923
|
+
});
|
|
5924
|
+
return 0;
|
|
5925
|
+
})
|
|
5926
|
+
.catch((e) => {
|
|
5927
|
+
_js_wasm_trace(
|
|
5928
|
+
'fcntl(%d, F_GETLK) %s findFirstConflictingByteRangeLock error %s',
|
|
5929
|
+
fd,
|
|
5930
|
+
vfsPath,
|
|
5931
|
+
e
|
|
5932
|
+
);
|
|
5933
|
+
return -ERRNO_CODES.EINVAL;
|
|
5934
|
+
});
|
|
5935
|
+
}
|
|
5936
|
+
|
|
5937
|
+
case emscripten_F_SETLK: {
|
|
5938
|
+
_js_wasm_trace('fcntl(%d, F_SETLK)', fd);
|
|
5939
|
+
let vfsPath;
|
|
5940
|
+
let errno;
|
|
5941
|
+
[vfsPath, errno] = locking.get_vfs_path_from_fd(fd);
|
|
5942
|
+
if (errno !== 0) {
|
|
5943
|
+
_js_wasm_trace(
|
|
5944
|
+
'fcntl(%d, F_SETLK) %s get_vfs_path_from_fd errno %d',
|
|
5945
|
+
fd,
|
|
5946
|
+
vfsPath,
|
|
5947
|
+
errno
|
|
5948
|
+
);
|
|
5949
|
+
return -errno;
|
|
5950
|
+
}
|
|
5951
|
+
if (!locking.is_path_to_shared_fs(vfsPath)) {
|
|
5952
|
+
_js_wasm_trace(
|
|
5953
|
+
'fcntl(%d, F_SETLK) locking is not implemented for non-NodeFS path %s',
|
|
5954
|
+
fd,
|
|
5955
|
+
vfsPath
|
|
5956
|
+
);
|
|
5957
|
+
// If not a NodeFS path, we can't lock it.
|
|
5958
|
+
// Default to succeeding as Emscripten does.
|
|
5959
|
+
return 0;
|
|
5960
|
+
}
|
|
5961
|
+
var flockStructAddr = syscallGetVarargP();
|
|
5962
|
+
const flockStruct = read_flock_struct(flockStructAddr);
|
|
5963
|
+
let absoluteStartOffset;
|
|
5964
|
+
[absoluteStartOffset, errno] = get_base_address(
|
|
5965
|
+
fd,
|
|
5966
|
+
flockStruct.l_whence,
|
|
5967
|
+
flockStruct.l_start
|
|
5968
|
+
);
|
|
5969
|
+
if (errno !== 0) {
|
|
5970
|
+
_js_wasm_trace(
|
|
5971
|
+
'fcntl(%d, F_SETLK) %s get_base_address errno %d',
|
|
5972
|
+
fd,
|
|
5973
|
+
vfsPath,
|
|
5974
|
+
errno
|
|
5975
|
+
);
|
|
5976
|
+
return -errno;
|
|
5977
|
+
}
|
|
5978
|
+
if (!(flockStruct.l_type in locking.fcntlToLockState)) {
|
|
5979
|
+
_js_wasm_trace(
|
|
5980
|
+
'fcntl(%d, F_SETLK) %s invalid lock type %d',
|
|
5981
|
+
fd,
|
|
5982
|
+
vfsPath,
|
|
5983
|
+
flockStruct.l_type
|
|
5984
|
+
);
|
|
5985
|
+
return -ERRNO_CODES.EINVAL;
|
|
5986
|
+
}
|
|
5987
|
+
errno = locking.check_lock_params(fd, flockStruct.l_type);
|
|
5988
|
+
if (errno !== 0) {
|
|
5989
|
+
_js_wasm_trace(
|
|
5990
|
+
'fcntl(%d, F_SETLK) %s check_lock_params errno %d',
|
|
5991
|
+
fd,
|
|
5992
|
+
vfsPath,
|
|
5993
|
+
errno
|
|
5994
|
+
);
|
|
5995
|
+
return -errno;
|
|
5996
|
+
}
|
|
5997
|
+
locking.maybeLockedFds.add(fd);
|
|
5998
|
+
const requestedLockType =
|
|
5999
|
+
locking.fcntlToLockState[flockStruct.l_type];
|
|
6000
|
+
const rangeLock = {
|
|
6001
|
+
type: requestedLockType,
|
|
6002
|
+
start: absoluteStartOffset,
|
|
6003
|
+
end: absoluteStartOffset + flockStruct.l_len,
|
|
6004
|
+
pid,
|
|
6005
|
+
};
|
|
6006
|
+
const nativeFilePath =
|
|
6007
|
+
locking.get_native_path_from_vfs_path(vfsPath);
|
|
6008
|
+
_js_wasm_trace(
|
|
6009
|
+
'fcntl(%d, F_SETLK) %s calling lockFileByteRange for range lock %s',
|
|
6010
|
+
fd,
|
|
6011
|
+
vfsPath,
|
|
6012
|
+
rangeLock
|
|
6013
|
+
);
|
|
6014
|
+
return PHPLoader.fileLockManager
|
|
6015
|
+
.lockFileByteRange(nativeFilePath, rangeLock)
|
|
6016
|
+
.then((succeeded) => {
|
|
6017
|
+
_js_wasm_trace(
|
|
6018
|
+
'fcntl(%d, F_SETLK) %s lockFileByteRange returned %d for range lock %s',
|
|
6019
|
+
fd,
|
|
6020
|
+
vfsPath,
|
|
6021
|
+
succeeded,
|
|
6022
|
+
rangeLock
|
|
6023
|
+
);
|
|
6024
|
+
return succeeded ? 0 : -ERRNO_CODES.EAGAIN;
|
|
6025
|
+
})
|
|
6026
|
+
.catch((e) => {
|
|
6027
|
+
_js_wasm_trace(
|
|
6028
|
+
'fcntl(%d, F_SETLK) %s lockFileByteRange error %s for range lock %s',
|
|
6029
|
+
fd,
|
|
6030
|
+
vfsPath,
|
|
6031
|
+
e,
|
|
6032
|
+
rangeLock
|
|
6033
|
+
);
|
|
6034
|
+
return -ERRNO_CODES.EINVAL;
|
|
6035
|
+
});
|
|
6036
|
+
}
|
|
6037
|
+
|
|
6038
|
+
// @TODO: Implement waiting for lock
|
|
6039
|
+
case emscripten_F_SETLKW: {
|
|
6040
|
+
// We do not yet support the blocking form of flock().
|
|
6041
|
+
// We respond with EDEADLK to indicate failure
|
|
6042
|
+
// because it is a known errno for a failed F_SETLKW command.
|
|
6043
|
+
return -ERRNO_CODES.EDEADLK;
|
|
6044
|
+
}
|
|
6045
|
+
|
|
6046
|
+
default:
|
|
6047
|
+
return _builtin_fcntl64(fd, cmd, varargs);
|
|
5264
6048
|
}
|
|
5265
6049
|
}
|
|
5266
6050
|
|
|
6051
|
+
___syscall_fcntl64.isAsync = true;
|
|
6052
|
+
|
|
5267
6053
|
function ___syscall_fdatasync(fd) {
|
|
5268
6054
|
try {
|
|
5269
6055
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
@@ -5295,11 +6081,6 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
5295
6081
|
}
|
|
5296
6082
|
}
|
|
5297
6083
|
|
|
5298
|
-
var stringToUTF8 = (str, outPtr, maxBytesToWrite) =>
|
|
5299
|
-
stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);
|
|
5300
|
-
|
|
5301
|
-
Module['stringToUTF8'] = stringToUTF8;
|
|
5302
|
-
|
|
5303
6084
|
function ___syscall_getcwd(buf, size) {
|
|
5304
6085
|
try {
|
|
5305
6086
|
if (size === 0) return -28;
|
|
@@ -5818,408 +6599,28 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
5818
6599
|
},
|
|
5819
6600
|
close(stream) {
|
|
5820
6601
|
var pipe = stream.node.pipe;
|
|
5821
|
-
pipe.refcnt--;
|
|
5822
|
-
if (pipe.refcnt === 0) {
|
|
5823
|
-
pipe.buckets = null;
|
|
5824
|
-
}
|
|
5825
|
-
},
|
|
5826
|
-
},
|
|
5827
|
-
nextname() {
|
|
5828
|
-
if (!PIPEFS.nextname.current) {
|
|
5829
|
-
PIPEFS.nextname.current = 0;
|
|
5830
|
-
}
|
|
5831
|
-
return 'pipe[' + PIPEFS.nextname.current++ + ']';
|
|
5832
|
-
},
|
|
5833
|
-
};
|
|
5834
|
-
|
|
5835
|
-
function ___syscall_pipe(fdPtr) {
|
|
5836
|
-
try {
|
|
5837
|
-
if (fdPtr == 0) {
|
|
5838
|
-
throw new FS.ErrnoError(21);
|
|
5839
|
-
}
|
|
5840
|
-
var res = PIPEFS.createPipe();
|
|
5841
|
-
HEAP32[fdPtr >> 2] = res.readable_fd;
|
|
5842
|
-
HEAP32[(fdPtr + 4) >> 2] = res.writable_fd;
|
|
5843
|
-
return 0;
|
|
5844
|
-
} catch (e) {
|
|
5845
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5846
|
-
return -e.errno;
|
|
5847
|
-
}
|
|
5848
|
-
}
|
|
5849
|
-
|
|
5850
|
-
function ___syscall_poll(fds, nfds, timeout) {
|
|
5851
|
-
try {
|
|
5852
|
-
var nonzero = 0;
|
|
5853
|
-
for (var i = 0; i < nfds; i++) {
|
|
5854
|
-
var pollfd = fds + 8 * i;
|
|
5855
|
-
var fd = HEAP32[pollfd >> 2];
|
|
5856
|
-
var events = HEAP16[(pollfd + 4) >> 1];
|
|
5857
|
-
var mask = 32;
|
|
5858
|
-
var stream = FS.getStream(fd);
|
|
5859
|
-
if (stream) {
|
|
5860
|
-
mask = SYSCALLS.DEFAULT_POLLMASK;
|
|
5861
|
-
if (stream.stream_ops?.poll) {
|
|
5862
|
-
mask = stream.stream_ops.poll(stream, -1);
|
|
5863
|
-
}
|
|
5864
|
-
}
|
|
5865
|
-
mask &= events | 8 | 16;
|
|
5866
|
-
if (mask) nonzero++;
|
|
5867
|
-
HEAP16[(pollfd + 6) >> 1] = mask;
|
|
5868
|
-
}
|
|
5869
|
-
return nonzero;
|
|
5870
|
-
} catch (e) {
|
|
5871
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5872
|
-
return -e.errno;
|
|
5873
|
-
}
|
|
5874
|
-
}
|
|
5875
|
-
|
|
5876
|
-
function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
|
|
5877
|
-
try {
|
|
5878
|
-
path = SYSCALLS.getStr(path);
|
|
5879
|
-
path = SYSCALLS.calculateAt(dirfd, path);
|
|
5880
|
-
if (bufsize <= 0) return -28;
|
|
5881
|
-
var ret = FS.readlink(path);
|
|
5882
|
-
var len = Math.min(bufsize, lengthBytesUTF8(ret));
|
|
5883
|
-
var endChar = HEAP8[buf + len];
|
|
5884
|
-
stringToUTF8(ret, buf, bufsize + 1);
|
|
5885
|
-
// readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)
|
|
5886
|
-
// stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.
|
|
5887
|
-
HEAP8[buf + len] = endChar;
|
|
5888
|
-
return len;
|
|
5889
|
-
} catch (e) {
|
|
5890
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5891
|
-
return -e.errno;
|
|
5892
|
-
}
|
|
5893
|
-
}
|
|
5894
|
-
|
|
5895
|
-
function ___syscall_recvfrom(fd, buf, len, flags, addr, addrlen) {
|
|
5896
|
-
try {
|
|
5897
|
-
var sock = getSocketFromFD(fd);
|
|
5898
|
-
var msg = sock.sock_ops.recvmsg(
|
|
5899
|
-
sock,
|
|
5900
|
-
len,
|
|
5901
|
-
typeof flags !== 'undefined' ? flags : 0
|
|
5902
|
-
);
|
|
5903
|
-
if (!msg) return 0;
|
|
5904
|
-
// socket is closed
|
|
5905
|
-
if (addr) {
|
|
5906
|
-
var errno = writeSockaddr(
|
|
5907
|
-
addr,
|
|
5908
|
-
sock.family,
|
|
5909
|
-
DNS.lookup_name(msg.addr),
|
|
5910
|
-
msg.port,
|
|
5911
|
-
addrlen
|
|
5912
|
-
);
|
|
5913
|
-
}
|
|
5914
|
-
HEAPU8.set(msg.buffer, buf);
|
|
5915
|
-
return msg.buffer.byteLength;
|
|
5916
|
-
} catch (e) {
|
|
5917
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5918
|
-
return -e.errno;
|
|
5919
|
-
}
|
|
5920
|
-
}
|
|
5921
|
-
|
|
5922
|
-
function ___syscall_renameat(olddirfd, oldpath, newdirfd, newpath) {
|
|
5923
|
-
try {
|
|
5924
|
-
oldpath = SYSCALLS.getStr(oldpath);
|
|
5925
|
-
newpath = SYSCALLS.getStr(newpath);
|
|
5926
|
-
oldpath = SYSCALLS.calculateAt(olddirfd, oldpath);
|
|
5927
|
-
newpath = SYSCALLS.calculateAt(newdirfd, newpath);
|
|
5928
|
-
FS.rename(oldpath, newpath);
|
|
5929
|
-
return 0;
|
|
5930
|
-
} catch (e) {
|
|
5931
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5932
|
-
return -e.errno;
|
|
5933
|
-
}
|
|
5934
|
-
}
|
|
5935
|
-
|
|
5936
|
-
function ___syscall_rmdir(path) {
|
|
5937
|
-
try {
|
|
5938
|
-
path = SYSCALLS.getStr(path);
|
|
5939
|
-
FS.rmdir(path);
|
|
5940
|
-
return 0;
|
|
5941
|
-
} catch (e) {
|
|
5942
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5943
|
-
return -e.errno;
|
|
5944
|
-
}
|
|
5945
|
-
}
|
|
5946
|
-
|
|
5947
|
-
function ___syscall_sendto(fd, message, length, flags, addr, addr_len) {
|
|
5948
|
-
try {
|
|
5949
|
-
var sock = getSocketFromFD(fd);
|
|
5950
|
-
if (!addr) {
|
|
5951
|
-
// send, no address provided
|
|
5952
|
-
return FS.write(sock.stream, HEAP8, message, length);
|
|
5953
|
-
}
|
|
5954
|
-
var dest = getSocketAddress(addr, addr_len);
|
|
5955
|
-
// sendto an address
|
|
5956
|
-
return sock.sock_ops.sendmsg(
|
|
5957
|
-
sock,
|
|
5958
|
-
HEAP8,
|
|
5959
|
-
message,
|
|
5960
|
-
length,
|
|
5961
|
-
dest.addr,
|
|
5962
|
-
dest.port
|
|
5963
|
-
);
|
|
5964
|
-
} catch (e) {
|
|
5965
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5966
|
-
return -e.errno;
|
|
5967
|
-
}
|
|
5968
|
-
}
|
|
5969
|
-
|
|
5970
|
-
function ___syscall_socket(domain, type, protocol) {
|
|
5971
|
-
try {
|
|
5972
|
-
var sock = SOCKFS.createSocket(domain, type, protocol);
|
|
5973
|
-
return sock.stream.fd;
|
|
5974
|
-
} catch (e) {
|
|
5975
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5976
|
-
return -e.errno;
|
|
5977
|
-
}
|
|
5978
|
-
}
|
|
5979
|
-
|
|
5980
|
-
function ___syscall_stat64(path, buf) {
|
|
5981
|
-
try {
|
|
5982
|
-
path = SYSCALLS.getStr(path);
|
|
5983
|
-
return SYSCALLS.writeStat(buf, FS.stat(path));
|
|
5984
|
-
} catch (e) {
|
|
5985
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5986
|
-
return -e.errno;
|
|
5987
|
-
}
|
|
5988
|
-
}
|
|
5989
|
-
|
|
5990
|
-
function ___syscall_statfs64(path, size, buf) {
|
|
5991
|
-
try {
|
|
5992
|
-
SYSCALLS.writeStatFs(buf, FS.statfs(SYSCALLS.getStr(path)));
|
|
5993
|
-
return 0;
|
|
5994
|
-
} catch (e) {
|
|
5995
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
5996
|
-
return -e.errno;
|
|
5997
|
-
}
|
|
5998
|
-
}
|
|
5999
|
-
|
|
6000
|
-
function ___syscall_symlinkat(target, dirfd, linkpath) {
|
|
6001
|
-
try {
|
|
6002
|
-
target = SYSCALLS.getStr(target);
|
|
6003
|
-
linkpath = SYSCALLS.getStr(linkpath);
|
|
6004
|
-
linkpath = SYSCALLS.calculateAt(dirfd, linkpath);
|
|
6005
|
-
FS.symlink(target, linkpath);
|
|
6006
|
-
return 0;
|
|
6007
|
-
} catch (e) {
|
|
6008
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6009
|
-
return -e.errno;
|
|
6010
|
-
}
|
|
6011
|
-
}
|
|
6012
|
-
|
|
6013
|
-
function ___syscall_unlinkat(dirfd, path, flags) {
|
|
6014
|
-
try {
|
|
6015
|
-
path = SYSCALLS.getStr(path);
|
|
6016
|
-
path = SYSCALLS.calculateAt(dirfd, path);
|
|
6017
|
-
if (flags === 0) {
|
|
6018
|
-
FS.unlink(path);
|
|
6019
|
-
} else if (flags === 512) {
|
|
6020
|
-
FS.rmdir(path);
|
|
6021
|
-
} else {
|
|
6022
|
-
abort('Invalid flags passed to unlinkat');
|
|
6023
|
-
}
|
|
6024
|
-
return 0;
|
|
6025
|
-
} catch (e) {
|
|
6026
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6027
|
-
return -e.errno;
|
|
6028
|
-
}
|
|
6029
|
-
}
|
|
6030
|
-
|
|
6031
|
-
var readI53FromI64 = (ptr) =>
|
|
6032
|
-
HEAPU32[ptr >> 2] + HEAP32[(ptr + 4) >> 2] * 4294967296;
|
|
6033
|
-
|
|
6034
|
-
function ___syscall_utimensat(dirfd, path, times, flags) {
|
|
6035
|
-
try {
|
|
6036
|
-
path = SYSCALLS.getStr(path);
|
|
6037
|
-
path = SYSCALLS.calculateAt(dirfd, path, true);
|
|
6038
|
-
var now = Date.now(),
|
|
6039
|
-
atime,
|
|
6040
|
-
mtime;
|
|
6041
|
-
if (!times) {
|
|
6042
|
-
atime = now;
|
|
6043
|
-
mtime = now;
|
|
6044
|
-
} else {
|
|
6045
|
-
var seconds = readI53FromI64(times);
|
|
6046
|
-
var nanoseconds = HEAP32[(times + 8) >> 2];
|
|
6047
|
-
if (nanoseconds == 1073741823) {
|
|
6048
|
-
atime = now;
|
|
6049
|
-
} else if (nanoseconds == 1073741822) {
|
|
6050
|
-
atime = null;
|
|
6051
|
-
} else {
|
|
6052
|
-
atime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
|
|
6053
|
-
}
|
|
6054
|
-
times += 16;
|
|
6055
|
-
seconds = readI53FromI64(times);
|
|
6056
|
-
nanoseconds = HEAP32[(times + 8) >> 2];
|
|
6057
|
-
if (nanoseconds == 1073741823) {
|
|
6058
|
-
mtime = now;
|
|
6059
|
-
} else if (nanoseconds == 1073741822) {
|
|
6060
|
-
mtime = null;
|
|
6061
|
-
} else {
|
|
6062
|
-
mtime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
|
|
6602
|
+
pipe.refcnt--;
|
|
6603
|
+
if (pipe.refcnt === 0) {
|
|
6604
|
+
pipe.buckets = null;
|
|
6063
6605
|
}
|
|
6606
|
+
},
|
|
6607
|
+
},
|
|
6608
|
+
nextname() {
|
|
6609
|
+
if (!PIPEFS.nextname.current) {
|
|
6610
|
+
PIPEFS.nextname.current = 0;
|
|
6064
6611
|
}
|
|
6065
|
-
|
|
6066
|
-
|
|
6067
|
-
if ((mtime ?? atime) !== null) {
|
|
6068
|
-
FS.utime(path, atime, mtime);
|
|
6069
|
-
}
|
|
6070
|
-
return 0;
|
|
6071
|
-
} catch (e) {
|
|
6072
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6073
|
-
return -e.errno;
|
|
6074
|
-
}
|
|
6075
|
-
}
|
|
6076
|
-
|
|
6077
|
-
var __abort_js = () => abort('');
|
|
6078
|
-
|
|
6079
|
-
var __emscripten_lookup_name = (name) => {
|
|
6080
|
-
// uint32_t _emscripten_lookup_name(const char *name);
|
|
6081
|
-
var nameString = UTF8ToString(name);
|
|
6082
|
-
return inetPton4(DNS.lookup_name(nameString));
|
|
6083
|
-
};
|
|
6084
|
-
|
|
6085
|
-
var runtimeKeepaliveCounter = 0;
|
|
6086
|
-
|
|
6087
|
-
var __emscripten_runtime_keepalive_clear = () => {
|
|
6088
|
-
noExitRuntime = false;
|
|
6089
|
-
runtimeKeepaliveCounter = 0;
|
|
6090
|
-
};
|
|
6091
|
-
|
|
6092
|
-
function __gmtime_js(time, tmPtr) {
|
|
6093
|
-
time = bigintToI53Checked(time);
|
|
6094
|
-
var date = new Date(time * 1e3);
|
|
6095
|
-
HEAP32[tmPtr >> 2] = date.getUTCSeconds();
|
|
6096
|
-
HEAP32[(tmPtr + 4) >> 2] = date.getUTCMinutes();
|
|
6097
|
-
HEAP32[(tmPtr + 8) >> 2] = date.getUTCHours();
|
|
6098
|
-
HEAP32[(tmPtr + 12) >> 2] = date.getUTCDate();
|
|
6099
|
-
HEAP32[(tmPtr + 16) >> 2] = date.getUTCMonth();
|
|
6100
|
-
HEAP32[(tmPtr + 20) >> 2] = date.getUTCFullYear() - 1900;
|
|
6101
|
-
HEAP32[(tmPtr + 24) >> 2] = date.getUTCDay();
|
|
6102
|
-
var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
|
|
6103
|
-
var yday = ((date.getTime() - start) / (1e3 * 60 * 60 * 24)) | 0;
|
|
6104
|
-
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
6105
|
-
}
|
|
6106
|
-
|
|
6107
|
-
var isLeapYear = (year) =>
|
|
6108
|
-
year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
6109
|
-
|
|
6110
|
-
var MONTH_DAYS_LEAP_CUMULATIVE = [
|
|
6111
|
-
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
|
|
6112
|
-
];
|
|
6113
|
-
|
|
6114
|
-
var MONTH_DAYS_REGULAR_CUMULATIVE = [
|
|
6115
|
-
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
|
|
6116
|
-
];
|
|
6117
|
-
|
|
6118
|
-
var ydayFromDate = (date) => {
|
|
6119
|
-
var leap = isLeapYear(date.getFullYear());
|
|
6120
|
-
var monthDaysCumulative = leap
|
|
6121
|
-
? MONTH_DAYS_LEAP_CUMULATIVE
|
|
6122
|
-
: MONTH_DAYS_REGULAR_CUMULATIVE;
|
|
6123
|
-
var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1;
|
|
6124
|
-
// -1 since it's days since Jan 1
|
|
6125
|
-
return yday;
|
|
6126
|
-
};
|
|
6127
|
-
|
|
6128
|
-
function __localtime_js(time, tmPtr) {
|
|
6129
|
-
time = bigintToI53Checked(time);
|
|
6130
|
-
var date = new Date(time * 1e3);
|
|
6131
|
-
HEAP32[tmPtr >> 2] = date.getSeconds();
|
|
6132
|
-
HEAP32[(tmPtr + 4) >> 2] = date.getMinutes();
|
|
6133
|
-
HEAP32[(tmPtr + 8) >> 2] = date.getHours();
|
|
6134
|
-
HEAP32[(tmPtr + 12) >> 2] = date.getDate();
|
|
6135
|
-
HEAP32[(tmPtr + 16) >> 2] = date.getMonth();
|
|
6136
|
-
HEAP32[(tmPtr + 20) >> 2] = date.getFullYear() - 1900;
|
|
6137
|
-
HEAP32[(tmPtr + 24) >> 2] = date.getDay();
|
|
6138
|
-
var yday = ydayFromDate(date) | 0;
|
|
6139
|
-
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
6140
|
-
HEAP32[(tmPtr + 36) >> 2] = -(date.getTimezoneOffset() * 60);
|
|
6141
|
-
// Attention: DST is in December in South, and some regions don't have DST at all.
|
|
6142
|
-
var start = new Date(date.getFullYear(), 0, 1);
|
|
6143
|
-
var summerOffset = new Date(
|
|
6144
|
-
date.getFullYear(),
|
|
6145
|
-
6,
|
|
6146
|
-
1
|
|
6147
|
-
).getTimezoneOffset();
|
|
6148
|
-
var winterOffset = start.getTimezoneOffset();
|
|
6149
|
-
var dst =
|
|
6150
|
-
(summerOffset != winterOffset &&
|
|
6151
|
-
date.getTimezoneOffset() ==
|
|
6152
|
-
Math.min(winterOffset, summerOffset)) | 0;
|
|
6153
|
-
HEAP32[(tmPtr + 32) >> 2] = dst;
|
|
6154
|
-
}
|
|
6155
|
-
|
|
6156
|
-
var __mktime_js = function (tmPtr) {
|
|
6157
|
-
var ret = (() => {
|
|
6158
|
-
var date = new Date(
|
|
6159
|
-
HEAP32[(tmPtr + 20) >> 2] + 1900,
|
|
6160
|
-
HEAP32[(tmPtr + 16) >> 2],
|
|
6161
|
-
HEAP32[(tmPtr + 12) >> 2],
|
|
6162
|
-
HEAP32[(tmPtr + 8) >> 2],
|
|
6163
|
-
HEAP32[(tmPtr + 4) >> 2],
|
|
6164
|
-
HEAP32[tmPtr >> 2],
|
|
6165
|
-
0
|
|
6166
|
-
);
|
|
6167
|
-
// There's an ambiguous hour when the time goes back; the tm_isdst field is
|
|
6168
|
-
// used to disambiguate it. Date() basically guesses, so we fix it up if it
|
|
6169
|
-
// guessed wrong, or fill in tm_isdst with the guess if it's -1.
|
|
6170
|
-
var dst = HEAP32[(tmPtr + 32) >> 2];
|
|
6171
|
-
var guessedOffset = date.getTimezoneOffset();
|
|
6172
|
-
var start = new Date(date.getFullYear(), 0, 1);
|
|
6173
|
-
var summerOffset = new Date(
|
|
6174
|
-
date.getFullYear(),
|
|
6175
|
-
6,
|
|
6176
|
-
1
|
|
6177
|
-
).getTimezoneOffset();
|
|
6178
|
-
var winterOffset = start.getTimezoneOffset();
|
|
6179
|
-
var dstOffset = Math.min(winterOffset, summerOffset);
|
|
6180
|
-
// DST is in December in South
|
|
6181
|
-
if (dst < 0) {
|
|
6182
|
-
// Attention: some regions don't have DST at all.
|
|
6183
|
-
HEAP32[(tmPtr + 32) >> 2] = Number(
|
|
6184
|
-
summerOffset != winterOffset && dstOffset == guessedOffset
|
|
6185
|
-
);
|
|
6186
|
-
} else if (dst > 0 != (dstOffset == guessedOffset)) {
|
|
6187
|
-
var nonDstOffset = Math.max(winterOffset, summerOffset);
|
|
6188
|
-
var trueOffset = dst > 0 ? dstOffset : nonDstOffset;
|
|
6189
|
-
// Don't try setMinutes(date.getMinutes() + ...) -- it's messed up.
|
|
6190
|
-
date.setTime(
|
|
6191
|
-
date.getTime() + (trueOffset - guessedOffset) * 6e4
|
|
6192
|
-
);
|
|
6193
|
-
}
|
|
6194
|
-
HEAP32[(tmPtr + 24) >> 2] = date.getDay();
|
|
6195
|
-
var yday = ydayFromDate(date) | 0;
|
|
6196
|
-
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
6197
|
-
// To match expected behavior, update fields from date
|
|
6198
|
-
HEAP32[tmPtr >> 2] = date.getSeconds();
|
|
6199
|
-
HEAP32[(tmPtr + 4) >> 2] = date.getMinutes();
|
|
6200
|
-
HEAP32[(tmPtr + 8) >> 2] = date.getHours();
|
|
6201
|
-
HEAP32[(tmPtr + 12) >> 2] = date.getDate();
|
|
6202
|
-
HEAP32[(tmPtr + 16) >> 2] = date.getMonth();
|
|
6203
|
-
HEAP32[(tmPtr + 20) >> 2] = date.getYear();
|
|
6204
|
-
var timeMs = date.getTime();
|
|
6205
|
-
if (isNaN(timeMs)) {
|
|
6206
|
-
return -1;
|
|
6207
|
-
}
|
|
6208
|
-
// Return time in microseconds
|
|
6209
|
-
return timeMs / 1e3;
|
|
6210
|
-
})();
|
|
6211
|
-
return BigInt(ret);
|
|
6612
|
+
return 'pipe[' + PIPEFS.nextname.current++ + ']';
|
|
6613
|
+
},
|
|
6212
6614
|
};
|
|
6213
6615
|
|
|
6214
|
-
function
|
|
6215
|
-
offset = bigintToI53Checked(offset);
|
|
6616
|
+
function ___syscall_pipe(fdPtr) {
|
|
6216
6617
|
try {
|
|
6217
|
-
if (
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
var
|
|
6221
|
-
HEAP32[
|
|
6222
|
-
|
|
6618
|
+
if (fdPtr == 0) {
|
|
6619
|
+
throw new FS.ErrnoError(21);
|
|
6620
|
+
}
|
|
6621
|
+
var res = PIPEFS.createPipe();
|
|
6622
|
+
HEAP32[fdPtr >> 2] = res.readable_fd;
|
|
6623
|
+
HEAP32[(fdPtr + 4) >> 2] = res.writable_fd;
|
|
6223
6624
|
return 0;
|
|
6224
6625
|
} catch (e) {
|
|
6225
6626
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
@@ -6227,991 +6628,1073 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
6227
6628
|
}
|
|
6228
6629
|
}
|
|
6229
6630
|
|
|
6230
|
-
function
|
|
6231
|
-
offset = bigintToI53Checked(offset);
|
|
6631
|
+
function ___syscall_poll(fds, nfds, timeout) {
|
|
6232
6632
|
try {
|
|
6233
|
-
var
|
|
6234
|
-
|
|
6235
|
-
|
|
6633
|
+
var nonzero = 0;
|
|
6634
|
+
for (var i = 0; i < nfds; i++) {
|
|
6635
|
+
var pollfd = fds + 8 * i;
|
|
6636
|
+
var fd = HEAP32[pollfd >> 2];
|
|
6637
|
+
var events = HEAP16[(pollfd + 4) >> 1];
|
|
6638
|
+
var mask = 32;
|
|
6639
|
+
var stream = FS.getStream(fd);
|
|
6640
|
+
if (stream) {
|
|
6641
|
+
mask = SYSCALLS.DEFAULT_POLLMASK;
|
|
6642
|
+
if (stream.stream_ops?.poll) {
|
|
6643
|
+
mask = stream.stream_ops.poll(stream, -1);
|
|
6644
|
+
}
|
|
6645
|
+
}
|
|
6646
|
+
mask &= events | 8 | 16;
|
|
6647
|
+
if (mask) nonzero++;
|
|
6648
|
+
HEAP16[(pollfd + 6) >> 1] = mask;
|
|
6236
6649
|
}
|
|
6650
|
+
return nonzero;
|
|
6237
6651
|
} catch (e) {
|
|
6238
6652
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6239
6653
|
return -e.errno;
|
|
6240
6654
|
}
|
|
6241
6655
|
}
|
|
6242
6656
|
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
var _proc_exit = (code) => {
|
|
6260
|
-
EXITSTATUS = code;
|
|
6261
|
-
if (!keepRuntimeAlive()) {
|
|
6262
|
-
Module['onExit']?.(code);
|
|
6263
|
-
ABORT = true;
|
|
6264
|
-
}
|
|
6265
|
-
quit_(code, new ExitStatus(code));
|
|
6266
|
-
};
|
|
6267
|
-
|
|
6268
|
-
/** @suppress {duplicate } */ /** @param {boolean|number=} implicit */ var exitJS =
|
|
6269
|
-
(status, implicit) => {
|
|
6270
|
-
EXITSTATUS = status;
|
|
6271
|
-
if (!keepRuntimeAlive()) {
|
|
6272
|
-
exitRuntime();
|
|
6273
|
-
}
|
|
6274
|
-
_proc_exit(status);
|
|
6275
|
-
};
|
|
6276
|
-
|
|
6277
|
-
var _exit = exitJS;
|
|
6278
|
-
|
|
6279
|
-
Module['_exit'] = _exit;
|
|
6280
|
-
|
|
6281
|
-
var maybeExit = () => {
|
|
6282
|
-
if (runtimeExited) {
|
|
6283
|
-
return;
|
|
6284
|
-
}
|
|
6285
|
-
if (!keepRuntimeAlive()) {
|
|
6286
|
-
try {
|
|
6287
|
-
_exit(EXITSTATUS);
|
|
6288
|
-
} catch (e) {
|
|
6289
|
-
handleException(e);
|
|
6290
|
-
}
|
|
6657
|
+
function ___syscall_readlinkat(dirfd, path, buf, bufsize) {
|
|
6658
|
+
try {
|
|
6659
|
+
path = SYSCALLS.getStr(path);
|
|
6660
|
+
path = SYSCALLS.calculateAt(dirfd, path);
|
|
6661
|
+
if (bufsize <= 0) return -28;
|
|
6662
|
+
var ret = FS.readlink(path);
|
|
6663
|
+
var len = Math.min(bufsize, lengthBytesUTF8(ret));
|
|
6664
|
+
var endChar = HEAP8[buf + len];
|
|
6665
|
+
stringToUTF8(ret, buf, bufsize + 1);
|
|
6666
|
+
// readlink is one of the rare functions that write out a C string, but does never append a null to the output buffer(!)
|
|
6667
|
+
// stringToUTF8() always appends a null byte, so restore the character under the null byte after the write.
|
|
6668
|
+
HEAP8[buf + len] = endChar;
|
|
6669
|
+
return len;
|
|
6670
|
+
} catch (e) {
|
|
6671
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6672
|
+
return -e.errno;
|
|
6291
6673
|
}
|
|
6292
|
-
}
|
|
6674
|
+
}
|
|
6293
6675
|
|
|
6294
|
-
|
|
6295
|
-
if (runtimeExited || ABORT) {
|
|
6296
|
-
return;
|
|
6297
|
-
}
|
|
6676
|
+
function ___syscall_recvfrom(fd, buf, len, flags, addr, addrlen) {
|
|
6298
6677
|
try {
|
|
6299
|
-
|
|
6300
|
-
|
|
6678
|
+
var sock = getSocketFromFD(fd);
|
|
6679
|
+
var msg = sock.sock_ops.recvmsg(
|
|
6680
|
+
sock,
|
|
6681
|
+
len,
|
|
6682
|
+
typeof flags !== 'undefined' ? flags : 0
|
|
6683
|
+
);
|
|
6684
|
+
if (!msg) return 0;
|
|
6685
|
+
// socket is closed
|
|
6686
|
+
if (addr) {
|
|
6687
|
+
var errno = writeSockaddr(
|
|
6688
|
+
addr,
|
|
6689
|
+
sock.family,
|
|
6690
|
+
DNS.lookup_name(msg.addr),
|
|
6691
|
+
msg.port,
|
|
6692
|
+
addrlen
|
|
6693
|
+
);
|
|
6694
|
+
}
|
|
6695
|
+
HEAPU8.set(msg.buffer, buf);
|
|
6696
|
+
return msg.buffer.byteLength;
|
|
6301
6697
|
} catch (e) {
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
};
|
|
6305
|
-
|
|
6306
|
-
var _emscripten_get_now = () => performance.now();
|
|
6307
|
-
|
|
6308
|
-
var __setitimer_js = (which, timeout_ms) => {
|
|
6309
|
-
// First, clear any existing timer.
|
|
6310
|
-
if (timers[which]) {
|
|
6311
|
-
clearTimeout(timers[which].id);
|
|
6312
|
-
delete timers[which];
|
|
6698
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6699
|
+
return -e.errno;
|
|
6313
6700
|
}
|
|
6314
|
-
|
|
6315
|
-
// more to do.
|
|
6316
|
-
if (!timeout_ms) return 0;
|
|
6317
|
-
var id = setTimeout(() => {
|
|
6318
|
-
delete timers[which];
|
|
6319
|
-
callUserCallback(() =>
|
|
6320
|
-
__emscripten_timeout(which, _emscripten_get_now())
|
|
6321
|
-
);
|
|
6322
|
-
}, timeout_ms);
|
|
6323
|
-
timers[which] = {
|
|
6324
|
-
id,
|
|
6325
|
-
timeout_ms,
|
|
6326
|
-
};
|
|
6327
|
-
return 0;
|
|
6328
|
-
};
|
|
6701
|
+
}
|
|
6329
6702
|
|
|
6330
|
-
|
|
6331
|
-
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
// compares whether the output of the given date the same (Standard) or less
|
|
6342
|
-
// (DST).
|
|
6343
|
-
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
|
|
6344
|
-
// timezone is specified as seconds west of UTC ("The external variable
|
|
6345
|
-
// `timezone` shall be set to the difference, in seconds, between
|
|
6346
|
-
// Coordinated Universal Time (UTC) and local standard time."), the same
|
|
6347
|
-
// as returned by stdTimezoneOffset.
|
|
6348
|
-
// See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
|
|
6349
|
-
HEAPU32[timezone >> 2] = stdTimezoneOffset * 60;
|
|
6350
|
-
HEAP32[daylight >> 2] = Number(winterOffset != summerOffset);
|
|
6351
|
-
var extractZone = (timezoneOffset) => {
|
|
6352
|
-
// Why inverse sign?
|
|
6353
|
-
// Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
|
|
6354
|
-
var sign = timezoneOffset >= 0 ? '-' : '+';
|
|
6355
|
-
var absOffset = Math.abs(timezoneOffset);
|
|
6356
|
-
var hours = String(Math.floor(absOffset / 60)).padStart(2, '0');
|
|
6357
|
-
var minutes = String(absOffset % 60).padStart(2, '0');
|
|
6358
|
-
return `UTC${sign}${hours}${minutes}`;
|
|
6359
|
-
};
|
|
6360
|
-
var winterName = extractZone(winterOffset);
|
|
6361
|
-
var summerName = extractZone(summerOffset);
|
|
6362
|
-
if (summerOffset < winterOffset) {
|
|
6363
|
-
// Northern hemisphere
|
|
6364
|
-
stringToUTF8(winterName, std_name, 17);
|
|
6365
|
-
stringToUTF8(summerName, dst_name, 17);
|
|
6366
|
-
} else {
|
|
6367
|
-
stringToUTF8(winterName, dst_name, 17);
|
|
6368
|
-
stringToUTF8(summerName, std_name, 17);
|
|
6703
|
+
function ___syscall_renameat(olddirfd, oldpath, newdirfd, newpath) {
|
|
6704
|
+
try {
|
|
6705
|
+
oldpath = SYSCALLS.getStr(oldpath);
|
|
6706
|
+
newpath = SYSCALLS.getStr(newpath);
|
|
6707
|
+
oldpath = SYSCALLS.calculateAt(olddirfd, oldpath);
|
|
6708
|
+
newpath = SYSCALLS.calculateAt(newdirfd, newpath);
|
|
6709
|
+
FS.rename(oldpath, newpath);
|
|
6710
|
+
return 0;
|
|
6711
|
+
} catch (e) {
|
|
6712
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6713
|
+
return -e.errno;
|
|
6369
6714
|
}
|
|
6370
|
-
}
|
|
6371
|
-
|
|
6372
|
-
var _emscripten_date_now = () => Date.now();
|
|
6373
|
-
|
|
6374
|
-
var nowIsMonotonic = 1;
|
|
6375
|
-
|
|
6376
|
-
var checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3;
|
|
6715
|
+
}
|
|
6377
6716
|
|
|
6378
|
-
function
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
now = _emscripten_date_now();
|
|
6387
|
-
} else if (nowIsMonotonic) {
|
|
6388
|
-
now = _emscripten_get_now();
|
|
6389
|
-
} else {
|
|
6390
|
-
return 52;
|
|
6717
|
+
function ___syscall_rmdir(path) {
|
|
6718
|
+
try {
|
|
6719
|
+
path = SYSCALLS.getStr(path);
|
|
6720
|
+
FS.rmdir(path);
|
|
6721
|
+
return 0;
|
|
6722
|
+
} catch (e) {
|
|
6723
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6724
|
+
return -e.errno;
|
|
6391
6725
|
}
|
|
6392
|
-
// "now" is in ms, and wasi times are in ns.
|
|
6393
|
-
var nsec = Math.round(now * 1e3 * 1e3);
|
|
6394
|
-
HEAP64[ptime >> 3] = BigInt(nsec);
|
|
6395
|
-
return 0;
|
|
6396
6726
|
}
|
|
6397
6727
|
|
|
6398
|
-
|
|
6399
|
-
// Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
|
|
6400
|
-
// full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
|
|
6401
|
-
// for any code that deals with heap sizes, which would require special
|
|
6402
|
-
// casing all heap size related code to treat 0 specially.
|
|
6403
|
-
2147483648;
|
|
6404
|
-
|
|
6405
|
-
var _emscripten_get_heap_max = () => getHeapMax();
|
|
6406
|
-
|
|
6407
|
-
var growMemory = (size) => {
|
|
6408
|
-
var b = wasmMemory.buffer;
|
|
6409
|
-
var pages = ((size - b.byteLength + 65535) / 65536) | 0;
|
|
6728
|
+
function ___syscall_sendto(fd, message, length, flags, addr, addr_len) {
|
|
6410
6729
|
try {
|
|
6411
|
-
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
return 1;
|
|
6416
|
-
} catch (e) {}
|
|
6417
|
-
};
|
|
6418
|
-
|
|
6419
|
-
var _emscripten_resize_heap = (requestedSize) => {
|
|
6420
|
-
var oldSize = HEAPU8.length;
|
|
6421
|
-
// With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
|
|
6422
|
-
requestedSize >>>= 0;
|
|
6423
|
-
// With multithreaded builds, races can happen (another thread might increase the size
|
|
6424
|
-
// in between), so return a failure, and let the caller retry.
|
|
6425
|
-
// Memory resize rules:
|
|
6426
|
-
// 1. Always increase heap size to at least the requested size, rounded up
|
|
6427
|
-
// to next page multiple.
|
|
6428
|
-
// 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
|
|
6429
|
-
// geometrically: increase the heap size according to
|
|
6430
|
-
// MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
|
|
6431
|
-
// overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
|
|
6432
|
-
// 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
|
|
6433
|
-
// linearly: increase the heap size by at least
|
|
6434
|
-
// MEMORY_GROWTH_LINEAR_STEP bytes.
|
|
6435
|
-
// 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
|
|
6436
|
-
// MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
|
|
6437
|
-
// 4. If we were unable to allocate as much memory, it may be due to
|
|
6438
|
-
// over-eager decision to excessively reserve due to (3) above.
|
|
6439
|
-
// Hence if an allocation fails, cut down on the amount of excess
|
|
6440
|
-
// growth, in an attempt to succeed to perform a smaller allocation.
|
|
6441
|
-
// A limit is set for how much we can grow. We should not exceed that
|
|
6442
|
-
// (the wasm binary specifies it, so if we tried, we'd fail anyhow).
|
|
6443
|
-
var maxHeapSize = getHeapMax();
|
|
6444
|
-
if (requestedSize > maxHeapSize) {
|
|
6445
|
-
return false;
|
|
6446
|
-
}
|
|
6447
|
-
// Loop through potential heap size increases. If we attempt a too eager
|
|
6448
|
-
// reservation that fails, cut down on the attempted size and reserve a
|
|
6449
|
-
// smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
|
|
6450
|
-
for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
|
|
6451
|
-
var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown);
|
|
6452
|
-
// ensure geometric growth
|
|
6453
|
-
// but limit overreserving (default to capping at +96MB overgrowth at most)
|
|
6454
|
-
overGrownHeapSize = Math.min(
|
|
6455
|
-
overGrownHeapSize,
|
|
6456
|
-
requestedSize + 100663296
|
|
6457
|
-
);
|
|
6458
|
-
var newSize = Math.min(
|
|
6459
|
-
maxHeapSize,
|
|
6460
|
-
alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536)
|
|
6461
|
-
);
|
|
6462
|
-
var replacement = growMemory(newSize);
|
|
6463
|
-
if (replacement) {
|
|
6464
|
-
return true;
|
|
6730
|
+
var sock = getSocketFromFD(fd);
|
|
6731
|
+
if (!addr) {
|
|
6732
|
+
// send, no address provided
|
|
6733
|
+
return FS.write(sock.stream, HEAP8, message, length);
|
|
6465
6734
|
}
|
|
6735
|
+
var dest = getSocketAddress(addr, addr_len);
|
|
6736
|
+
// sendto an address
|
|
6737
|
+
return sock.sock_ops.sendmsg(
|
|
6738
|
+
sock,
|
|
6739
|
+
HEAP8,
|
|
6740
|
+
message,
|
|
6741
|
+
length,
|
|
6742
|
+
dest.addr,
|
|
6743
|
+
dest.port
|
|
6744
|
+
);
|
|
6745
|
+
} catch (e) {
|
|
6746
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6747
|
+
return -e.errno;
|
|
6466
6748
|
}
|
|
6467
|
-
|
|
6468
|
-
};
|
|
6469
|
-
|
|
6470
|
-
var runtimeKeepalivePush = () => {
|
|
6471
|
-
runtimeKeepaliveCounter += 1;
|
|
6472
|
-
};
|
|
6473
|
-
|
|
6474
|
-
var runtimeKeepalivePop = () => {
|
|
6475
|
-
runtimeKeepaliveCounter -= 1;
|
|
6476
|
-
};
|
|
6749
|
+
}
|
|
6477
6750
|
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6751
|
+
function ___syscall_socket(domain, type, protocol) {
|
|
6752
|
+
try {
|
|
6753
|
+
var sock = SOCKFS.createSocket(domain, type, protocol);
|
|
6754
|
+
return sock.stream.fd;
|
|
6755
|
+
} catch (e) {
|
|
6756
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6757
|
+
return -e.errno;
|
|
6758
|
+
}
|
|
6759
|
+
}
|
|
6485
6760
|
|
|
6486
|
-
|
|
6487
|
-
|
|
6761
|
+
function ___syscall_stat64(path, buf) {
|
|
6762
|
+
try {
|
|
6763
|
+
path = SYSCALLS.getStr(path);
|
|
6764
|
+
return SYSCALLS.writeStat(buf, FS.stat(path));
|
|
6765
|
+
} catch (e) {
|
|
6766
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6767
|
+
return -e.errno;
|
|
6768
|
+
}
|
|
6769
|
+
}
|
|
6488
6770
|
|
|
6489
|
-
|
|
6771
|
+
function ___syscall_statfs64(path, size, buf) {
|
|
6772
|
+
try {
|
|
6773
|
+
SYSCALLS.writeStatFs(buf, FS.statfs(SYSCALLS.getStr(path)));
|
|
6774
|
+
return 0;
|
|
6775
|
+
} catch (e) {
|
|
6776
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6777
|
+
return -e.errno;
|
|
6778
|
+
}
|
|
6779
|
+
}
|
|
6490
6780
|
|
|
6491
|
-
|
|
6781
|
+
function ___syscall_symlinkat(target, dirfd, linkpath) {
|
|
6782
|
+
try {
|
|
6783
|
+
target = SYSCALLS.getStr(target);
|
|
6784
|
+
linkpath = SYSCALLS.getStr(linkpath);
|
|
6785
|
+
linkpath = SYSCALLS.calculateAt(dirfd, linkpath);
|
|
6786
|
+
FS.symlink(target, linkpath);
|
|
6787
|
+
return 0;
|
|
6788
|
+
} catch (e) {
|
|
6789
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6790
|
+
return -e.errno;
|
|
6791
|
+
}
|
|
6792
|
+
}
|
|
6492
6793
|
|
|
6493
|
-
|
|
6794
|
+
function ___syscall_unlinkat(dirfd, path, flags) {
|
|
6795
|
+
try {
|
|
6796
|
+
path = SYSCALLS.getStr(path);
|
|
6797
|
+
path = SYSCALLS.calculateAt(dirfd, path);
|
|
6798
|
+
if (flags === 0) {
|
|
6799
|
+
FS.unlink(path);
|
|
6800
|
+
} else if (flags === 512) {
|
|
6801
|
+
FS.rmdir(path);
|
|
6802
|
+
} else {
|
|
6803
|
+
abort('Invalid flags passed to unlinkat');
|
|
6804
|
+
}
|
|
6805
|
+
return 0;
|
|
6806
|
+
} catch (e) {
|
|
6807
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6808
|
+
return -e.errno;
|
|
6809
|
+
}
|
|
6810
|
+
}
|
|
6494
6811
|
|
|
6495
|
-
var
|
|
6812
|
+
var readI53FromI64 = (ptr) =>
|
|
6813
|
+
HEAPU32[ptr >> 2] + HEAP32[(ptr + 4) >> 2] * 4294967296;
|
|
6496
6814
|
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
|
|
6500
|
-
|
|
6501
|
-
var
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6516
|
-
|
|
6517
|
-
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
if (
|
|
6523
|
-
|
|
6815
|
+
function ___syscall_utimensat(dirfd, path, times, flags) {
|
|
6816
|
+
try {
|
|
6817
|
+
path = SYSCALLS.getStr(path);
|
|
6818
|
+
path = SYSCALLS.calculateAt(dirfd, path, true);
|
|
6819
|
+
var now = Date.now(),
|
|
6820
|
+
atime,
|
|
6821
|
+
mtime;
|
|
6822
|
+
if (!times) {
|
|
6823
|
+
atime = now;
|
|
6824
|
+
mtime = now;
|
|
6825
|
+
} else {
|
|
6826
|
+
var seconds = readI53FromI64(times);
|
|
6827
|
+
var nanoseconds = HEAP32[(times + 8) >> 2];
|
|
6828
|
+
if (nanoseconds == 1073741823) {
|
|
6829
|
+
atime = now;
|
|
6830
|
+
} else if (nanoseconds == 1073741822) {
|
|
6831
|
+
atime = null;
|
|
6832
|
+
} else {
|
|
6833
|
+
atime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
|
|
6834
|
+
}
|
|
6835
|
+
times += 16;
|
|
6836
|
+
seconds = readI53FromI64(times);
|
|
6837
|
+
nanoseconds = HEAP32[(times + 8) >> 2];
|
|
6838
|
+
if (nanoseconds == 1073741823) {
|
|
6839
|
+
mtime = now;
|
|
6840
|
+
} else if (nanoseconds == 1073741822) {
|
|
6841
|
+
mtime = null;
|
|
6842
|
+
} else {
|
|
6843
|
+
mtime = seconds * 1e3 + nanoseconds / (1e3 * 1e3);
|
|
6844
|
+
}
|
|
6524
6845
|
}
|
|
6525
|
-
|
|
6526
|
-
|
|
6527
|
-
|
|
6846
|
+
// null here means UTIME_OMIT was passed. If both were set to UTIME_OMIT then
|
|
6847
|
+
// we can skip the call completely.
|
|
6848
|
+
if ((mtime ?? atime) !== null) {
|
|
6849
|
+
FS.utime(path, atime, mtime);
|
|
6528
6850
|
}
|
|
6529
|
-
|
|
6851
|
+
return 0;
|
|
6852
|
+
} catch (e) {
|
|
6853
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6854
|
+
return -e.errno;
|
|
6530
6855
|
}
|
|
6531
|
-
|
|
6532
|
-
};
|
|
6856
|
+
}
|
|
6533
6857
|
|
|
6534
|
-
var
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6858
|
+
var __abort_js = () => abort('');
|
|
6859
|
+
|
|
6860
|
+
var __emscripten_lookup_name = (name) => {
|
|
6861
|
+
// uint32_t _emscripten_lookup_name(const char *name);
|
|
6862
|
+
var nameString = UTF8ToString(name);
|
|
6863
|
+
return inetPton4(DNS.lookup_name(nameString));
|
|
6540
6864
|
};
|
|
6541
6865
|
|
|
6542
|
-
var
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
stringToAscii(string, ptr);
|
|
6548
|
-
bufSize += string.length + 1;
|
|
6549
|
-
});
|
|
6550
|
-
return 0;
|
|
6866
|
+
var runtimeKeepaliveCounter = 0;
|
|
6867
|
+
|
|
6868
|
+
var __emscripten_runtime_keepalive_clear = () => {
|
|
6869
|
+
noExitRuntime = false;
|
|
6870
|
+
runtimeKeepaliveCounter = 0;
|
|
6551
6871
|
};
|
|
6552
6872
|
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
|
|
6873
|
+
function __gmtime_js(time, tmPtr) {
|
|
6874
|
+
time = bigintToI53Checked(time);
|
|
6875
|
+
var date = new Date(time * 1e3);
|
|
6876
|
+
HEAP32[tmPtr >> 2] = date.getUTCSeconds();
|
|
6877
|
+
HEAP32[(tmPtr + 4) >> 2] = date.getUTCMinutes();
|
|
6878
|
+
HEAP32[(tmPtr + 8) >> 2] = date.getUTCHours();
|
|
6879
|
+
HEAP32[(tmPtr + 12) >> 2] = date.getUTCDate();
|
|
6880
|
+
HEAP32[(tmPtr + 16) >> 2] = date.getUTCMonth();
|
|
6881
|
+
HEAP32[(tmPtr + 20) >> 2] = date.getUTCFullYear() - 1900;
|
|
6882
|
+
HEAP32[(tmPtr + 24) >> 2] = date.getUTCDay();
|
|
6883
|
+
var start = Date.UTC(date.getUTCFullYear(), 0, 1, 0, 0, 0, 0);
|
|
6884
|
+
var yday = ((date.getTime() - start) / (1e3 * 60 * 60 * 24)) | 0;
|
|
6885
|
+
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
6886
|
+
}
|
|
6887
|
+
|
|
6888
|
+
var isLeapYear = (year) =>
|
|
6889
|
+
year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
6890
|
+
|
|
6891
|
+
var MONTH_DAYS_LEAP_CUMULATIVE = [
|
|
6892
|
+
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335,
|
|
6893
|
+
];
|
|
6894
|
+
|
|
6895
|
+
var MONTH_DAYS_REGULAR_CUMULATIVE = [
|
|
6896
|
+
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334,
|
|
6897
|
+
];
|
|
6898
|
+
|
|
6899
|
+
var ydayFromDate = (date) => {
|
|
6900
|
+
var leap = isLeapYear(date.getFullYear());
|
|
6901
|
+
var monthDaysCumulative = leap
|
|
6902
|
+
? MONTH_DAYS_LEAP_CUMULATIVE
|
|
6903
|
+
: MONTH_DAYS_REGULAR_CUMULATIVE;
|
|
6904
|
+
var yday = monthDaysCumulative[date.getMonth()] + date.getDate() - 1;
|
|
6905
|
+
// -1 since it's days since Jan 1
|
|
6906
|
+
return yday;
|
|
6560
6907
|
};
|
|
6561
6908
|
|
|
6562
|
-
function
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
6570
|
-
|
|
6909
|
+
function __localtime_js(time, tmPtr) {
|
|
6910
|
+
time = bigintToI53Checked(time);
|
|
6911
|
+
var date = new Date(time * 1e3);
|
|
6912
|
+
HEAP32[tmPtr >> 2] = date.getSeconds();
|
|
6913
|
+
HEAP32[(tmPtr + 4) >> 2] = date.getMinutes();
|
|
6914
|
+
HEAP32[(tmPtr + 8) >> 2] = date.getHours();
|
|
6915
|
+
HEAP32[(tmPtr + 12) >> 2] = date.getDate();
|
|
6916
|
+
HEAP32[(tmPtr + 16) >> 2] = date.getMonth();
|
|
6917
|
+
HEAP32[(tmPtr + 20) >> 2] = date.getFullYear() - 1900;
|
|
6918
|
+
HEAP32[(tmPtr + 24) >> 2] = date.getDay();
|
|
6919
|
+
var yday = ydayFromDate(date) | 0;
|
|
6920
|
+
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
6921
|
+
HEAP32[(tmPtr + 36) >> 2] = -(date.getTimezoneOffset() * 60);
|
|
6922
|
+
// Attention: DST is in December in South, and some regions don't have DST at all.
|
|
6923
|
+
var start = new Date(date.getFullYear(), 0, 1);
|
|
6924
|
+
var summerOffset = new Date(
|
|
6925
|
+
date.getFullYear(),
|
|
6926
|
+
6,
|
|
6927
|
+
1
|
|
6928
|
+
).getTimezoneOffset();
|
|
6929
|
+
var winterOffset = start.getTimezoneOffset();
|
|
6930
|
+
var dst =
|
|
6931
|
+
(summerOffset != winterOffset &&
|
|
6932
|
+
date.getTimezoneOffset() ==
|
|
6933
|
+
Math.min(winterOffset, summerOffset)) | 0;
|
|
6934
|
+
HEAP32[(tmPtr + 32) >> 2] = dst;
|
|
6571
6935
|
}
|
|
6572
6936
|
|
|
6573
|
-
function
|
|
6574
|
-
|
|
6575
|
-
var
|
|
6576
|
-
|
|
6577
|
-
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
|
|
6937
|
+
var __mktime_js = function (tmPtr) {
|
|
6938
|
+
var ret = (() => {
|
|
6939
|
+
var date = new Date(
|
|
6940
|
+
HEAP32[(tmPtr + 20) >> 2] + 1900,
|
|
6941
|
+
HEAP32[(tmPtr + 16) >> 2],
|
|
6942
|
+
HEAP32[(tmPtr + 12) >> 2],
|
|
6943
|
+
HEAP32[(tmPtr + 8) >> 2],
|
|
6944
|
+
HEAP32[(tmPtr + 4) >> 2],
|
|
6945
|
+
HEAP32[tmPtr >> 2],
|
|
6946
|
+
0
|
|
6947
|
+
);
|
|
6948
|
+
// There's an ambiguous hour when the time goes back; the tm_isdst field is
|
|
6949
|
+
// used to disambiguate it. Date() basically guesses, so we fix it up if it
|
|
6950
|
+
// guessed wrong, or fill in tm_isdst with the guess if it's -1.
|
|
6951
|
+
var dst = HEAP32[(tmPtr + 32) >> 2];
|
|
6952
|
+
var guessedOffset = date.getTimezoneOffset();
|
|
6953
|
+
var start = new Date(date.getFullYear(), 0, 1);
|
|
6954
|
+
var summerOffset = new Date(
|
|
6955
|
+
date.getFullYear(),
|
|
6956
|
+
6,
|
|
6957
|
+
1
|
|
6958
|
+
).getTimezoneOffset();
|
|
6959
|
+
var winterOffset = start.getTimezoneOffset();
|
|
6960
|
+
var dstOffset = Math.min(winterOffset, summerOffset);
|
|
6961
|
+
// DST is in December in South
|
|
6962
|
+
if (dst < 0) {
|
|
6963
|
+
// Attention: some regions don't have DST at all.
|
|
6964
|
+
HEAP32[(tmPtr + 32) >> 2] = Number(
|
|
6965
|
+
summerOffset != winterOffset && dstOffset == guessedOffset
|
|
6966
|
+
);
|
|
6967
|
+
} else if (dst > 0 != (dstOffset == guessedOffset)) {
|
|
6968
|
+
var nonDstOffset = Math.max(winterOffset, summerOffset);
|
|
6969
|
+
var trueOffset = dst > 0 ? dstOffset : nonDstOffset;
|
|
6970
|
+
// Don't try setMinutes(date.getMinutes() + ...) -- it's messed up.
|
|
6971
|
+
date.setTime(
|
|
6972
|
+
date.getTime() + (trueOffset - guessedOffset) * 6e4
|
|
6973
|
+
);
|
|
6589
6974
|
}
|
|
6590
|
-
|
|
6591
|
-
|
|
6592
|
-
|
|
6593
|
-
|
|
6594
|
-
|
|
6595
|
-
|
|
6596
|
-
|
|
6597
|
-
|
|
6598
|
-
|
|
6599
|
-
|
|
6600
|
-
|
|
6601
|
-
|
|
6602
|
-
|
|
6603
|
-
iov,
|
|
6604
|
-
iovcnt,
|
|
6605
|
-
offset
|
|
6606
|
-
) => {
|
|
6607
|
-
var ret = 0;
|
|
6608
|
-
for (var i = 0; i < iovcnt; i++) {
|
|
6609
|
-
var ptr = HEAPU32[iov >> 2];
|
|
6610
|
-
var len = HEAPU32[(iov + 4) >> 2];
|
|
6611
|
-
iov += 8;
|
|
6612
|
-
var curr = FS.read(stream, HEAP8, ptr, len, offset);
|
|
6613
|
-
if (curr < 0) return -1;
|
|
6614
|
-
ret += curr;
|
|
6615
|
-
if (curr < len) break;
|
|
6616
|
-
// nothing more to read
|
|
6617
|
-
if (typeof offset != 'undefined') {
|
|
6618
|
-
offset += curr;
|
|
6975
|
+
HEAP32[(tmPtr + 24) >> 2] = date.getDay();
|
|
6976
|
+
var yday = ydayFromDate(date) | 0;
|
|
6977
|
+
HEAP32[(tmPtr + 28) >> 2] = yday;
|
|
6978
|
+
// To match expected behavior, update fields from date
|
|
6979
|
+
HEAP32[tmPtr >> 2] = date.getSeconds();
|
|
6980
|
+
HEAP32[(tmPtr + 4) >> 2] = date.getMinutes();
|
|
6981
|
+
HEAP32[(tmPtr + 8) >> 2] = date.getHours();
|
|
6982
|
+
HEAP32[(tmPtr + 12) >> 2] = date.getDate();
|
|
6983
|
+
HEAP32[(tmPtr + 16) >> 2] = date.getMonth();
|
|
6984
|
+
HEAP32[(tmPtr + 20) >> 2] = date.getYear();
|
|
6985
|
+
var timeMs = date.getTime();
|
|
6986
|
+
if (isNaN(timeMs)) {
|
|
6987
|
+
return -1;
|
|
6619
6988
|
}
|
|
6620
|
-
|
|
6621
|
-
|
|
6989
|
+
// Return time in microseconds
|
|
6990
|
+
return timeMs / 1e3;
|
|
6991
|
+
})();
|
|
6992
|
+
return BigInt(ret);
|
|
6622
6993
|
};
|
|
6623
6994
|
|
|
6624
|
-
function
|
|
6995
|
+
function __mmap_js(len, prot, flags, fd, offset, allocated, addr) {
|
|
6996
|
+
offset = bigintToI53Checked(offset);
|
|
6625
6997
|
try {
|
|
6998
|
+
if (isNaN(offset)) return 61;
|
|
6626
6999
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
6627
|
-
var
|
|
6628
|
-
|
|
7000
|
+
var res = FS.mmap(stream, len, offset, prot, flags);
|
|
7001
|
+
var ptr = res.ptr;
|
|
7002
|
+
HEAP32[allocated >> 2] = res.allocated;
|
|
7003
|
+
HEAPU32[addr >> 2] = ptr;
|
|
6629
7004
|
return 0;
|
|
6630
7005
|
} catch (e) {
|
|
6631
7006
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6632
|
-
return e.errno;
|
|
7007
|
+
return -e.errno;
|
|
6633
7008
|
}
|
|
6634
7009
|
}
|
|
6635
7010
|
|
|
6636
|
-
function
|
|
7011
|
+
function __munmap_js(addr, len, prot, flags, fd, offset) {
|
|
6637
7012
|
offset = bigintToI53Checked(offset);
|
|
6638
7013
|
try {
|
|
6639
|
-
if (isNaN(offset)) return 61;
|
|
6640
7014
|
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
6641
|
-
|
|
6642
|
-
|
|
6643
|
-
|
|
6644
|
-
stream.getdents = null;
|
|
6645
|
-
// reset readdir state
|
|
6646
|
-
return 0;
|
|
7015
|
+
if (prot & 2) {
|
|
7016
|
+
SYSCALLS.doMsync(addr, stream, len, flags, offset);
|
|
7017
|
+
}
|
|
6647
7018
|
} catch (e) {
|
|
6648
7019
|
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6649
|
-
return e.errno;
|
|
7020
|
+
return -e.errno;
|
|
6650
7021
|
}
|
|
6651
7022
|
}
|
|
6652
7023
|
|
|
6653
|
-
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
iov += 8;
|
|
6664
|
-
var curr = FS.write(stream, HEAP8, ptr, len, offset);
|
|
6665
|
-
if (curr < 0) return -1;
|
|
6666
|
-
ret += curr;
|
|
6667
|
-
if (curr < len) {
|
|
6668
|
-
// No more space to write.
|
|
6669
|
-
break;
|
|
6670
|
-
}
|
|
6671
|
-
if (typeof offset != 'undefined') {
|
|
6672
|
-
offset += curr;
|
|
6673
|
-
}
|
|
7024
|
+
var timers = {};
|
|
7025
|
+
|
|
7026
|
+
var handleException = (e) => {
|
|
7027
|
+
// Certain exception types we do not treat as errors since they are used for
|
|
7028
|
+
// internal control flow.
|
|
7029
|
+
// 1. ExitStatus, which is thrown by exit()
|
|
7030
|
+
// 2. "unwind", which is thrown by emscripten_unwind_to_js_event_loop() and others
|
|
7031
|
+
// that wish to return to JS event loop.
|
|
7032
|
+
if (e instanceof ExitStatus || e == 'unwind') {
|
|
7033
|
+
return EXITSTATUS;
|
|
6674
7034
|
}
|
|
6675
|
-
|
|
7035
|
+
quit_(1, e);
|
|
6676
7036
|
};
|
|
6677
7037
|
|
|
6678
|
-
|
|
6679
|
-
try {
|
|
6680
|
-
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
6681
|
-
var num = doWritev(stream, iov, iovcnt);
|
|
6682
|
-
HEAPU32[pnum >> 2] = num;
|
|
6683
|
-
return 0;
|
|
6684
|
-
} catch (e) {
|
|
6685
|
-
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
6686
|
-
return e.errno;
|
|
6687
|
-
}
|
|
6688
|
-
}
|
|
7038
|
+
var keepRuntimeAlive = () => noExitRuntime || runtimeKeepaliveCounter > 0;
|
|
6689
7039
|
|
|
6690
|
-
var
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
var type = 0;
|
|
6696
|
-
var proto = 0;
|
|
6697
|
-
var ai;
|
|
6698
|
-
function allocaddrinfo(family, type, proto, canon, addr, port) {
|
|
6699
|
-
var sa, salen, ai;
|
|
6700
|
-
var errno;
|
|
6701
|
-
salen = family === 10 ? 28 : 16;
|
|
6702
|
-
addr = family === 10 ? inetNtop6(addr) : inetNtop4(addr);
|
|
6703
|
-
sa = _malloc(salen);
|
|
6704
|
-
errno = writeSockaddr(sa, family, addr, port);
|
|
6705
|
-
assert(!errno);
|
|
6706
|
-
ai = _malloc(32);
|
|
6707
|
-
HEAP32[(ai + 4) >> 2] = family;
|
|
6708
|
-
HEAP32[(ai + 8) >> 2] = type;
|
|
6709
|
-
HEAP32[(ai + 12) >> 2] = proto;
|
|
6710
|
-
HEAPU32[(ai + 24) >> 2] = canon;
|
|
6711
|
-
HEAPU32[(ai + 20) >> 2] = sa;
|
|
6712
|
-
if (family === 10) {
|
|
6713
|
-
HEAP32[(ai + 16) >> 2] = 28;
|
|
6714
|
-
} else {
|
|
6715
|
-
HEAP32[(ai + 16) >> 2] = 16;
|
|
6716
|
-
}
|
|
6717
|
-
HEAP32[(ai + 28) >> 2] = 0;
|
|
6718
|
-
return ai;
|
|
6719
|
-
}
|
|
6720
|
-
if (hint) {
|
|
6721
|
-
flags = HEAP32[hint >> 2];
|
|
6722
|
-
family = HEAP32[(hint + 4) >> 2];
|
|
6723
|
-
type = HEAP32[(hint + 8) >> 2];
|
|
6724
|
-
proto = HEAP32[(hint + 12) >> 2];
|
|
6725
|
-
}
|
|
6726
|
-
if (type && !proto) {
|
|
6727
|
-
proto = type === 2 ? 17 : 6;
|
|
6728
|
-
}
|
|
6729
|
-
if (!type && proto) {
|
|
6730
|
-
type = proto === 17 ? 2 : 1;
|
|
6731
|
-
}
|
|
6732
|
-
// If type or proto are set to zero in hints we should really be returning multiple addrinfo values, but for
|
|
6733
|
-
// now default to a TCP STREAM socket so we can at least return a sensible addrinfo given NULL hints.
|
|
6734
|
-
if (proto === 0) {
|
|
6735
|
-
proto = 6;
|
|
6736
|
-
}
|
|
6737
|
-
if (type === 0) {
|
|
6738
|
-
type = 1;
|
|
6739
|
-
}
|
|
6740
|
-
if (!node && !service) {
|
|
6741
|
-
return -2;
|
|
6742
|
-
}
|
|
6743
|
-
if (flags & ~(1 | 2 | 4 | 1024 | 8 | 16 | 32)) {
|
|
6744
|
-
return -1;
|
|
6745
|
-
}
|
|
6746
|
-
if (hint !== 0 && HEAP32[hint >> 2] & 2 && !node) {
|
|
6747
|
-
return -1;
|
|
6748
|
-
}
|
|
6749
|
-
if (flags & 32) {
|
|
6750
|
-
// TODO
|
|
6751
|
-
return -2;
|
|
6752
|
-
}
|
|
6753
|
-
if (type !== 0 && type !== 1 && type !== 2) {
|
|
6754
|
-
return -7;
|
|
6755
|
-
}
|
|
6756
|
-
if (family !== 0 && family !== 2 && family !== 10) {
|
|
6757
|
-
return -6;
|
|
6758
|
-
}
|
|
6759
|
-
if (service) {
|
|
6760
|
-
service = UTF8ToString(service);
|
|
6761
|
-
port = parseInt(service, 10);
|
|
6762
|
-
if (isNaN(port)) {
|
|
6763
|
-
if (flags & 1024) {
|
|
6764
|
-
return -2;
|
|
6765
|
-
}
|
|
6766
|
-
// TODO support resolving well-known service names from:
|
|
6767
|
-
// http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
|
|
6768
|
-
return -8;
|
|
6769
|
-
}
|
|
6770
|
-
}
|
|
6771
|
-
if (!node) {
|
|
6772
|
-
if (family === 0) {
|
|
6773
|
-
family = 2;
|
|
6774
|
-
}
|
|
6775
|
-
if ((flags & 1) === 0) {
|
|
6776
|
-
if (family === 2) {
|
|
6777
|
-
addr = _htonl(2130706433);
|
|
6778
|
-
} else {
|
|
6779
|
-
addr = [0, 0, 0, _htonl(1)];
|
|
6780
|
-
}
|
|
6781
|
-
}
|
|
6782
|
-
ai = allocaddrinfo(family, type, proto, null, addr, port);
|
|
6783
|
-
HEAPU32[out >> 2] = ai;
|
|
6784
|
-
return 0;
|
|
7040
|
+
var _proc_exit = (code) => {
|
|
7041
|
+
EXITSTATUS = code;
|
|
7042
|
+
if (!keepRuntimeAlive()) {
|
|
7043
|
+
Module['onExit']?.(code);
|
|
7044
|
+
ABORT = true;
|
|
6785
7045
|
}
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
|
|
6793
|
-
|
|
6794
|
-
addr = [0, 0, _htonl(65535), addr];
|
|
6795
|
-
family = 10;
|
|
6796
|
-
} else {
|
|
6797
|
-
return -2;
|
|
7046
|
+
quit_(code, new ExitStatus(code));
|
|
7047
|
+
};
|
|
7048
|
+
|
|
7049
|
+
/** @suppress {duplicate } */ /** @param {boolean|number=} implicit */ var exitJS =
|
|
7050
|
+
(status, implicit) => {
|
|
7051
|
+
EXITSTATUS = status;
|
|
7052
|
+
if (!keepRuntimeAlive()) {
|
|
7053
|
+
exitRuntime();
|
|
6798
7054
|
}
|
|
6799
|
-
|
|
6800
|
-
|
|
6801
|
-
|
|
6802
|
-
|
|
6803
|
-
|
|
6804
|
-
|
|
6805
|
-
|
|
6806
|
-
|
|
6807
|
-
|
|
7055
|
+
_proc_exit(status);
|
|
7056
|
+
};
|
|
7057
|
+
|
|
7058
|
+
var _exit = exitJS;
|
|
7059
|
+
|
|
7060
|
+
Module['_exit'] = _exit;
|
|
7061
|
+
|
|
7062
|
+
var maybeExit = () => {
|
|
7063
|
+
if (runtimeExited) {
|
|
7064
|
+
return;
|
|
7065
|
+
}
|
|
7066
|
+
if (!keepRuntimeAlive()) {
|
|
7067
|
+
try {
|
|
7068
|
+
_exit(EXITSTATUS);
|
|
7069
|
+
} catch (e) {
|
|
7070
|
+
handleException(e);
|
|
6808
7071
|
}
|
|
6809
7072
|
}
|
|
6810
|
-
|
|
6811
|
-
|
|
6812
|
-
|
|
6813
|
-
|
|
7073
|
+
};
|
|
7074
|
+
|
|
7075
|
+
var callUserCallback = (func) => {
|
|
7076
|
+
if (runtimeExited || ABORT) {
|
|
7077
|
+
return;
|
|
6814
7078
|
}
|
|
6815
|
-
|
|
6816
|
-
|
|
7079
|
+
try {
|
|
7080
|
+
func();
|
|
7081
|
+
maybeExit();
|
|
7082
|
+
} catch (e) {
|
|
7083
|
+
handleException(e);
|
|
6817
7084
|
}
|
|
6818
|
-
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
7085
|
+
};
|
|
7086
|
+
|
|
7087
|
+
var _emscripten_get_now = () => performance.now();
|
|
7088
|
+
|
|
7089
|
+
var __setitimer_js = (which, timeout_ms) => {
|
|
7090
|
+
// First, clear any existing timer.
|
|
7091
|
+
if (timers[which]) {
|
|
7092
|
+
clearTimeout(timers[which].id);
|
|
7093
|
+
delete timers[which];
|
|
6826
7094
|
}
|
|
6827
|
-
|
|
6828
|
-
|
|
7095
|
+
// A timeout of zero simply cancels the current timeout so we have nothing
|
|
7096
|
+
// more to do.
|
|
7097
|
+
if (!timeout_ms) return 0;
|
|
7098
|
+
var id = setTimeout(() => {
|
|
7099
|
+
delete timers[which];
|
|
7100
|
+
callUserCallback(() =>
|
|
7101
|
+
__emscripten_timeout(which, _emscripten_get_now())
|
|
7102
|
+
);
|
|
7103
|
+
}, timeout_ms);
|
|
7104
|
+
timers[which] = {
|
|
7105
|
+
id,
|
|
7106
|
+
timeout_ms,
|
|
7107
|
+
};
|
|
6829
7108
|
return 0;
|
|
6830
7109
|
};
|
|
6831
7110
|
|
|
6832
|
-
var
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
6837
|
-
var
|
|
6838
|
-
var
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
7111
|
+
var __tzset_js = (timezone, daylight, std_name, dst_name) => {
|
|
7112
|
+
// TODO: Use (malleable) environment variables instead of system settings.
|
|
7113
|
+
var currentYear = new Date().getFullYear();
|
|
7114
|
+
var winter = new Date(currentYear, 0, 1);
|
|
7115
|
+
var summer = new Date(currentYear, 6, 1);
|
|
7116
|
+
var winterOffset = winter.getTimezoneOffset();
|
|
7117
|
+
var summerOffset = summer.getTimezoneOffset();
|
|
7118
|
+
// Local standard timezone offset. Local standard time is not adjusted for
|
|
7119
|
+
// daylight savings. This code uses the fact that getTimezoneOffset returns
|
|
7120
|
+
// a greater value during Standard Time versus Daylight Saving Time (DST).
|
|
7121
|
+
// Thus it determines the expected output during Standard Time, and it
|
|
7122
|
+
// compares whether the output of the given date the same (Standard) or less
|
|
7123
|
+
// (DST).
|
|
7124
|
+
var stdTimezoneOffset = Math.max(winterOffset, summerOffset);
|
|
7125
|
+
// timezone is specified as seconds west of UTC ("The external variable
|
|
7126
|
+
// `timezone` shall be set to the difference, in seconds, between
|
|
7127
|
+
// Coordinated Universal Time (UTC) and local standard time."), the same
|
|
7128
|
+
// as returned by stdTimezoneOffset.
|
|
7129
|
+
// See http://pubs.opengroup.org/onlinepubs/009695399/functions/tzset.html
|
|
7130
|
+
HEAPU32[timezone >> 2] = stdTimezoneOffset * 60;
|
|
7131
|
+
HEAP32[daylight >> 2] = Number(winterOffset != summerOffset);
|
|
7132
|
+
var extractZone = (timezoneOffset) => {
|
|
7133
|
+
// Why inverse sign?
|
|
7134
|
+
// Read here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset
|
|
7135
|
+
var sign = timezoneOffset >= 0 ? '-' : '+';
|
|
7136
|
+
var absOffset = Math.abs(timezoneOffset);
|
|
7137
|
+
var hours = String(Math.floor(absOffset / 60)).padStart(2, '0');
|
|
7138
|
+
var minutes = String(absOffset % 60).padStart(2, '0');
|
|
7139
|
+
return `UTC${sign}${hours}${minutes}`;
|
|
7140
|
+
};
|
|
7141
|
+
var winterName = extractZone(winterOffset);
|
|
7142
|
+
var summerName = extractZone(summerOffset);
|
|
7143
|
+
if (summerOffset < winterOffset) {
|
|
7144
|
+
// Northern hemisphere
|
|
7145
|
+
stringToUTF8(winterName, std_name, 17);
|
|
7146
|
+
stringToUTF8(summerName, dst_name, 17);
|
|
7147
|
+
} else {
|
|
7148
|
+
stringToUTF8(winterName, dst_name, 17);
|
|
7149
|
+
stringToUTF8(summerName, std_name, 17);
|
|
6853
7150
|
}
|
|
6854
|
-
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6858
|
-
|
|
6859
|
-
|
|
7151
|
+
};
|
|
7152
|
+
|
|
7153
|
+
var _emscripten_date_now = () => Date.now();
|
|
7154
|
+
|
|
7155
|
+
var nowIsMonotonic = 1;
|
|
7156
|
+
|
|
7157
|
+
var checkWasiClock = (clock_id) => clock_id >= 0 && clock_id <= 3;
|
|
7158
|
+
|
|
7159
|
+
function _clock_time_get(clk_id, ignored_precision, ptime) {
|
|
7160
|
+
ignored_precision = bigintToI53Checked(ignored_precision);
|
|
7161
|
+
if (!checkWasiClock(clk_id)) {
|
|
7162
|
+
return 28;
|
|
6860
7163
|
}
|
|
6861
|
-
|
|
6862
|
-
|
|
6863
|
-
|
|
7164
|
+
var now;
|
|
7165
|
+
// all wasi clocks but realtime are monotonic
|
|
7166
|
+
if (clk_id === 0) {
|
|
7167
|
+
now = _emscripten_date_now();
|
|
7168
|
+
} else if (nowIsMonotonic) {
|
|
7169
|
+
now = _emscripten_get_now();
|
|
7170
|
+
} else {
|
|
7171
|
+
return 52;
|
|
6864
7172
|
}
|
|
7173
|
+
// "now" is in ms, and wasi times are in ns.
|
|
7174
|
+
var nsec = Math.round(now * 1e3 * 1e3);
|
|
7175
|
+
HEAP64[ptime >> 3] = BigInt(nsec);
|
|
6865
7176
|
return 0;
|
|
7177
|
+
}
|
|
7178
|
+
|
|
7179
|
+
var getHeapMax = () =>
|
|
7180
|
+
// Stay one Wasm page short of 4GB: while e.g. Chrome is able to allocate
|
|
7181
|
+
// full 4GB Wasm memories, the size will wrap back to 0 bytes in Wasm side
|
|
7182
|
+
// for any code that deals with heap sizes, which would require special
|
|
7183
|
+
// casing all heap size related code to treat 0 specially.
|
|
7184
|
+
2147483648;
|
|
7185
|
+
|
|
7186
|
+
var _emscripten_get_heap_max = () => getHeapMax();
|
|
7187
|
+
|
|
7188
|
+
var growMemory = (size) => {
|
|
7189
|
+
var b = wasmMemory.buffer;
|
|
7190
|
+
var pages = ((size - b.byteLength + 65535) / 65536) | 0;
|
|
7191
|
+
try {
|
|
7192
|
+
// round size grow request up to wasm page size (fixed 64KB per spec)
|
|
7193
|
+
wasmMemory.grow(pages);
|
|
7194
|
+
// .grow() takes a delta compared to the previous size
|
|
7195
|
+
updateMemoryViews();
|
|
7196
|
+
return 1;
|
|
7197
|
+
} catch (e) {}
|
|
7198
|
+
};
|
|
7199
|
+
|
|
7200
|
+
var _emscripten_resize_heap = (requestedSize) => {
|
|
7201
|
+
var oldSize = HEAPU8.length;
|
|
7202
|
+
// With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned.
|
|
7203
|
+
requestedSize >>>= 0;
|
|
7204
|
+
// With multithreaded builds, races can happen (another thread might increase the size
|
|
7205
|
+
// in between), so return a failure, and let the caller retry.
|
|
7206
|
+
// Memory resize rules:
|
|
7207
|
+
// 1. Always increase heap size to at least the requested size, rounded up
|
|
7208
|
+
// to next page multiple.
|
|
7209
|
+
// 2a. If MEMORY_GROWTH_LINEAR_STEP == -1, excessively resize the heap
|
|
7210
|
+
// geometrically: increase the heap size according to
|
|
7211
|
+
// MEMORY_GROWTH_GEOMETRIC_STEP factor (default +20%), At most
|
|
7212
|
+
// overreserve by MEMORY_GROWTH_GEOMETRIC_CAP bytes (default 96MB).
|
|
7213
|
+
// 2b. If MEMORY_GROWTH_LINEAR_STEP != -1, excessively resize the heap
|
|
7214
|
+
// linearly: increase the heap size by at least
|
|
7215
|
+
// MEMORY_GROWTH_LINEAR_STEP bytes.
|
|
7216
|
+
// 3. Max size for the heap is capped at 2048MB-WASM_PAGE_SIZE, or by
|
|
7217
|
+
// MAXIMUM_MEMORY, or by ASAN limit, depending on which is smallest
|
|
7218
|
+
// 4. If we were unable to allocate as much memory, it may be due to
|
|
7219
|
+
// over-eager decision to excessively reserve due to (3) above.
|
|
7220
|
+
// Hence if an allocation fails, cut down on the amount of excess
|
|
7221
|
+
// growth, in an attempt to succeed to perform a smaller allocation.
|
|
7222
|
+
// A limit is set for how much we can grow. We should not exceed that
|
|
7223
|
+
// (the wasm binary specifies it, so if we tried, we'd fail anyhow).
|
|
7224
|
+
var maxHeapSize = getHeapMax();
|
|
7225
|
+
if (requestedSize > maxHeapSize) {
|
|
7226
|
+
return false;
|
|
7227
|
+
}
|
|
7228
|
+
// Loop through potential heap size increases. If we attempt a too eager
|
|
7229
|
+
// reservation that fails, cut down on the attempted size and reserve a
|
|
7230
|
+
// smaller bump instead. (max 3 times, chosen somewhat arbitrarily)
|
|
7231
|
+
for (var cutDown = 1; cutDown <= 4; cutDown *= 2) {
|
|
7232
|
+
var overGrownHeapSize = oldSize * (1 + 0.2 / cutDown);
|
|
7233
|
+
// ensure geometric growth
|
|
7234
|
+
// but limit overreserving (default to capping at +96MB overgrowth at most)
|
|
7235
|
+
overGrownHeapSize = Math.min(
|
|
7236
|
+
overGrownHeapSize,
|
|
7237
|
+
requestedSize + 100663296
|
|
7238
|
+
);
|
|
7239
|
+
var newSize = Math.min(
|
|
7240
|
+
maxHeapSize,
|
|
7241
|
+
alignMemory(Math.max(requestedSize, overGrownHeapSize), 65536)
|
|
7242
|
+
);
|
|
7243
|
+
var replacement = growMemory(newSize);
|
|
7244
|
+
if (replacement) {
|
|
7245
|
+
return true;
|
|
7246
|
+
}
|
|
7247
|
+
}
|
|
7248
|
+
return false;
|
|
7249
|
+
};
|
|
7250
|
+
|
|
7251
|
+
var runtimeKeepalivePush = () => {
|
|
7252
|
+
runtimeKeepaliveCounter += 1;
|
|
7253
|
+
};
|
|
7254
|
+
|
|
7255
|
+
var runtimeKeepalivePop = () => {
|
|
7256
|
+
runtimeKeepaliveCounter -= 1;
|
|
7257
|
+
};
|
|
7258
|
+
|
|
7259
|
+
/** @param {number=} timeout */ var safeSetTimeout = (func, timeout) => {
|
|
7260
|
+
runtimeKeepalivePush();
|
|
7261
|
+
return setTimeout(() => {
|
|
7262
|
+
runtimeKeepalivePop();
|
|
7263
|
+
callUserCallback(func);
|
|
7264
|
+
}, timeout);
|
|
6866
7265
|
};
|
|
6867
7266
|
|
|
6868
|
-
var
|
|
6869
|
-
|
|
6870
|
-
map: {},
|
|
6871
|
-
};
|
|
7267
|
+
var _emscripten_sleep = (ms) =>
|
|
7268
|
+
Asyncify.handleSleep((wakeUp) => safeSetTimeout(wakeUp, ms));
|
|
6872
7269
|
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
//
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
7270
|
+
Module['_emscripten_sleep'] = _emscripten_sleep;
|
|
7271
|
+
|
|
7272
|
+
_emscripten_sleep.isAsync = true;
|
|
7273
|
+
|
|
7274
|
+
var ENV = PHPLoader.ENV || {};
|
|
7275
|
+
|
|
7276
|
+
var getExecutableName = () => thisProgram || './this.program';
|
|
7277
|
+
|
|
7278
|
+
var getEnvStrings = () => {
|
|
7279
|
+
if (!getEnvStrings.strings) {
|
|
7280
|
+
// Default values.
|
|
7281
|
+
// Browser language detection #8751
|
|
7282
|
+
var lang =
|
|
7283
|
+
(
|
|
7284
|
+
(typeof navigator == 'object' &&
|
|
7285
|
+
navigator.languages &&
|
|
7286
|
+
navigator.languages[0]) ||
|
|
7287
|
+
'C'
|
|
7288
|
+
).replace('-', '_') + '.UTF-8';
|
|
7289
|
+
var env = {
|
|
7290
|
+
USER: 'web_user',
|
|
7291
|
+
LOGNAME: 'web_user',
|
|
7292
|
+
PATH: '/',
|
|
7293
|
+
PWD: '/',
|
|
7294
|
+
HOME: '/home/web_user',
|
|
7295
|
+
LANG: lang,
|
|
7296
|
+
_: getExecutableName(),
|
|
7297
|
+
};
|
|
7298
|
+
// Apply the user-provided values, if any.
|
|
7299
|
+
for (var x in ENV) {
|
|
7300
|
+
// x is a key in ENV; if ENV[x] is undefined, that means it was
|
|
7301
|
+
// explicitly set to be so. We allow user code to do that to
|
|
7302
|
+
// force variables with default values to remain unset.
|
|
7303
|
+
if (ENV[x] === undefined) delete env[x];
|
|
7304
|
+
else env[x] = ENV[x];
|
|
6890
7305
|
}
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
HEAPU32[(pe + 4) >> 2] = aliasListBuf;
|
|
6897
|
-
HEAP32[(pe + 8) >> 2] = proto;
|
|
6898
|
-
return pe;
|
|
6899
|
-
}
|
|
6900
|
-
// Populate the protocol 'database'. The entries are limited to tcp and udp, though it is fairly trivial
|
|
6901
|
-
// to add extra entries from /etc/protocols if desired - though not sure if that'd actually be useful.
|
|
6902
|
-
var list = Protocols.list;
|
|
6903
|
-
var map = Protocols.map;
|
|
6904
|
-
if (list.length === 0) {
|
|
6905
|
-
var entry = allocprotoent('tcp', 6, ['TCP']);
|
|
6906
|
-
list.push(entry);
|
|
6907
|
-
map['tcp'] = map['6'] = entry;
|
|
6908
|
-
entry = allocprotoent('udp', 17, ['UDP']);
|
|
6909
|
-
list.push(entry);
|
|
6910
|
-
map['udp'] = map['17'] = entry;
|
|
7306
|
+
var strings = [];
|
|
7307
|
+
for (var x in env) {
|
|
7308
|
+
strings.push(`${x}=${env[x]}`);
|
|
7309
|
+
}
|
|
7310
|
+
getEnvStrings.strings = strings;
|
|
6911
7311
|
}
|
|
6912
|
-
|
|
7312
|
+
return getEnvStrings.strings;
|
|
6913
7313
|
};
|
|
6914
7314
|
|
|
6915
|
-
var
|
|
6916
|
-
|
|
6917
|
-
|
|
6918
|
-
|
|
6919
|
-
|
|
6920
|
-
|
|
7315
|
+
var stringToAscii = (str, buffer) => {
|
|
7316
|
+
for (var i = 0; i < str.length; ++i) {
|
|
7317
|
+
HEAP8[buffer++] = str.charCodeAt(i);
|
|
7318
|
+
}
|
|
7319
|
+
// Null-terminate the string
|
|
7320
|
+
HEAP8[buffer] = 0;
|
|
6921
7321
|
};
|
|
6922
7322
|
|
|
6923
|
-
var
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
7323
|
+
var _environ_get = (__environ, environ_buf) => {
|
|
7324
|
+
var bufSize = 0;
|
|
7325
|
+
getEnvStrings().forEach((string, i) => {
|
|
7326
|
+
var ptr = environ_buf + bufSize;
|
|
7327
|
+
HEAPU32[(__environ + i * 4) >> 2] = ptr;
|
|
7328
|
+
stringToAscii(string, ptr);
|
|
7329
|
+
bufSize += string.length + 1;
|
|
7330
|
+
});
|
|
7331
|
+
return 0;
|
|
6928
7332
|
};
|
|
6929
7333
|
|
|
6930
|
-
var
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
var
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
return
|
|
7334
|
+
var _environ_sizes_get = (penviron_count, penviron_buf_size) => {
|
|
7335
|
+
var strings = getEnvStrings();
|
|
7336
|
+
HEAPU32[penviron_count >> 2] = strings.length;
|
|
7337
|
+
var bufSize = 0;
|
|
7338
|
+
strings.forEach((string) => (bufSize += string.length + 1));
|
|
7339
|
+
HEAPU32[penviron_buf_size >> 2] = bufSize;
|
|
7340
|
+
return 0;
|
|
6937
7341
|
};
|
|
6938
7342
|
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
|
|
6943
|
-
|
|
6944
|
-
|
|
6945
|
-
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
|
|
6951
|
-
|
|
6952
|
-
|
|
6953
|
-
|
|
6954
|
-
|
|
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.
|
|
6991
|
-
PHPWASM.EventEmitter = ENVIRONMENT_IS_NODE
|
|
6992
|
-
? require('events').EventEmitter
|
|
6993
|
-
: class EventEmitter {
|
|
6994
|
-
constructor() {
|
|
6995
|
-
this.listeners = {};
|
|
6996
|
-
}
|
|
6997
|
-
emit(eventName, data) {
|
|
6998
|
-
if (this.listeners[eventName]) {
|
|
6999
|
-
this.listeners[eventName].forEach(
|
|
7000
|
-
(callback) => {
|
|
7001
|
-
callback(data);
|
|
7002
|
-
}
|
|
7003
|
-
);
|
|
7004
|
-
}
|
|
7005
|
-
}
|
|
7006
|
-
once(eventName, callback) {
|
|
7007
|
-
const self = this;
|
|
7008
|
-
function removedCallback() {
|
|
7009
|
-
callback(...arguments);
|
|
7010
|
-
self.removeListener(eventName, removedCallback);
|
|
7011
|
-
}
|
|
7012
|
-
this.on(eventName, removedCallback);
|
|
7013
|
-
}
|
|
7014
|
-
removeAllListeners(eventName) {
|
|
7015
|
-
if (eventName) {
|
|
7016
|
-
delete this.listeners[eventName];
|
|
7017
|
-
} else {
|
|
7018
|
-
this.listeners = {};
|
|
7019
|
-
}
|
|
7020
|
-
}
|
|
7021
|
-
removeListener(eventName, callback) {
|
|
7022
|
-
if (this.listeners[eventName]) {
|
|
7023
|
-
const idx =
|
|
7024
|
-
this.listeners[eventName].indexOf(callback);
|
|
7025
|
-
if (idx !== -1) {
|
|
7026
|
-
this.listeners[eventName].splice(idx, 1);
|
|
7027
|
-
}
|
|
7028
|
-
}
|
|
7029
|
-
}
|
|
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
|
-
};
|
|
7037
|
-
PHPWASM.child_proc_by_fd = {};
|
|
7038
|
-
PHPWASM.child_proc_by_pid = {};
|
|
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;
|
|
7343
|
+
function _fd_fdstat_get(fd, pbuf) {
|
|
7344
|
+
try {
|
|
7345
|
+
var rightsBase = 0;
|
|
7346
|
+
var rightsInheriting = 0;
|
|
7347
|
+
var flags = 0;
|
|
7348
|
+
{
|
|
7349
|
+
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
7350
|
+
// All character devices are terminals (other things a Linux system would
|
|
7351
|
+
// assume is a character device, like the mouse, we have special APIs for).
|
|
7352
|
+
var type = stream.tty
|
|
7353
|
+
? 2
|
|
7354
|
+
: FS.isDir(stream.mode)
|
|
7355
|
+
? 3
|
|
7356
|
+
: FS.isLink(stream.mode)
|
|
7357
|
+
? 7
|
|
7358
|
+
: 4;
|
|
7066
7359
|
}
|
|
7067
|
-
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7360
|
+
HEAP8[pbuf] = type;
|
|
7361
|
+
HEAP16[(pbuf + 2) >> 1] = flags;
|
|
7362
|
+
HEAP64[(pbuf + 8) >> 3] = BigInt(rightsBase);
|
|
7363
|
+
HEAP64[(pbuf + 16) >> 3] = BigInt(rightsInheriting);
|
|
7364
|
+
return 0;
|
|
7365
|
+
} catch (e) {
|
|
7366
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
7367
|
+
return e.errno;
|
|
7368
|
+
}
|
|
7369
|
+
}
|
|
7370
|
+
|
|
7371
|
+
/** @param {number=} offset */ var doReadv = (
|
|
7372
|
+
stream,
|
|
7373
|
+
iov,
|
|
7374
|
+
iovcnt,
|
|
7375
|
+
offset
|
|
7376
|
+
) => {
|
|
7377
|
+
var ret = 0;
|
|
7378
|
+
for (var i = 0; i < iovcnt; i++) {
|
|
7379
|
+
var ptr = HEAPU32[iov >> 2];
|
|
7380
|
+
var len = HEAPU32[(iov + 4) >> 2];
|
|
7381
|
+
iov += 8;
|
|
7382
|
+
var curr = FS.read(stream, HEAP8, ptr, len, offset);
|
|
7383
|
+
if (curr < 0) return -1;
|
|
7384
|
+
ret += curr;
|
|
7385
|
+
if (curr < len) break;
|
|
7386
|
+
// nothing more to read
|
|
7387
|
+
if (typeof offset != 'undefined') {
|
|
7388
|
+
offset += curr;
|
|
7075
7389
|
}
|
|
7076
|
-
|
|
7077
|
-
|
|
7078
|
-
|
|
7079
|
-
|
|
7080
|
-
|
|
7081
|
-
|
|
7390
|
+
}
|
|
7391
|
+
return ret;
|
|
7392
|
+
};
|
|
7393
|
+
|
|
7394
|
+
function _fd_read(fd, iov, iovcnt, pnum) {
|
|
7395
|
+
try {
|
|
7396
|
+
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
7397
|
+
var num = doReadv(stream, iov, iovcnt);
|
|
7398
|
+
HEAPU32[pnum >> 2] = num;
|
|
7399
|
+
return 0;
|
|
7400
|
+
} catch (e) {
|
|
7401
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
7402
|
+
return e.errno;
|
|
7403
|
+
}
|
|
7404
|
+
}
|
|
7405
|
+
|
|
7406
|
+
function _fd_seek(fd, offset, whence, newOffset) {
|
|
7407
|
+
offset = bigintToI53Checked(offset);
|
|
7408
|
+
try {
|
|
7409
|
+
if (isNaN(offset)) return 61;
|
|
7410
|
+
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
7411
|
+
FS.llseek(stream, offset, whence);
|
|
7412
|
+
HEAP64[newOffset >> 3] = BigInt(stream.position);
|
|
7413
|
+
if (stream.getdents && offset === 0 && whence === 0)
|
|
7414
|
+
stream.getdents = null;
|
|
7415
|
+
// reset readdir state
|
|
7416
|
+
return 0;
|
|
7417
|
+
} catch (e) {
|
|
7418
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
7419
|
+
return e.errno;
|
|
7420
|
+
}
|
|
7421
|
+
}
|
|
7422
|
+
|
|
7423
|
+
/** @param {number=} offset */ var doWritev = (
|
|
7424
|
+
stream,
|
|
7425
|
+
iov,
|
|
7426
|
+
iovcnt,
|
|
7427
|
+
offset
|
|
7428
|
+
) => {
|
|
7429
|
+
var ret = 0;
|
|
7430
|
+
for (var i = 0; i < iovcnt; i++) {
|
|
7431
|
+
var ptr = HEAPU32[iov >> 2];
|
|
7432
|
+
var len = HEAPU32[(iov + 4) >> 2];
|
|
7433
|
+
iov += 8;
|
|
7434
|
+
var curr = FS.write(stream, HEAP8, ptr, len, offset);
|
|
7435
|
+
if (curr < 0) return -1;
|
|
7436
|
+
ret += curr;
|
|
7437
|
+
if (curr < len) {
|
|
7438
|
+
// No more space to write.
|
|
7439
|
+
break;
|
|
7082
7440
|
}
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
if (Module['onStderr']) {
|
|
7086
|
-
Module['onStderr'](chunk);
|
|
7087
|
-
return;
|
|
7441
|
+
if (typeof offset != 'undefined') {
|
|
7442
|
+
offset += curr;
|
|
7088
7443
|
}
|
|
7089
|
-
|
|
7090
|
-
|
|
7444
|
+
}
|
|
7445
|
+
return ret;
|
|
7446
|
+
};
|
|
7447
|
+
|
|
7448
|
+
function _fd_write(fd, iov, iovcnt, pnum) {
|
|
7449
|
+
try {
|
|
7450
|
+
var stream = SYSCALLS.getStreamFromFD(fd);
|
|
7451
|
+
var num = doWritev(stream, iov, iovcnt);
|
|
7452
|
+
HEAPU32[pnum >> 2] = num;
|
|
7453
|
+
return 0;
|
|
7454
|
+
} catch (e) {
|
|
7455
|
+
if (typeof FS == 'undefined' || !(e.name === 'ErrnoError')) throw e;
|
|
7456
|
+
return e.errno;
|
|
7457
|
+
}
|
|
7458
|
+
}
|
|
7459
|
+
|
|
7460
|
+
var _getaddrinfo = (node, service, hint, out) => {
|
|
7461
|
+
var addr = 0;
|
|
7462
|
+
var port = 0;
|
|
7463
|
+
var flags = 0;
|
|
7464
|
+
var family = 0;
|
|
7465
|
+
var type = 0;
|
|
7466
|
+
var proto = 0;
|
|
7467
|
+
var ai;
|
|
7468
|
+
function allocaddrinfo(family, type, proto, canon, addr, port) {
|
|
7469
|
+
var sa, salen, ai;
|
|
7470
|
+
var errno;
|
|
7471
|
+
salen = family === 10 ? 28 : 16;
|
|
7472
|
+
addr = family === 10 ? inetNtop6(addr) : inetNtop4(addr);
|
|
7473
|
+
sa = _malloc(salen);
|
|
7474
|
+
errno = writeSockaddr(sa, family, addr, port);
|
|
7475
|
+
assert(!errno);
|
|
7476
|
+
ai = _malloc(32);
|
|
7477
|
+
HEAP32[(ai + 4) >> 2] = family;
|
|
7478
|
+
HEAP32[(ai + 8) >> 2] = type;
|
|
7479
|
+
HEAP32[(ai + 12) >> 2] = proto;
|
|
7480
|
+
HEAPU32[(ai + 24) >> 2] = canon;
|
|
7481
|
+
HEAPU32[(ai + 20) >> 2] = sa;
|
|
7482
|
+
if (family === 10) {
|
|
7483
|
+
HEAP32[(ai + 16) >> 2] = 28;
|
|
7091
7484
|
} else {
|
|
7092
|
-
|
|
7093
|
-
chunk,
|
|
7094
|
-
});
|
|
7095
|
-
}
|
|
7096
|
-
},
|
|
7097
|
-
getAllWebSockets: function (sock) {
|
|
7098
|
-
const webSockets = new Set();
|
|
7099
|
-
if (sock.server) {
|
|
7100
|
-
sock.server.clients.forEach((ws) => {
|
|
7101
|
-
webSockets.add(ws);
|
|
7102
|
-
});
|
|
7103
|
-
}
|
|
7104
|
-
for (const peer of PHPWASM.getAllPeers(sock)) {
|
|
7105
|
-
webSockets.add(peer.socket);
|
|
7106
|
-
}
|
|
7107
|
-
return Array.from(webSockets);
|
|
7108
|
-
},
|
|
7109
|
-
getAllPeers: function (sock) {
|
|
7110
|
-
const peers = new Set();
|
|
7111
|
-
if (sock.server) {
|
|
7112
|
-
sock.pending
|
|
7113
|
-
.filter((pending) => pending.peers)
|
|
7114
|
-
.forEach((pending) => {
|
|
7115
|
-
for (const peer of Object.values(pending.peers)) {
|
|
7116
|
-
peers.add(peer);
|
|
7117
|
-
}
|
|
7118
|
-
});
|
|
7485
|
+
HEAP32[(ai + 16) >> 2] = 16;
|
|
7119
7486
|
}
|
|
7120
|
-
|
|
7121
|
-
|
|
7122
|
-
|
|
7487
|
+
HEAP32[(ai + 28) >> 2] = 0;
|
|
7488
|
+
return ai;
|
|
7489
|
+
}
|
|
7490
|
+
if (hint) {
|
|
7491
|
+
flags = HEAP32[hint >> 2];
|
|
7492
|
+
family = HEAP32[(hint + 4) >> 2];
|
|
7493
|
+
type = HEAP32[(hint + 8) >> 2];
|
|
7494
|
+
proto = HEAP32[(hint + 12) >> 2];
|
|
7495
|
+
}
|
|
7496
|
+
if (type && !proto) {
|
|
7497
|
+
proto = type === 2 ? 17 : 6;
|
|
7498
|
+
}
|
|
7499
|
+
if (!type && proto) {
|
|
7500
|
+
type = proto === 17 ? 2 : 1;
|
|
7501
|
+
}
|
|
7502
|
+
// If type or proto are set to zero in hints we should really be returning multiple addrinfo values, but for
|
|
7503
|
+
// now default to a TCP STREAM socket so we can at least return a sensible addrinfo given NULL hints.
|
|
7504
|
+
if (proto === 0) {
|
|
7505
|
+
proto = 6;
|
|
7506
|
+
}
|
|
7507
|
+
if (type === 0) {
|
|
7508
|
+
type = 1;
|
|
7509
|
+
}
|
|
7510
|
+
if (!node && !service) {
|
|
7511
|
+
return -2;
|
|
7512
|
+
}
|
|
7513
|
+
if (flags & ~(1 | 2 | 4 | 1024 | 8 | 16 | 32)) {
|
|
7514
|
+
return -1;
|
|
7515
|
+
}
|
|
7516
|
+
if (hint !== 0 && HEAP32[hint >> 2] & 2 && !node) {
|
|
7517
|
+
return -1;
|
|
7518
|
+
}
|
|
7519
|
+
if (flags & 32) {
|
|
7520
|
+
// TODO
|
|
7521
|
+
return -2;
|
|
7522
|
+
}
|
|
7523
|
+
if (type !== 0 && type !== 1 && type !== 2) {
|
|
7524
|
+
return -7;
|
|
7525
|
+
}
|
|
7526
|
+
if (family !== 0 && family !== 2 && family !== 10) {
|
|
7527
|
+
return -6;
|
|
7528
|
+
}
|
|
7529
|
+
if (service) {
|
|
7530
|
+
service = UTF8ToString(service);
|
|
7531
|
+
port = parseInt(service, 10);
|
|
7532
|
+
if (isNaN(port)) {
|
|
7533
|
+
if (flags & 1024) {
|
|
7534
|
+
return -2;
|
|
7123
7535
|
}
|
|
7536
|
+
// TODO support resolving well-known service names from:
|
|
7537
|
+
// http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt
|
|
7538
|
+
return -8;
|
|
7124
7539
|
}
|
|
7125
|
-
|
|
7126
|
-
|
|
7127
|
-
|
|
7128
|
-
|
|
7129
|
-
|
|
7130
|
-
|
|
7131
|
-
|
|
7132
|
-
|
|
7540
|
+
}
|
|
7541
|
+
if (!node) {
|
|
7542
|
+
if (family === 0) {
|
|
7543
|
+
family = 2;
|
|
7544
|
+
}
|
|
7545
|
+
if ((flags & 1) === 0) {
|
|
7546
|
+
if (family === 2) {
|
|
7547
|
+
addr = _htonl(2130706433);
|
|
7548
|
+
} else {
|
|
7549
|
+
addr = [0, 0, 0, _htonl(1)];
|
|
7550
|
+
}
|
|
7133
7551
|
}
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7552
|
+
ai = allocaddrinfo(family, type, proto, null, addr, port);
|
|
7553
|
+
HEAPU32[out >> 2] = ai;
|
|
7554
|
+
return 0;
|
|
7555
|
+
}
|
|
7556
|
+
// try as a numeric address
|
|
7557
|
+
node = UTF8ToString(node);
|
|
7558
|
+
addr = inetPton4(node);
|
|
7559
|
+
if (addr !== null) {
|
|
7560
|
+
// incoming node is a valid ipv4 address
|
|
7561
|
+
if (family === 0 || family === 2) {
|
|
7562
|
+
family = 2;
|
|
7563
|
+
} else if (family === 10 && flags & 8) {
|
|
7564
|
+
addr = [0, 0, _htonl(65535), addr];
|
|
7565
|
+
family = 10;
|
|
7566
|
+
} else {
|
|
7567
|
+
return -2;
|
|
7139
7568
|
}
|
|
7140
|
-
|
|
7141
|
-
|
|
7142
|
-
|
|
7143
|
-
|
|
7144
|
-
|
|
7569
|
+
} else {
|
|
7570
|
+
addr = inetPton6(node);
|
|
7571
|
+
if (addr !== null) {
|
|
7572
|
+
// incoming node is a valid ipv6 address
|
|
7573
|
+
if (family === 0 || family === 10) {
|
|
7574
|
+
family = 10;
|
|
7575
|
+
} else {
|
|
7576
|
+
return -2;
|
|
7577
|
+
}
|
|
7145
7578
|
}
|
|
7146
|
-
|
|
7147
|
-
|
|
7148
|
-
|
|
7149
|
-
|
|
7150
|
-
|
|
7151
|
-
|
|
7152
|
-
|
|
7153
|
-
|
|
7154
|
-
|
|
7155
|
-
|
|
7156
|
-
|
|
7157
|
-
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
|
|
7163
|
-
|
|
7164
|
-
|
|
7165
|
-
|
|
7166
|
-
|
|
7167
|
-
|
|
7168
|
-
|
|
7169
|
-
|
|
7170
|
-
|
|
7171
|
-
|
|
7172
|
-
|
|
7173
|
-
|
|
7174
|
-
|
|
7175
|
-
|
|
7176
|
-
|
|
7177
|
-
|
|
7178
|
-
|
|
7179
|
-
|
|
7180
|
-
|
|
7181
|
-
|
|
7579
|
+
}
|
|
7580
|
+
if (addr != null) {
|
|
7581
|
+
ai = allocaddrinfo(family, type, proto, node, addr, port);
|
|
7582
|
+
HEAPU32[out >> 2] = ai;
|
|
7583
|
+
return 0;
|
|
7584
|
+
}
|
|
7585
|
+
if (flags & 4) {
|
|
7586
|
+
return -2;
|
|
7587
|
+
}
|
|
7588
|
+
// try as a hostname
|
|
7589
|
+
// resolve the hostname to a temporary fake address
|
|
7590
|
+
node = DNS.lookup_name(node);
|
|
7591
|
+
addr = inetPton4(node);
|
|
7592
|
+
if (family === 0) {
|
|
7593
|
+
family = 2;
|
|
7594
|
+
} else if (family === 10) {
|
|
7595
|
+
addr = [0, 0, _htonl(65535), addr];
|
|
7596
|
+
}
|
|
7597
|
+
ai = allocaddrinfo(family, type, proto, null, addr, port);
|
|
7598
|
+
HEAPU32[out >> 2] = ai;
|
|
7599
|
+
return 0;
|
|
7600
|
+
};
|
|
7601
|
+
|
|
7602
|
+
var _getnameinfo = (sa, salen, node, nodelen, serv, servlen, flags) => {
|
|
7603
|
+
var info = readSockaddr(sa, salen);
|
|
7604
|
+
if (info.errno) {
|
|
7605
|
+
return -6;
|
|
7606
|
+
}
|
|
7607
|
+
var port = info.port;
|
|
7608
|
+
var addr = info.addr;
|
|
7609
|
+
var overflowed = false;
|
|
7610
|
+
if (node && nodelen) {
|
|
7611
|
+
var lookup;
|
|
7612
|
+
if (flags & 1 || !(lookup = DNS.lookup_addr(addr))) {
|
|
7613
|
+
if (flags & 8) {
|
|
7614
|
+
return -2;
|
|
7615
|
+
}
|
|
7616
|
+
} else {
|
|
7617
|
+
addr = lookup;
|
|
7182
7618
|
}
|
|
7183
|
-
|
|
7184
|
-
|
|
7185
|
-
|
|
7186
|
-
shell: true,
|
|
7187
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
7188
|
-
timeout: 100,
|
|
7189
|
-
});
|
|
7619
|
+
var numBytesWrittenExclNull = stringToUTF8(addr, node, nodelen);
|
|
7620
|
+
if (numBytesWrittenExclNull + 1 >= nodelen) {
|
|
7621
|
+
overflowed = true;
|
|
7190
7622
|
}
|
|
7191
|
-
|
|
7192
|
-
|
|
7193
|
-
|
|
7194
|
-
|
|
7195
|
-
)
|
|
7196
|
-
|
|
7197
|
-
throw e;
|
|
7198
|
-
},
|
|
7199
|
-
shutdownSocket: function (socketd, how) {
|
|
7200
|
-
// This implementation only supports websockets at the moment
|
|
7201
|
-
const sock = getSocketFromFD(socketd);
|
|
7202
|
-
const peer = Object.values(sock.peers)[0];
|
|
7203
|
-
if (!peer) {
|
|
7204
|
-
return -1;
|
|
7623
|
+
}
|
|
7624
|
+
if (serv && servlen) {
|
|
7625
|
+
port = '' + port;
|
|
7626
|
+
var numBytesWrittenExclNull = stringToUTF8(port, serv, servlen);
|
|
7627
|
+
if (numBytesWrittenExclNull + 1 >= servlen) {
|
|
7628
|
+
overflowed = true;
|
|
7205
7629
|
}
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
|
|
7212
|
-
|
|
7630
|
+
}
|
|
7631
|
+
if (overflowed) {
|
|
7632
|
+
// Note: even when we overflow, getnameinfo() is specced to write out the truncated results.
|
|
7633
|
+
return -12;
|
|
7634
|
+
}
|
|
7635
|
+
return 0;
|
|
7636
|
+
};
|
|
7637
|
+
|
|
7638
|
+
var Protocols = {
|
|
7639
|
+
list: [],
|
|
7640
|
+
map: {},
|
|
7641
|
+
};
|
|
7642
|
+
|
|
7643
|
+
var _setprotoent = (stayopen) => {
|
|
7644
|
+
// void setprotoent(int stayopen);
|
|
7645
|
+
// Allocate and populate a protoent structure given a name, protocol number and array of aliases
|
|
7646
|
+
function allocprotoent(name, proto, aliases) {
|
|
7647
|
+
// write name into buffer
|
|
7648
|
+
var nameBuf = _malloc(name.length + 1);
|
|
7649
|
+
stringToAscii(name, nameBuf);
|
|
7650
|
+
// write aliases into buffer
|
|
7651
|
+
var j = 0;
|
|
7652
|
+
var length = aliases.length;
|
|
7653
|
+
var aliasListBuf = _malloc((length + 1) * 4);
|
|
7654
|
+
// Use length + 1 so we have space for the terminating NULL ptr.
|
|
7655
|
+
for (var i = 0; i < length; i++, j += 4) {
|
|
7656
|
+
var alias = aliases[i];
|
|
7657
|
+
var aliasBuf = _malloc(alias.length + 1);
|
|
7658
|
+
stringToAscii(alias, aliasBuf);
|
|
7659
|
+
HEAPU32[(aliasListBuf + j) >> 2] = aliasBuf;
|
|
7213
7660
|
}
|
|
7214
|
-
|
|
7661
|
+
HEAPU32[(aliasListBuf + j) >> 2] = 0;
|
|
7662
|
+
// Terminating NULL pointer.
|
|
7663
|
+
// generate protoent
|
|
7664
|
+
var pe = _malloc(12);
|
|
7665
|
+
HEAPU32[pe >> 2] = nameBuf;
|
|
7666
|
+
HEAPU32[(pe + 4) >> 2] = aliasListBuf;
|
|
7667
|
+
HEAP32[(pe + 8) >> 2] = proto;
|
|
7668
|
+
return pe;
|
|
7669
|
+
}
|
|
7670
|
+
// Populate the protocol 'database'. The entries are limited to tcp and udp, though it is fairly trivial
|
|
7671
|
+
// to add extra entries from /etc/protocols if desired - though not sure if that'd actually be useful.
|
|
7672
|
+
var list = Protocols.list;
|
|
7673
|
+
var map = Protocols.map;
|
|
7674
|
+
if (list.length === 0) {
|
|
7675
|
+
var entry = allocprotoent('tcp', 6, ['TCP']);
|
|
7676
|
+
list.push(entry);
|
|
7677
|
+
map['tcp'] = map['6'] = entry;
|
|
7678
|
+
entry = allocprotoent('udp', 17, ['UDP']);
|
|
7679
|
+
list.push(entry);
|
|
7680
|
+
map['udp'] = map['17'] = entry;
|
|
7681
|
+
}
|
|
7682
|
+
_setprotoent.index = 0;
|
|
7683
|
+
};
|
|
7684
|
+
|
|
7685
|
+
var _getprotobyname = (name) => {
|
|
7686
|
+
// struct protoent *getprotobyname(const char *);
|
|
7687
|
+
name = UTF8ToString(name);
|
|
7688
|
+
_setprotoent(true);
|
|
7689
|
+
var result = Protocols.map[name];
|
|
7690
|
+
return result;
|
|
7691
|
+
};
|
|
7692
|
+
|
|
7693
|
+
var _getprotobynumber = (number) => {
|
|
7694
|
+
// struct protoent *getprotobynumber(int proto);
|
|
7695
|
+
_setprotoent(true);
|
|
7696
|
+
var result = Protocols.map[number];
|
|
7697
|
+
return result;
|
|
7215
7698
|
};
|
|
7216
7699
|
|
|
7217
7700
|
function _js_create_input_device(deviceId) {
|
|
@@ -7249,6 +7732,98 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7249
7732
|
return allocateUTF8OnStack(devicePath);
|
|
7250
7733
|
}
|
|
7251
7734
|
|
|
7735
|
+
async function _js_flock(fd, op) {
|
|
7736
|
+
_js_wasm_trace('js_flock(%d, %d)', fd, op);
|
|
7737
|
+
// Emscripten does not expose these constants to JS, so we hardcode them here.
|
|
7738
|
+
// Based on
|
|
7739
|
+
// https://github.com/emscripten-core/emscripten/blob/76860cc47cef67f5712a7a03a247bc1baabf7ba4/system/lib/libc/musl/include/sys/file.h#L7-L10
|
|
7740
|
+
const emscripten_LOCK_SH = 1;
|
|
7741
|
+
const emscripten_LOCK_EX = 2;
|
|
7742
|
+
const emscripten_LOCK_NB = 4;
|
|
7743
|
+
const emscripten_LOCK_UN = 8;
|
|
7744
|
+
const flockToLockOpType = {
|
|
7745
|
+
[emscripten_LOCK_SH]: 'shared',
|
|
7746
|
+
[emscripten_LOCK_EX]: 'exclusive',
|
|
7747
|
+
[emscripten_LOCK_UN]: 'unlocked',
|
|
7748
|
+
};
|
|
7749
|
+
let vfsPath;
|
|
7750
|
+
let errno;
|
|
7751
|
+
[vfsPath, errno] = locking.get_vfs_path_from_fd(fd);
|
|
7752
|
+
if (errno !== 0) {
|
|
7753
|
+
_js_wasm_trace(
|
|
7754
|
+
'js_flock(%d, %d) get_vfs_path_from_fd errno %d',
|
|
7755
|
+
fd,
|
|
7756
|
+
op,
|
|
7757
|
+
vfsPath,
|
|
7758
|
+
errno
|
|
7759
|
+
);
|
|
7760
|
+
return -errno;
|
|
7761
|
+
}
|
|
7762
|
+
if (!locking.is_path_to_shared_fs(vfsPath)) {
|
|
7763
|
+
_js_wasm_trace(
|
|
7764
|
+
'flock(%d, %d) locking is not implemented for non-NodeFS path %s',
|
|
7765
|
+
fd,
|
|
7766
|
+
op,
|
|
7767
|
+
vfsPath
|
|
7768
|
+
);
|
|
7769
|
+
// If not a NodeFS path, we can't lock it.
|
|
7770
|
+
// Default to succeeding as Emscripten does.
|
|
7771
|
+
return 0;
|
|
7772
|
+
}
|
|
7773
|
+
errno = locking.check_lock_params(fd, op);
|
|
7774
|
+
if (errno !== 0) {
|
|
7775
|
+
_js_wasm_trace(
|
|
7776
|
+
'js_flock(%d, %d) check_lock_params errno %d',
|
|
7777
|
+
fd,
|
|
7778
|
+
op,
|
|
7779
|
+
errno
|
|
7780
|
+
);
|
|
7781
|
+
return -errno;
|
|
7782
|
+
}
|
|
7783
|
+
// @TODO: Consider supporting blocking mode of flock()
|
|
7784
|
+
if (op & (emscripten_LOCK_NB === 0)) {
|
|
7785
|
+
_js_wasm_trace(
|
|
7786
|
+
'js_flock(%d, %d) blocking mode of flock() is not implemented',
|
|
7787
|
+
fd,
|
|
7788
|
+
op
|
|
7789
|
+
);
|
|
7790
|
+
// We do not yet support the blocking form of flock().
|
|
7791
|
+
// We respond with EINVAL to indicate failure
|
|
7792
|
+
// because it is a known errno for a failed blocking flock().
|
|
7793
|
+
return -ERRNO_CODES.EINVAL;
|
|
7794
|
+
}
|
|
7795
|
+
const maskedOp =
|
|
7796
|
+
op & (emscripten_LOCK_SH | emscripten_LOCK_EX | emscripten_LOCK_UN);
|
|
7797
|
+
const lockOpType = flockToLockOpType[maskedOp];
|
|
7798
|
+
if (lockOpType === undefined) {
|
|
7799
|
+
_js_wasm_trace(
|
|
7800
|
+
'js_flock(%d, %d) invalid flock() operation',
|
|
7801
|
+
fd,
|
|
7802
|
+
op
|
|
7803
|
+
);
|
|
7804
|
+
return -ERRNO_CODES.EINVAL;
|
|
7805
|
+
}
|
|
7806
|
+
const nativeFilePath = locking.get_native_path_from_vfs_path(vfsPath);
|
|
7807
|
+
const obtainedLock = await PHPLoader.fileLockManager.lockWholeFile(
|
|
7808
|
+
nativeFilePath,
|
|
7809
|
+
{
|
|
7810
|
+
type: lockOpType,
|
|
7811
|
+
pid: PHPLoader.processId,
|
|
7812
|
+
fd,
|
|
7813
|
+
}
|
|
7814
|
+
);
|
|
7815
|
+
_js_wasm_trace(
|
|
7816
|
+
'js_flock(%d, %d) lockWholeFile %s returned %d',
|
|
7817
|
+
fd,
|
|
7818
|
+
op,
|
|
7819
|
+
vfsPath,
|
|
7820
|
+
obtainedLock
|
|
7821
|
+
);
|
|
7822
|
+
return obtainedLock ? 0 : -ERRNO_CODES.EWOULDBLOCK;
|
|
7823
|
+
}
|
|
7824
|
+
|
|
7825
|
+
_js_flock.isAsync = true;
|
|
7826
|
+
|
|
7252
7827
|
function _js_open_process(
|
|
7253
7828
|
command,
|
|
7254
7829
|
argsPtr,
|
|
@@ -7521,6 +8096,21 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
7521
8096
|
return 0;
|
|
7522
8097
|
}
|
|
7523
8098
|
|
|
8099
|
+
var _js_release_file_locks = async function js_release_file_locks() {
|
|
8100
|
+
_js_wasm_trace('js_release_file_locks()');
|
|
8101
|
+
const pid = PHPLoader.processId;
|
|
8102
|
+
return await PHPLoader.fileLockManager
|
|
8103
|
+
.releaseLocksForProcess(pid)
|
|
8104
|
+
.then(() => {
|
|
8105
|
+
_js_wasm_trace('js_release_file_locks succeeded');
|
|
8106
|
+
})
|
|
8107
|
+
.catch((e) => {
|
|
8108
|
+
_js_wasm_trace('js_release_file_locks error %s', e);
|
|
8109
|
+
});
|
|
8110
|
+
};
|
|
8111
|
+
|
|
8112
|
+
_js_release_file_locks.isAsync = true;
|
|
8113
|
+
|
|
7524
8114
|
function _js_waitpid(pid, exitCodePtr) {
|
|
7525
8115
|
if (!PHPWASM.child_proc_by_pid[pid]) {
|
|
7526
8116
|
return -1;
|
|
@@ -8443,9 +9033,13 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8443
9033
|
/** @export */ getprotobyname: _getprotobyname,
|
|
8444
9034
|
/** @export */ getprotobynumber: _getprotobynumber,
|
|
8445
9035
|
/** @export */ js_create_input_device: _js_create_input_device,
|
|
9036
|
+
/** @export */ js_flock: _js_flock,
|
|
9037
|
+
/** @export */ js_getpid: _js_getpid,
|
|
8446
9038
|
/** @export */ js_open_process: _js_open_process,
|
|
8447
9039
|
/** @export */ js_process_status: _js_process_status,
|
|
9040
|
+
/** @export */ js_release_file_locks: _js_release_file_locks,
|
|
8448
9041
|
/** @export */ js_waitpid: _js_waitpid,
|
|
9042
|
+
/** @export */ js_wasm_trace: _js_wasm_trace,
|
|
8449
9043
|
/** @export */ proc_exit: _proc_exit,
|
|
8450
9044
|
/** @export */ strptime: _strptime,
|
|
8451
9045
|
/** @export */ wasm_close: _wasm_close,
|
|
@@ -8461,6 +9055,9 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8461
9055
|
|
|
8462
9056
|
var _malloc = (a0) => (_malloc = wasmExports['malloc'])(a0);
|
|
8463
9057
|
|
|
9058
|
+
var _getpid = (Module['_getpid'] = () =>
|
|
9059
|
+
(_getpid = Module['_getpid'] = wasmExports['getpid'])());
|
|
9060
|
+
|
|
8464
9061
|
var _wasm_read = (Module['_wasm_read'] = (a0, a1, a2) =>
|
|
8465
9062
|
(_wasm_read = Module['_wasm_read'] = wasmExports['wasm_read'])(
|
|
8466
9063
|
a0,
|
|
@@ -8470,6 +9067,9 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8470
9067
|
|
|
8471
9068
|
var _fflush = (a0) => (_fflush = wasmExports['fflush'])(a0);
|
|
8472
9069
|
|
|
9070
|
+
var _flock = (Module['_flock'] = (a0, a1) =>
|
|
9071
|
+
(_flock = Module['_flock'] = wasmExports['flock'])(a0, a1));
|
|
9072
|
+
|
|
8473
9073
|
var _wasm_popen = (Module['_wasm_popen'] = (a0, a1) =>
|
|
8474
9074
|
(_wasm_popen = Module['_wasm_popen'] = wasmExports['wasm_popen'])(
|
|
8475
9075
|
a0,
|
|
@@ -8584,6 +9184,16 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8584
9184
|
var _wasm_free = (Module['_wasm_free'] = (a0) =>
|
|
8585
9185
|
(_wasm_free = Module['_wasm_free'] = wasmExports['wasm_free'])(a0));
|
|
8586
9186
|
|
|
9187
|
+
var _wasm_get_end_offset = (Module['_wasm_get_end_offset'] = (a0) =>
|
|
9188
|
+
(_wasm_get_end_offset = Module['_wasm_get_end_offset'] =
|
|
9189
|
+
wasmExports['wasm_get_end_offset'])(a0));
|
|
9190
|
+
|
|
9191
|
+
var _wasm_trace = (Module['_wasm_trace'] = (a0, a1) =>
|
|
9192
|
+
(_wasm_trace = Module['_wasm_trace'] = wasmExports['wasm_trace'])(
|
|
9193
|
+
a0,
|
|
9194
|
+
a1
|
|
9195
|
+
));
|
|
9196
|
+
|
|
8587
9197
|
var ___funcs_on_exit = () =>
|
|
8588
9198
|
(___funcs_on_exit = wasmExports['__funcs_on_exit'])();
|
|
8589
9199
|
|
|
@@ -8737,6 +9347,32 @@ export function init(RuntimeName, PHPLoader) {
|
|
|
8737
9347
|
PHPLoader['free'] =
|
|
8738
9348
|
typeof _free === 'function' ? _free : PHPLoader['_wasm_free'];
|
|
8739
9349
|
|
|
9350
|
+
if (typeof NODEFS === 'object') {
|
|
9351
|
+
// We override NODEFS.createNode() to add an `isSharedFS` flag to all NODEFS
|
|
9352
|
+
// nodes. This way we can tell whether file-locking is needed and possible
|
|
9353
|
+
// for an FS node, even if wrapped with PROXYFS.
|
|
9354
|
+
const originalCreateNode = NODEFS.createNode;
|
|
9355
|
+
NODEFS.createNode = function createNodeWithSharedFlag() {
|
|
9356
|
+
const node = originalCreateNode.apply(NODEFS, arguments);
|
|
9357
|
+
node.isSharedFS = true;
|
|
9358
|
+
return node;
|
|
9359
|
+
};
|
|
9360
|
+
|
|
9361
|
+
var originalHashAddNode = FS.hashAddNode;
|
|
9362
|
+
FS.hashAddNode = function hashAddNodeIfNotSharedFS(node) {
|
|
9363
|
+
if (
|
|
9364
|
+
typeof locking === 'object' &&
|
|
9365
|
+
locking?.is_shared_fs_node(node)
|
|
9366
|
+
) {
|
|
9367
|
+
// Avoid caching shared VFS nodes so multiple instances
|
|
9368
|
+
// can access the same underlying filesystem without
|
|
9369
|
+
// conflicting caches.
|
|
9370
|
+
return;
|
|
9371
|
+
}
|
|
9372
|
+
return originalHashAddNode.apply(FS, arguments);
|
|
9373
|
+
};
|
|
9374
|
+
}
|
|
9375
|
+
|
|
8740
9376
|
return PHPLoader;
|
|
8741
9377
|
|
|
8742
9378
|
// Close the opening bracket from esm-prefix.js:
|