11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { ObjectDefineProperty } = primordials; 41cb0ef41Sopenharmony_ciconst rawMethods = internalBinding('process_methods'); 51cb0ef41Sopenharmony_ciconst { 61cb0ef41Sopenharmony_ci namespace: { 71cb0ef41Sopenharmony_ci addSerializeCallback, 81cb0ef41Sopenharmony_ci isBuildingSnapshot, 91cb0ef41Sopenharmony_ci }, 101cb0ef41Sopenharmony_ci} = require('internal/v8/startup_snapshot'); 111cb0ef41Sopenharmony_ci// TODO(joyeecheung): deprecate and remove these underscore methods 121cb0ef41Sopenharmony_ciprocess._debugProcess = rawMethods._debugProcess; 131cb0ef41Sopenharmony_ciprocess._debugEnd = rawMethods._debugEnd; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_ci// See the discussion in https://github.com/nodejs/node/issues/19009 and 161cb0ef41Sopenharmony_ci// https://github.com/nodejs/node/pull/34010 for why these are no-ops. 171cb0ef41Sopenharmony_ci// Five word summary: they were broken beyond repair. 181cb0ef41Sopenharmony_ciprocess._startProfilerIdleNotifier = () => {}; 191cb0ef41Sopenharmony_ciprocess._stopProfilerIdleNotifier = () => {}; 201cb0ef41Sopenharmony_ci 211cb0ef41Sopenharmony_cifunction defineStream(name, getter) { 221cb0ef41Sopenharmony_ci ObjectDefineProperty(process, name, { 231cb0ef41Sopenharmony_ci __proto__: null, 241cb0ef41Sopenharmony_ci configurable: true, 251cb0ef41Sopenharmony_ci enumerable: true, 261cb0ef41Sopenharmony_ci get: getter, 271cb0ef41Sopenharmony_ci }); 281cb0ef41Sopenharmony_ci} 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_cidefineStream('stdout', getStdout); 311cb0ef41Sopenharmony_cidefineStream('stdin', getStdin); 321cb0ef41Sopenharmony_cidefineStream('stderr', getStderr); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci// Worker threads don't receive signals. 351cb0ef41Sopenharmony_ciconst { 361cb0ef41Sopenharmony_ci startListeningIfSignal, 371cb0ef41Sopenharmony_ci stopListeningIfSignal, 381cb0ef41Sopenharmony_ci} = require('internal/process/signal'); 391cb0ef41Sopenharmony_ciprocess.on('newListener', startListeningIfSignal); 401cb0ef41Sopenharmony_ciprocess.on('removeListener', stopListeningIfSignal); 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci// ---- keep the attachment of the wrappers above so that it's easier to ---- 431cb0ef41Sopenharmony_ci// ---- compare the setups side-by-side ----- 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ciconst { guessHandleType } = internalBinding('util'); 461cb0ef41Sopenharmony_ci 471cb0ef41Sopenharmony_cifunction createWritableStdioStream(fd) { 481cb0ef41Sopenharmony_ci let stream; 491cb0ef41Sopenharmony_ci // Note stream._type is used for test-module-load-list.js 501cb0ef41Sopenharmony_ci switch (guessHandleType(fd)) { 511cb0ef41Sopenharmony_ci case 'TTY': { 521cb0ef41Sopenharmony_ci const tty = require('tty'); 531cb0ef41Sopenharmony_ci stream = new tty.WriteStream(fd); 541cb0ef41Sopenharmony_ci stream._type = 'tty'; 551cb0ef41Sopenharmony_ci break; 561cb0ef41Sopenharmony_ci } 571cb0ef41Sopenharmony_ci 581cb0ef41Sopenharmony_ci case 'FILE': { 591cb0ef41Sopenharmony_ci const SyncWriteStream = require('internal/fs/sync_write_stream'); 601cb0ef41Sopenharmony_ci stream = new SyncWriteStream(fd, { autoClose: false }); 611cb0ef41Sopenharmony_ci stream._type = 'fs'; 621cb0ef41Sopenharmony_ci break; 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_ci case 'PIPE': 661cb0ef41Sopenharmony_ci case 'TCP': { 671cb0ef41Sopenharmony_ci const net = require('net'); 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci // If fd is already being used for the IPC channel, libuv will return 701cb0ef41Sopenharmony_ci // an error when trying to use it again. In that case, create the socket 711cb0ef41Sopenharmony_ci // using the existing handle instead of the fd. 721cb0ef41Sopenharmony_ci if (process.channel && process.channel.fd === fd) { 731cb0ef41Sopenharmony_ci const { kChannelHandle } = require('internal/child_process'); 741cb0ef41Sopenharmony_ci stream = new net.Socket({ 751cb0ef41Sopenharmony_ci handle: process[kChannelHandle], 761cb0ef41Sopenharmony_ci readable: false, 771cb0ef41Sopenharmony_ci writable: true, 781cb0ef41Sopenharmony_ci }); 791cb0ef41Sopenharmony_ci } else { 801cb0ef41Sopenharmony_ci stream = new net.Socket({ 811cb0ef41Sopenharmony_ci fd, 821cb0ef41Sopenharmony_ci readable: false, 831cb0ef41Sopenharmony_ci writable: true, 841cb0ef41Sopenharmony_ci }); 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci stream._type = 'pipe'; 881cb0ef41Sopenharmony_ci break; 891cb0ef41Sopenharmony_ci } 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_ci default: { 921cb0ef41Sopenharmony_ci // Provide a dummy black-hole output for e.g. non-console 931cb0ef41Sopenharmony_ci // Windows applications. 941cb0ef41Sopenharmony_ci const { Writable } = require('stream'); 951cb0ef41Sopenharmony_ci stream = new Writable({ 961cb0ef41Sopenharmony_ci write(buf, enc, cb) { 971cb0ef41Sopenharmony_ci cb(); 981cb0ef41Sopenharmony_ci }, 991cb0ef41Sopenharmony_ci }); 1001cb0ef41Sopenharmony_ci } 1011cb0ef41Sopenharmony_ci } 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci // For supporting legacy API we put the FD here. 1041cb0ef41Sopenharmony_ci stream.fd = fd; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci stream._isStdio = true; 1071cb0ef41Sopenharmony_ci 1081cb0ef41Sopenharmony_ci return stream; 1091cb0ef41Sopenharmony_ci} 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_cifunction dummyDestroy(err, cb) { 1121cb0ef41Sopenharmony_ci cb(err); 1131cb0ef41Sopenharmony_ci this._undestroy(); 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci // We need to emit 'close' anyway so that the closing 1161cb0ef41Sopenharmony_ci // of the stream is observable. We just make sure we 1171cb0ef41Sopenharmony_ci // are not going to do it twice. 1181cb0ef41Sopenharmony_ci // The 'close' event is needed so that finished and 1191cb0ef41Sopenharmony_ci // pipeline work correctly. 1201cb0ef41Sopenharmony_ci if (!this._writableState.emitClose) { 1211cb0ef41Sopenharmony_ci process.nextTick(() => { 1221cb0ef41Sopenharmony_ci this.emit('close'); 1231cb0ef41Sopenharmony_ci }); 1241cb0ef41Sopenharmony_ci } 1251cb0ef41Sopenharmony_ci} 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_cilet stdin; 1281cb0ef41Sopenharmony_cilet stdout; 1291cb0ef41Sopenharmony_cilet stderr; 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_cilet stdoutDestroy; 1321cb0ef41Sopenharmony_cilet stderrDestroy; 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_cifunction refreshStdoutOnSigWinch() { 1351cb0ef41Sopenharmony_ci stdout._refreshSize(); 1361cb0ef41Sopenharmony_ci} 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_cifunction refreshStderrOnSigWinch() { 1391cb0ef41Sopenharmony_ci stderr._refreshSize(); 1401cb0ef41Sopenharmony_ci} 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_cifunction addCleanup(fn) { 1431cb0ef41Sopenharmony_ci if (isBuildingSnapshot()) { 1441cb0ef41Sopenharmony_ci addSerializeCallback(fn); 1451cb0ef41Sopenharmony_ci } 1461cb0ef41Sopenharmony_ci} 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_cifunction getStdout() { 1491cb0ef41Sopenharmony_ci if (stdout) return stdout; 1501cb0ef41Sopenharmony_ci stdout = createWritableStdioStream(1); 1511cb0ef41Sopenharmony_ci stdout.destroySoon = stdout.destroy; 1521cb0ef41Sopenharmony_ci // Override _destroy so that the fd is never actually closed. 1531cb0ef41Sopenharmony_ci stdoutDestroy = stdout._destroy; 1541cb0ef41Sopenharmony_ci stdout._destroy = dummyDestroy; 1551cb0ef41Sopenharmony_ci if (stdout.isTTY) { 1561cb0ef41Sopenharmony_ci process.on('SIGWINCH', refreshStdoutOnSigWinch); 1571cb0ef41Sopenharmony_ci } 1581cb0ef41Sopenharmony_ci 1591cb0ef41Sopenharmony_ci addCleanup(function cleanupStdout() { 1601cb0ef41Sopenharmony_ci stdout._destroy = stdoutDestroy; 1611cb0ef41Sopenharmony_ci stdout.destroy(); 1621cb0ef41Sopenharmony_ci process.removeListener('SIGWINCH', refreshStdoutOnSigWinch); 1631cb0ef41Sopenharmony_ci stdout = undefined; 1641cb0ef41Sopenharmony_ci }); 1651cb0ef41Sopenharmony_ci // No need to add deserialize callback because stdout = undefined above 1661cb0ef41Sopenharmony_ci // causes the stream to be lazily initialized again later. 1671cb0ef41Sopenharmony_ci return stdout; 1681cb0ef41Sopenharmony_ci} 1691cb0ef41Sopenharmony_ci 1701cb0ef41Sopenharmony_cifunction getStderr() { 1711cb0ef41Sopenharmony_ci if (stderr) return stderr; 1721cb0ef41Sopenharmony_ci stderr = createWritableStdioStream(2); 1731cb0ef41Sopenharmony_ci stderr.destroySoon = stderr.destroy; 1741cb0ef41Sopenharmony_ci stderrDestroy = stderr._destroy; 1751cb0ef41Sopenharmony_ci // Override _destroy so that the fd is never actually closed. 1761cb0ef41Sopenharmony_ci stderr._destroy = dummyDestroy; 1771cb0ef41Sopenharmony_ci if (stderr.isTTY) { 1781cb0ef41Sopenharmony_ci process.on('SIGWINCH', refreshStderrOnSigWinch); 1791cb0ef41Sopenharmony_ci } 1801cb0ef41Sopenharmony_ci addCleanup(function cleanupStderr() { 1811cb0ef41Sopenharmony_ci stderr._destroy = stderrDestroy; 1821cb0ef41Sopenharmony_ci stderr.destroy(); 1831cb0ef41Sopenharmony_ci process.removeListener('SIGWINCH', refreshStderrOnSigWinch); 1841cb0ef41Sopenharmony_ci stderr = undefined; 1851cb0ef41Sopenharmony_ci }); 1861cb0ef41Sopenharmony_ci // No need to add deserialize callback because stderr = undefined above 1871cb0ef41Sopenharmony_ci // causes the stream to be lazily initialized again later. 1881cb0ef41Sopenharmony_ci return stderr; 1891cb0ef41Sopenharmony_ci} 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_cifunction getStdin() { 1921cb0ef41Sopenharmony_ci if (stdin) return stdin; 1931cb0ef41Sopenharmony_ci const fd = 0; 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_ci switch (guessHandleType(fd)) { 1961cb0ef41Sopenharmony_ci case 'TTY': { 1971cb0ef41Sopenharmony_ci const tty = require('tty'); 1981cb0ef41Sopenharmony_ci stdin = new tty.ReadStream(fd); 1991cb0ef41Sopenharmony_ci break; 2001cb0ef41Sopenharmony_ci } 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci case 'FILE': { 2031cb0ef41Sopenharmony_ci const fs = require('fs'); 2041cb0ef41Sopenharmony_ci stdin = new fs.ReadStream(null, { fd: fd, autoClose: false }); 2051cb0ef41Sopenharmony_ci break; 2061cb0ef41Sopenharmony_ci } 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci case 'PIPE': 2091cb0ef41Sopenharmony_ci case 'TCP': { 2101cb0ef41Sopenharmony_ci const net = require('net'); 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci // It could be that process has been started with an IPC channel 2131cb0ef41Sopenharmony_ci // sitting on fd=0, in such case the pipe for this fd is already 2141cb0ef41Sopenharmony_ci // present and creating a new one will lead to the assertion failure 2151cb0ef41Sopenharmony_ci // in libuv. 2161cb0ef41Sopenharmony_ci if (process.channel && process.channel.fd === fd) { 2171cb0ef41Sopenharmony_ci stdin = new net.Socket({ 2181cb0ef41Sopenharmony_ci handle: process.channel, 2191cb0ef41Sopenharmony_ci readable: true, 2201cb0ef41Sopenharmony_ci writable: false, 2211cb0ef41Sopenharmony_ci manualStart: true, 2221cb0ef41Sopenharmony_ci }); 2231cb0ef41Sopenharmony_ci } else { 2241cb0ef41Sopenharmony_ci stdin = new net.Socket({ 2251cb0ef41Sopenharmony_ci fd: fd, 2261cb0ef41Sopenharmony_ci readable: true, 2271cb0ef41Sopenharmony_ci writable: false, 2281cb0ef41Sopenharmony_ci manualStart: true, 2291cb0ef41Sopenharmony_ci }); 2301cb0ef41Sopenharmony_ci } 2311cb0ef41Sopenharmony_ci // Make sure the stdin can't be `.end()`-ed 2321cb0ef41Sopenharmony_ci stdin._writableState.ended = true; 2331cb0ef41Sopenharmony_ci break; 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci default: { 2371cb0ef41Sopenharmony_ci // Provide a dummy contentless input for e.g. non-console 2381cb0ef41Sopenharmony_ci // Windows applications. 2391cb0ef41Sopenharmony_ci const { Readable } = require('stream'); 2401cb0ef41Sopenharmony_ci stdin = new Readable({ read() {} }); 2411cb0ef41Sopenharmony_ci stdin.push(null); 2421cb0ef41Sopenharmony_ci } 2431cb0ef41Sopenharmony_ci } 2441cb0ef41Sopenharmony_ci 2451cb0ef41Sopenharmony_ci // For supporting legacy API we put the FD here. 2461cb0ef41Sopenharmony_ci stdin.fd = fd; 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci // `stdin` starts out life in a paused state, but node doesn't 2491cb0ef41Sopenharmony_ci // know yet. Explicitly to readStop() it to put it in the 2501cb0ef41Sopenharmony_ci // not-reading state. 2511cb0ef41Sopenharmony_ci if (stdin._handle && stdin._handle.readStop) { 2521cb0ef41Sopenharmony_ci stdin._handle.reading = false; 2531cb0ef41Sopenharmony_ci stdin._readableState.reading = false; 2541cb0ef41Sopenharmony_ci stdin._handle.readStop(); 2551cb0ef41Sopenharmony_ci } 2561cb0ef41Sopenharmony_ci 2571cb0ef41Sopenharmony_ci // If the user calls stdin.pause(), then we need to stop reading 2581cb0ef41Sopenharmony_ci // once the stream implementation does so (one nextTick later), 2591cb0ef41Sopenharmony_ci // so that the process can close down. 2601cb0ef41Sopenharmony_ci stdin.on('pause', () => { 2611cb0ef41Sopenharmony_ci process.nextTick(onpause); 2621cb0ef41Sopenharmony_ci }); 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci function onpause() { 2651cb0ef41Sopenharmony_ci if (!stdin._handle) 2661cb0ef41Sopenharmony_ci return; 2671cb0ef41Sopenharmony_ci if (stdin._handle.reading && !stdin.readableFlowing) { 2681cb0ef41Sopenharmony_ci stdin._readableState.reading = false; 2691cb0ef41Sopenharmony_ci stdin._handle.reading = false; 2701cb0ef41Sopenharmony_ci stdin._handle.readStop(); 2711cb0ef41Sopenharmony_ci } 2721cb0ef41Sopenharmony_ci } 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci addCleanup(function cleanupStdin() { 2751cb0ef41Sopenharmony_ci stdin.destroy(); 2761cb0ef41Sopenharmony_ci stdin = undefined; 2771cb0ef41Sopenharmony_ci }); 2781cb0ef41Sopenharmony_ci // No need to add deserialize callback because stdin = undefined above 2791cb0ef41Sopenharmony_ci // causes the stream to be lazily initialized again later. 2801cb0ef41Sopenharmony_ci return stdin; 2811cb0ef41Sopenharmony_ci} 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci// Used by internal tests. 2841cb0ef41Sopenharmony_cirawMethods.resetStdioForTesting = function() { 2851cb0ef41Sopenharmony_ci stdin = undefined; 2861cb0ef41Sopenharmony_ci stdout = undefined; 2871cb0ef41Sopenharmony_ci stderr = undefined; 2881cb0ef41Sopenharmony_ci}; 2891cb0ef41Sopenharmony_ci 2901cb0ef41Sopenharmony_ci// Needed by the module loader and generally needed everywhere. 2911cb0ef41Sopenharmony_cirequire('fs'); 2921cb0ef41Sopenharmony_cirequire('util'); 2931cb0ef41Sopenharmony_cirequire('url'); 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_cirequire('internal/modules/cjs/loader'); 2961cb0ef41Sopenharmony_cirequire('internal/modules/esm/utils'); 2971cb0ef41Sopenharmony_cirequire('internal/vm/module'); 2981cb0ef41Sopenharmony_ci// Needed to refresh the time origin. 2991cb0ef41Sopenharmony_cirequire('internal/perf/utils'); 3001cb0ef41Sopenharmony_ci// Needed to register the async hooks. 3011cb0ef41Sopenharmony_ciif (internalBinding('config').hasInspector) { 3021cb0ef41Sopenharmony_ci require('internal/inspector_async_hook'); 3031cb0ef41Sopenharmony_ci} 3041cb0ef41Sopenharmony_ci// Needed to set the wasm web API callbacks. 3051cb0ef41Sopenharmony_ciinternalBinding('wasm_web_api'); 3061cb0ef41Sopenharmony_ci// Needed to detect whether it's on main thread. 3071cb0ef41Sopenharmony_ciinternalBinding('worker'); 3081cb0ef41Sopenharmony_ci// Needed by most execution modes. 3091cb0ef41Sopenharmony_cirequire('internal/modules/run_main'); 3101cb0ef41Sopenharmony_ci// Needed to refresh DNS configurations. 3111cb0ef41Sopenharmony_cirequire('internal/dns/utils'); 3121cb0ef41Sopenharmony_ci// Needed by almost all execution modes. It's fine to 3131cb0ef41Sopenharmony_ci// load them into the snapshot as long as we don't run 3141cb0ef41Sopenharmony_ci// any of the initialization. 3151cb0ef41Sopenharmony_cirequire('internal/process/pre_execution'); 316