11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci ArrayIsArray, 51cb0ef41Sopenharmony_ci ArrayPrototypePush, 61cb0ef41Sopenharmony_ci ArrayPrototypeReduce, 71cb0ef41Sopenharmony_ci ArrayPrototypeSlice, 81cb0ef41Sopenharmony_ci FunctionPrototype, 91cb0ef41Sopenharmony_ci FunctionPrototypeCall, 101cb0ef41Sopenharmony_ci ObjectDefineProperty, 111cb0ef41Sopenharmony_ci ObjectSetPrototypeOf, 121cb0ef41Sopenharmony_ci ReflectApply, 131cb0ef41Sopenharmony_ci StringPrototypeSlice, 141cb0ef41Sopenharmony_ci Symbol, 151cb0ef41Sopenharmony_ci SymbolDispose, 161cb0ef41Sopenharmony_ci Uint8Array, 171cb0ef41Sopenharmony_ci} = primordials; 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciconst { 201cb0ef41Sopenharmony_ci errnoException, 211cb0ef41Sopenharmony_ci codes: { 221cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 231cb0ef41Sopenharmony_ci ERR_INVALID_ARG_VALUE, 241cb0ef41Sopenharmony_ci ERR_INVALID_HANDLE_TYPE, 251cb0ef41Sopenharmony_ci ERR_INVALID_SYNC_FORK_INPUT, 261cb0ef41Sopenharmony_ci ERR_IPC_CHANNEL_CLOSED, 271cb0ef41Sopenharmony_ci ERR_IPC_DISCONNECTED, 281cb0ef41Sopenharmony_ci ERR_IPC_ONE_PIPE, 291cb0ef41Sopenharmony_ci ERR_IPC_SYNC_FORK, 301cb0ef41Sopenharmony_ci ERR_MISSING_ARGS, 311cb0ef41Sopenharmony_ci }, 321cb0ef41Sopenharmony_ci} = require('internal/errors'); 331cb0ef41Sopenharmony_ciconst { 341cb0ef41Sopenharmony_ci validateArray, 351cb0ef41Sopenharmony_ci validateObject, 361cb0ef41Sopenharmony_ci validateOneOf, 371cb0ef41Sopenharmony_ci validateString, 381cb0ef41Sopenharmony_ci} = require('internal/validators'); 391cb0ef41Sopenharmony_ciconst EventEmitter = require('events'); 401cb0ef41Sopenharmony_ciconst net = require('net'); 411cb0ef41Sopenharmony_ciconst dgram = require('dgram'); 421cb0ef41Sopenharmony_ciconst inspect = require('internal/util/inspect').inspect; 431cb0ef41Sopenharmony_ciconst assert = require('internal/assert'); 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ciconst { Process } = internalBinding('process_wrap'); 461cb0ef41Sopenharmony_ciconst { 471cb0ef41Sopenharmony_ci WriteWrap, 481cb0ef41Sopenharmony_ci kReadBytesOrError, 491cb0ef41Sopenharmony_ci kArrayBufferOffset, 501cb0ef41Sopenharmony_ci kLastWriteWasAsync, 511cb0ef41Sopenharmony_ci streamBaseState, 521cb0ef41Sopenharmony_ci} = internalBinding('stream_wrap'); 531cb0ef41Sopenharmony_ciconst { Pipe, constants: PipeConstants } = internalBinding('pipe_wrap'); 541cb0ef41Sopenharmony_ciconst { TCP } = internalBinding('tcp_wrap'); 551cb0ef41Sopenharmony_ciconst { TTY } = internalBinding('tty_wrap'); 561cb0ef41Sopenharmony_ciconst { UDP } = internalBinding('udp_wrap'); 571cb0ef41Sopenharmony_ciconst SocketList = require('internal/socket_list'); 581cb0ef41Sopenharmony_ciconst { owner_symbol } = require('internal/async_hooks').symbols; 591cb0ef41Sopenharmony_ciconst { convertToValidSignal, deprecate } = require('internal/util'); 601cb0ef41Sopenharmony_ciconst { isArrayBufferView } = require('internal/util/types'); 611cb0ef41Sopenharmony_ciconst spawn_sync = internalBinding('spawn_sync'); 621cb0ef41Sopenharmony_ciconst { kStateSymbol } = require('internal/dgram'); 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ciconst { 651cb0ef41Sopenharmony_ci UV_EACCES, 661cb0ef41Sopenharmony_ci UV_EAGAIN, 671cb0ef41Sopenharmony_ci UV_EINVAL, 681cb0ef41Sopenharmony_ci UV_EMFILE, 691cb0ef41Sopenharmony_ci UV_ENFILE, 701cb0ef41Sopenharmony_ci UV_ENOENT, 711cb0ef41Sopenharmony_ci UV_ENOSYS, 721cb0ef41Sopenharmony_ci UV_ESRCH, 731cb0ef41Sopenharmony_ci} = internalBinding('uv'); 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ciconst { SocketListSend, SocketListReceive } = SocketList; 761cb0ef41Sopenharmony_ci 771cb0ef41Sopenharmony_ci// Lazy loaded for startup performance and to allow monkey patching of 781cb0ef41Sopenharmony_ci// internalBinding('http_parser').HTTPParser. 791cb0ef41Sopenharmony_cilet freeParser; 801cb0ef41Sopenharmony_cilet HTTPParser; 811cb0ef41Sopenharmony_ci 821cb0ef41Sopenharmony_ciconst MAX_HANDLE_RETRANSMISSIONS = 3; 831cb0ef41Sopenharmony_ciconst kChannelHandle = Symbol('kChannelHandle'); 841cb0ef41Sopenharmony_ciconst kIsUsedAsStdio = Symbol('kIsUsedAsStdio'); 851cb0ef41Sopenharmony_ciconst kPendingMessages = Symbol('kPendingMessages'); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci// This object contain function to convert TCP objects to native handle objects 881cb0ef41Sopenharmony_ci// and back again. 891cb0ef41Sopenharmony_ciconst handleConversion = { 901cb0ef41Sopenharmony_ci 'net.Native': { 911cb0ef41Sopenharmony_ci simultaneousAccepts: true, 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci send(message, handle, options) { 941cb0ef41Sopenharmony_ci return handle; 951cb0ef41Sopenharmony_ci }, 961cb0ef41Sopenharmony_ci 971cb0ef41Sopenharmony_ci got(message, handle, emit) { 981cb0ef41Sopenharmony_ci emit(handle); 991cb0ef41Sopenharmony_ci }, 1001cb0ef41Sopenharmony_ci }, 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci 'net.Server': { 1031cb0ef41Sopenharmony_ci simultaneousAccepts: true, 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci send(message, server, options) { 1061cb0ef41Sopenharmony_ci return server._handle; 1071cb0ef41Sopenharmony_ci }, 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci got(message, handle, emit) { 1101cb0ef41Sopenharmony_ci const server = new net.Server(); 1111cb0ef41Sopenharmony_ci server.listen(handle, () => { 1121cb0ef41Sopenharmony_ci emit(server); 1131cb0ef41Sopenharmony_ci }); 1141cb0ef41Sopenharmony_ci }, 1151cb0ef41Sopenharmony_ci }, 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ci 'net.Socket': { 1181cb0ef41Sopenharmony_ci send(message, socket, options) { 1191cb0ef41Sopenharmony_ci if (!socket._handle) 1201cb0ef41Sopenharmony_ci return; 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci // If the socket was created by net.Server 1231cb0ef41Sopenharmony_ci if (socket.server) { 1241cb0ef41Sopenharmony_ci // The worker should keep track of the socket 1251cb0ef41Sopenharmony_ci message.key = socket.server._connectionKey; 1261cb0ef41Sopenharmony_ci 1271cb0ef41Sopenharmony_ci const firstTime = !this[kChannelHandle].sockets.send[message.key]; 1281cb0ef41Sopenharmony_ci const socketList = getSocketList('send', this, message.key); 1291cb0ef41Sopenharmony_ci 1301cb0ef41Sopenharmony_ci // The server should no longer expose a .connection property 1311cb0ef41Sopenharmony_ci // and when asked to close it should query the socket status from 1321cb0ef41Sopenharmony_ci // the workers 1331cb0ef41Sopenharmony_ci if (firstTime) socket.server._setupWorker(socketList); 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci // Act like socket is detached 1361cb0ef41Sopenharmony_ci if (!options.keepOpen) 1371cb0ef41Sopenharmony_ci socket.server._connections--; 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci const handle = socket._handle; 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci // Remove handle from socket object, it will be closed when the socket 1431cb0ef41Sopenharmony_ci // will be sent 1441cb0ef41Sopenharmony_ci if (!options.keepOpen) { 1451cb0ef41Sopenharmony_ci handle.onread = nop; 1461cb0ef41Sopenharmony_ci socket._handle = null; 1471cb0ef41Sopenharmony_ci socket.setTimeout(0); 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci if (freeParser === undefined) 1501cb0ef41Sopenharmony_ci freeParser = require('_http_common').freeParser; 1511cb0ef41Sopenharmony_ci if (HTTPParser === undefined) 1521cb0ef41Sopenharmony_ci HTTPParser = require('_http_common').HTTPParser; 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci // In case of an HTTP connection socket, release the associated 1551cb0ef41Sopenharmony_ci // resources 1561cb0ef41Sopenharmony_ci if (socket.parser && socket.parser instanceof HTTPParser) { 1571cb0ef41Sopenharmony_ci freeParser(socket.parser, null, socket); 1581cb0ef41Sopenharmony_ci if (socket._httpMessage) 1591cb0ef41Sopenharmony_ci socket._httpMessage.detachSocket(socket); 1601cb0ef41Sopenharmony_ci } 1611cb0ef41Sopenharmony_ci } 1621cb0ef41Sopenharmony_ci 1631cb0ef41Sopenharmony_ci return handle; 1641cb0ef41Sopenharmony_ci }, 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci postSend(message, handle, options, callback, target) { 1671cb0ef41Sopenharmony_ci // Store the handle after successfully sending it, so it can be closed 1681cb0ef41Sopenharmony_ci // when the NODE_HANDLE_ACK is received. If the handle could not be sent, 1691cb0ef41Sopenharmony_ci // just close it. 1701cb0ef41Sopenharmony_ci if (handle && !options.keepOpen) { 1711cb0ef41Sopenharmony_ci if (target) { 1721cb0ef41Sopenharmony_ci // There can only be one _pendingMessage as passing handles are 1731cb0ef41Sopenharmony_ci // processed one at a time: handles are stored in _handleQueue while 1741cb0ef41Sopenharmony_ci // waiting for the NODE_HANDLE_ACK of the current passing handle. 1751cb0ef41Sopenharmony_ci assert(!target._pendingMessage); 1761cb0ef41Sopenharmony_ci target._pendingMessage = 1771cb0ef41Sopenharmony_ci { callback, message, handle, options, retransmissions: 0 }; 1781cb0ef41Sopenharmony_ci } else { 1791cb0ef41Sopenharmony_ci handle.close(); 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci } 1821cb0ef41Sopenharmony_ci }, 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci got(message, handle, emit) { 1851cb0ef41Sopenharmony_ci const socket = new net.Socket({ 1861cb0ef41Sopenharmony_ci handle: handle, 1871cb0ef41Sopenharmony_ci readable: true, 1881cb0ef41Sopenharmony_ci writable: true, 1891cb0ef41Sopenharmony_ci }); 1901cb0ef41Sopenharmony_ci 1911cb0ef41Sopenharmony_ci // If the socket was created by net.Server we will track the socket 1921cb0ef41Sopenharmony_ci if (message.key) { 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci // Add socket to connections list 1951cb0ef41Sopenharmony_ci const socketList = getSocketList('got', this, message.key); 1961cb0ef41Sopenharmony_ci socketList.add({ 1971cb0ef41Sopenharmony_ci socket: socket, 1981cb0ef41Sopenharmony_ci }); 1991cb0ef41Sopenharmony_ci } 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci emit(socket); 2021cb0ef41Sopenharmony_ci }, 2031cb0ef41Sopenharmony_ci }, 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_ci 'dgram.Native': { 2061cb0ef41Sopenharmony_ci simultaneousAccepts: false, 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci send(message, handle, options) { 2091cb0ef41Sopenharmony_ci return handle; 2101cb0ef41Sopenharmony_ci }, 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci got(message, handle, emit) { 2131cb0ef41Sopenharmony_ci emit(handle); 2141cb0ef41Sopenharmony_ci }, 2151cb0ef41Sopenharmony_ci }, 2161cb0ef41Sopenharmony_ci 2171cb0ef41Sopenharmony_ci 'dgram.Socket': { 2181cb0ef41Sopenharmony_ci simultaneousAccepts: false, 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci send(message, socket, options) { 2211cb0ef41Sopenharmony_ci message.dgramType = socket.type; 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci return socket[kStateSymbol].handle; 2241cb0ef41Sopenharmony_ci }, 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci got(message, handle, emit) { 2271cb0ef41Sopenharmony_ci const socket = new dgram.Socket(message.dgramType); 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci socket.bind(handle, () => { 2301cb0ef41Sopenharmony_ci emit(socket); 2311cb0ef41Sopenharmony_ci }); 2321cb0ef41Sopenharmony_ci }, 2331cb0ef41Sopenharmony_ci }, 2341cb0ef41Sopenharmony_ci}; 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_cifunction stdioStringToArray(stdio, channel) { 2371cb0ef41Sopenharmony_ci const options = []; 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci switch (stdio) { 2401cb0ef41Sopenharmony_ci case 'ignore': 2411cb0ef41Sopenharmony_ci case 'overlapped': 2421cb0ef41Sopenharmony_ci case 'pipe': ArrayPrototypePush(options, stdio, stdio, stdio); break; 2431cb0ef41Sopenharmony_ci case 'inherit': ArrayPrototypePush(options, 0, 1, 2); break; 2441cb0ef41Sopenharmony_ci default: 2451cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('stdio', stdio); 2461cb0ef41Sopenharmony_ci } 2471cb0ef41Sopenharmony_ci 2481cb0ef41Sopenharmony_ci if (channel) ArrayPrototypePush(options, channel); 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci return options; 2511cb0ef41Sopenharmony_ci} 2521cb0ef41Sopenharmony_ci 2531cb0ef41Sopenharmony_cifunction ChildProcess() { 2541cb0ef41Sopenharmony_ci FunctionPrototypeCall(EventEmitter, this); 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci this._closesNeeded = 1; 2571cb0ef41Sopenharmony_ci this._closesGot = 0; 2581cb0ef41Sopenharmony_ci this.connected = false; 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci this.signalCode = null; 2611cb0ef41Sopenharmony_ci this.exitCode = null; 2621cb0ef41Sopenharmony_ci this.killed = false; 2631cb0ef41Sopenharmony_ci this.spawnfile = null; 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ci this._handle = new Process(); 2661cb0ef41Sopenharmony_ci this._handle[owner_symbol] = this; 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci this._handle.onexit = (exitCode, signalCode) => { 2691cb0ef41Sopenharmony_ci if (signalCode) { 2701cb0ef41Sopenharmony_ci this.signalCode = signalCode; 2711cb0ef41Sopenharmony_ci } else { 2721cb0ef41Sopenharmony_ci this.exitCode = exitCode; 2731cb0ef41Sopenharmony_ci } 2741cb0ef41Sopenharmony_ci 2751cb0ef41Sopenharmony_ci if (this.stdin) { 2761cb0ef41Sopenharmony_ci this.stdin.destroy(); 2771cb0ef41Sopenharmony_ci } 2781cb0ef41Sopenharmony_ci 2791cb0ef41Sopenharmony_ci this._handle.close(); 2801cb0ef41Sopenharmony_ci this._handle = null; 2811cb0ef41Sopenharmony_ci 2821cb0ef41Sopenharmony_ci if (exitCode < 0) { 2831cb0ef41Sopenharmony_ci const syscall = this.spawnfile ? 'spawn ' + this.spawnfile : 'spawn'; 2841cb0ef41Sopenharmony_ci const err = errnoException(exitCode, syscall); 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci if (this.spawnfile) 2871cb0ef41Sopenharmony_ci err.path = this.spawnfile; 2881cb0ef41Sopenharmony_ci 2891cb0ef41Sopenharmony_ci err.spawnargs = ArrayPrototypeSlice(this.spawnargs, 1); 2901cb0ef41Sopenharmony_ci this.emit('error', err); 2911cb0ef41Sopenharmony_ci } else { 2921cb0ef41Sopenharmony_ci this.emit('exit', this.exitCode, this.signalCode); 2931cb0ef41Sopenharmony_ci } 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci // If any of the stdio streams have not been touched, 2961cb0ef41Sopenharmony_ci // then pull all the data through so that it can get the 2971cb0ef41Sopenharmony_ci // eof and emit a 'close' event. 2981cb0ef41Sopenharmony_ci // Do it on nextTick so that the user has one last chance 2991cb0ef41Sopenharmony_ci // to consume the output, if for example they only want to 3001cb0ef41Sopenharmony_ci // start reading the data once the process exits. 3011cb0ef41Sopenharmony_ci process.nextTick(flushStdio, this); 3021cb0ef41Sopenharmony_ci 3031cb0ef41Sopenharmony_ci maybeClose(this); 3041cb0ef41Sopenharmony_ci }; 3051cb0ef41Sopenharmony_ci} 3061cb0ef41Sopenharmony_ciObjectSetPrototypeOf(ChildProcess.prototype, EventEmitter.prototype); 3071cb0ef41Sopenharmony_ciObjectSetPrototypeOf(ChildProcess, EventEmitter); 3081cb0ef41Sopenharmony_ci 3091cb0ef41Sopenharmony_ci 3101cb0ef41Sopenharmony_cifunction flushStdio(subprocess) { 3111cb0ef41Sopenharmony_ci const stdio = subprocess.stdio; 3121cb0ef41Sopenharmony_ci 3131cb0ef41Sopenharmony_ci if (stdio == null) return; 3141cb0ef41Sopenharmony_ci 3151cb0ef41Sopenharmony_ci for (let i = 0; i < stdio.length; i++) { 3161cb0ef41Sopenharmony_ci const stream = stdio[i]; 3171cb0ef41Sopenharmony_ci // TODO(addaleax): This doesn't necessarily account for all the ways in 3181cb0ef41Sopenharmony_ci // which data can be read from a stream, e.g. being consumed on the 3191cb0ef41Sopenharmony_ci // native layer directly as a StreamBase. 3201cb0ef41Sopenharmony_ci if (!stream || !stream.readable || stream[kIsUsedAsStdio]) { 3211cb0ef41Sopenharmony_ci continue; 3221cb0ef41Sopenharmony_ci } 3231cb0ef41Sopenharmony_ci stream.resume(); 3241cb0ef41Sopenharmony_ci } 3251cb0ef41Sopenharmony_ci} 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci 3281cb0ef41Sopenharmony_cifunction createSocket(pipe, readable) { 3291cb0ef41Sopenharmony_ci return net.Socket({ handle: pipe, readable }); 3301cb0ef41Sopenharmony_ci} 3311cb0ef41Sopenharmony_ci 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_cifunction getHandleWrapType(stream) { 3341cb0ef41Sopenharmony_ci if (stream instanceof Pipe) return 'pipe'; 3351cb0ef41Sopenharmony_ci if (stream instanceof TTY) return 'tty'; 3361cb0ef41Sopenharmony_ci if (stream instanceof TCP) return 'tcp'; 3371cb0ef41Sopenharmony_ci if (stream instanceof UDP) return 'udp'; 3381cb0ef41Sopenharmony_ci 3391cb0ef41Sopenharmony_ci return false; 3401cb0ef41Sopenharmony_ci} 3411cb0ef41Sopenharmony_ci 3421cb0ef41Sopenharmony_cifunction closePendingHandle(target) { 3431cb0ef41Sopenharmony_ci target._pendingMessage.handle.close(); 3441cb0ef41Sopenharmony_ci target._pendingMessage = null; 3451cb0ef41Sopenharmony_ci} 3461cb0ef41Sopenharmony_ci 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ciChildProcess.prototype.spawn = function(options) { 3491cb0ef41Sopenharmony_ci let i = 0; 3501cb0ef41Sopenharmony_ci 3511cb0ef41Sopenharmony_ci validateObject(options, 'options'); 3521cb0ef41Sopenharmony_ci 3531cb0ef41Sopenharmony_ci // If no `stdio` option was given - use default 3541cb0ef41Sopenharmony_ci let stdio = options.stdio || 'pipe'; 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci stdio = getValidStdio(stdio, false); 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci const ipc = stdio.ipc; 3591cb0ef41Sopenharmony_ci const ipcFd = stdio.ipcFd; 3601cb0ef41Sopenharmony_ci stdio = options.stdio = stdio.stdio; 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci validateOneOf(options.serialization, 'options.serialization', 3641cb0ef41Sopenharmony_ci [undefined, 'json', 'advanced']); 3651cb0ef41Sopenharmony_ci const serialization = options.serialization || 'json'; 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci if (ipc !== undefined) { 3681cb0ef41Sopenharmony_ci // Let child process know about opened IPC channel 3691cb0ef41Sopenharmony_ci if (options.envPairs === undefined) 3701cb0ef41Sopenharmony_ci options.envPairs = []; 3711cb0ef41Sopenharmony_ci else 3721cb0ef41Sopenharmony_ci validateArray(options.envPairs, 'options.envPairs'); 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci ArrayPrototypePush(options.envPairs, `NODE_CHANNEL_FD=${ipcFd}`); 3751cb0ef41Sopenharmony_ci ArrayPrototypePush(options.envPairs, 3761cb0ef41Sopenharmony_ci `NODE_CHANNEL_SERIALIZATION_MODE=${serialization}`); 3771cb0ef41Sopenharmony_ci } 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_ci validateString(options.file, 'options.file'); 3801cb0ef41Sopenharmony_ci this.spawnfile = options.file; 3811cb0ef41Sopenharmony_ci 3821cb0ef41Sopenharmony_ci if (options.args === undefined) { 3831cb0ef41Sopenharmony_ci this.spawnargs = []; 3841cb0ef41Sopenharmony_ci } else { 3851cb0ef41Sopenharmony_ci validateArray(options.args, 'options.args'); 3861cb0ef41Sopenharmony_ci this.spawnargs = options.args; 3871cb0ef41Sopenharmony_ci } 3881cb0ef41Sopenharmony_ci 3891cb0ef41Sopenharmony_ci const err = this._handle.spawn(options); 3901cb0ef41Sopenharmony_ci 3911cb0ef41Sopenharmony_ci // Run-time errors should emit an error, not throw an exception. 3921cb0ef41Sopenharmony_ci if (err === UV_EACCES || 3931cb0ef41Sopenharmony_ci err === UV_EAGAIN || 3941cb0ef41Sopenharmony_ci err === UV_EMFILE || 3951cb0ef41Sopenharmony_ci err === UV_ENFILE || 3961cb0ef41Sopenharmony_ci err === UV_ENOENT) { 3971cb0ef41Sopenharmony_ci process.nextTick(onErrorNT, this, err); 3981cb0ef41Sopenharmony_ci 3991cb0ef41Sopenharmony_ci // There is no point in continuing when we've hit EMFILE or ENFILE 4001cb0ef41Sopenharmony_ci // because we won't be able to set up the stdio file descriptors. 4011cb0ef41Sopenharmony_ci if (err === UV_EMFILE || err === UV_ENFILE) 4021cb0ef41Sopenharmony_ci return err; 4031cb0ef41Sopenharmony_ci } else if (err) { 4041cb0ef41Sopenharmony_ci // Close all opened fds on error 4051cb0ef41Sopenharmony_ci for (i = 0; i < stdio.length; i++) { 4061cb0ef41Sopenharmony_ci const stream = stdio[i]; 4071cb0ef41Sopenharmony_ci if (stream.type === 'pipe') { 4081cb0ef41Sopenharmony_ci stream.handle.close(); 4091cb0ef41Sopenharmony_ci } 4101cb0ef41Sopenharmony_ci } 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci this._handle.close(); 4131cb0ef41Sopenharmony_ci this._handle = null; 4141cb0ef41Sopenharmony_ci throw errnoException(err, 'spawn'); 4151cb0ef41Sopenharmony_ci } else { 4161cb0ef41Sopenharmony_ci process.nextTick(onSpawnNT, this); 4171cb0ef41Sopenharmony_ci } 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci this.pid = this._handle.pid; 4201cb0ef41Sopenharmony_ci 4211cb0ef41Sopenharmony_ci for (i = 0; i < stdio.length; i++) { 4221cb0ef41Sopenharmony_ci const stream = stdio[i]; 4231cb0ef41Sopenharmony_ci if (stream.type === 'ignore') continue; 4241cb0ef41Sopenharmony_ci 4251cb0ef41Sopenharmony_ci if (stream.ipc) { 4261cb0ef41Sopenharmony_ci this._closesNeeded++; 4271cb0ef41Sopenharmony_ci continue; 4281cb0ef41Sopenharmony_ci } 4291cb0ef41Sopenharmony_ci 4301cb0ef41Sopenharmony_ci // The stream is already cloned and piped, thus stop its readable side, 4311cb0ef41Sopenharmony_ci // otherwise we might attempt to read from the stream when at the same time 4321cb0ef41Sopenharmony_ci // the child process does. 4331cb0ef41Sopenharmony_ci if (stream.type === 'wrap') { 4341cb0ef41Sopenharmony_ci stream.handle.reading = false; 4351cb0ef41Sopenharmony_ci stream.handle.readStop(); 4361cb0ef41Sopenharmony_ci stream._stdio.pause(); 4371cb0ef41Sopenharmony_ci stream._stdio.readableFlowing = false; 4381cb0ef41Sopenharmony_ci stream._stdio._readableState.reading = false; 4391cb0ef41Sopenharmony_ci stream._stdio[kIsUsedAsStdio] = true; 4401cb0ef41Sopenharmony_ci continue; 4411cb0ef41Sopenharmony_ci } 4421cb0ef41Sopenharmony_ci 4431cb0ef41Sopenharmony_ci if (stream.handle) { 4441cb0ef41Sopenharmony_ci stream.socket = createSocket(this.pid !== 0 ? 4451cb0ef41Sopenharmony_ci stream.handle : null, i > 0); 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ci if (i > 0 && this.pid !== 0) { 4481cb0ef41Sopenharmony_ci this._closesNeeded++; 4491cb0ef41Sopenharmony_ci stream.socket.on('close', () => { 4501cb0ef41Sopenharmony_ci maybeClose(this); 4511cb0ef41Sopenharmony_ci }); 4521cb0ef41Sopenharmony_ci } 4531cb0ef41Sopenharmony_ci } 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci 4561cb0ef41Sopenharmony_ci this.stdin = stdio.length >= 1 && stdio[0].socket !== undefined ? 4571cb0ef41Sopenharmony_ci stdio[0].socket : null; 4581cb0ef41Sopenharmony_ci this.stdout = stdio.length >= 2 && stdio[1].socket !== undefined ? 4591cb0ef41Sopenharmony_ci stdio[1].socket : null; 4601cb0ef41Sopenharmony_ci this.stderr = stdio.length >= 3 && stdio[2].socket !== undefined ? 4611cb0ef41Sopenharmony_ci stdio[2].socket : null; 4621cb0ef41Sopenharmony_ci 4631cb0ef41Sopenharmony_ci this.stdio = []; 4641cb0ef41Sopenharmony_ci 4651cb0ef41Sopenharmony_ci for (i = 0; i < stdio.length; i++) 4661cb0ef41Sopenharmony_ci ArrayPrototypePush(this.stdio, 4671cb0ef41Sopenharmony_ci stdio[i].socket === undefined ? null : stdio[i].socket); 4681cb0ef41Sopenharmony_ci 4691cb0ef41Sopenharmony_ci // Add .send() method and start listening for IPC data 4701cb0ef41Sopenharmony_ci if (ipc !== undefined) setupChannel(this, ipc, serialization); 4711cb0ef41Sopenharmony_ci 4721cb0ef41Sopenharmony_ci return err; 4731cb0ef41Sopenharmony_ci}; 4741cb0ef41Sopenharmony_ci 4751cb0ef41Sopenharmony_ci 4761cb0ef41Sopenharmony_cifunction onErrorNT(self, err) { 4771cb0ef41Sopenharmony_ci self._handle.onexit(err); 4781cb0ef41Sopenharmony_ci} 4791cb0ef41Sopenharmony_ci 4801cb0ef41Sopenharmony_ci 4811cb0ef41Sopenharmony_cifunction onSpawnNT(self) { 4821cb0ef41Sopenharmony_ci self.emit('spawn'); 4831cb0ef41Sopenharmony_ci} 4841cb0ef41Sopenharmony_ci 4851cb0ef41Sopenharmony_ci 4861cb0ef41Sopenharmony_ciChildProcess.prototype.kill = function(sig) { 4871cb0ef41Sopenharmony_ci 4881cb0ef41Sopenharmony_ci const signal = sig === 0 ? sig : 4891cb0ef41Sopenharmony_ci convertToValidSignal(sig === undefined ? 'SIGTERM' : sig); 4901cb0ef41Sopenharmony_ci 4911cb0ef41Sopenharmony_ci if (this._handle) { 4921cb0ef41Sopenharmony_ci const err = this._handle.kill(signal); 4931cb0ef41Sopenharmony_ci if (err === 0) { 4941cb0ef41Sopenharmony_ci /* Success. */ 4951cb0ef41Sopenharmony_ci this.killed = true; 4961cb0ef41Sopenharmony_ci return true; 4971cb0ef41Sopenharmony_ci } 4981cb0ef41Sopenharmony_ci if (err === UV_ESRCH) { 4991cb0ef41Sopenharmony_ci /* Already dead. */ 5001cb0ef41Sopenharmony_ci } else if (err === UV_EINVAL || err === UV_ENOSYS) { 5011cb0ef41Sopenharmony_ci /* The underlying platform doesn't support this signal. */ 5021cb0ef41Sopenharmony_ci throw errnoException(err, 'kill'); 5031cb0ef41Sopenharmony_ci } else { 5041cb0ef41Sopenharmony_ci /* Other error, almost certainly EPERM. */ 5051cb0ef41Sopenharmony_ci this.emit('error', errnoException(err, 'kill')); 5061cb0ef41Sopenharmony_ci } 5071cb0ef41Sopenharmony_ci } 5081cb0ef41Sopenharmony_ci 5091cb0ef41Sopenharmony_ci /* Kill didn't succeed. */ 5101cb0ef41Sopenharmony_ci return false; 5111cb0ef41Sopenharmony_ci}; 5121cb0ef41Sopenharmony_ci 5131cb0ef41Sopenharmony_ciChildProcess.prototype[SymbolDispose] = function() { 5141cb0ef41Sopenharmony_ci if (!this.killed) { 5151cb0ef41Sopenharmony_ci this.kill(); 5161cb0ef41Sopenharmony_ci } 5171cb0ef41Sopenharmony_ci}; 5181cb0ef41Sopenharmony_ci 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ciChildProcess.prototype.ref = function() { 5211cb0ef41Sopenharmony_ci if (this._handle) this._handle.ref(); 5221cb0ef41Sopenharmony_ci}; 5231cb0ef41Sopenharmony_ci 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ciChildProcess.prototype.unref = function() { 5261cb0ef41Sopenharmony_ci if (this._handle) this._handle.unref(); 5271cb0ef41Sopenharmony_ci}; 5281cb0ef41Sopenharmony_ci 5291cb0ef41Sopenharmony_ciclass Control extends EventEmitter { 5301cb0ef41Sopenharmony_ci #channel = null; 5311cb0ef41Sopenharmony_ci #refs = 0; 5321cb0ef41Sopenharmony_ci #refExplicitlySet = false; 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci constructor(channel) { 5351cb0ef41Sopenharmony_ci super(); 5361cb0ef41Sopenharmony_ci this.#channel = channel; 5371cb0ef41Sopenharmony_ci this[kPendingMessages] = []; 5381cb0ef41Sopenharmony_ci } 5391cb0ef41Sopenharmony_ci 5401cb0ef41Sopenharmony_ci // The methods keeping track of the counter are being used to track the 5411cb0ef41Sopenharmony_ci // listener count on the child process object as well as when writes are 5421cb0ef41Sopenharmony_ci // in progress. Once the user has explicitly requested a certain state, these 5431cb0ef41Sopenharmony_ci // methods become no-ops in order to not interfere with the user's intentions. 5441cb0ef41Sopenharmony_ci refCounted() { 5451cb0ef41Sopenharmony_ci if (++this.#refs === 1 && !this.#refExplicitlySet) { 5461cb0ef41Sopenharmony_ci this.#channel.ref(); 5471cb0ef41Sopenharmony_ci } 5481cb0ef41Sopenharmony_ci } 5491cb0ef41Sopenharmony_ci 5501cb0ef41Sopenharmony_ci unrefCounted() { 5511cb0ef41Sopenharmony_ci if (--this.#refs === 0 && !this.#refExplicitlySet) { 5521cb0ef41Sopenharmony_ci this.#channel.unref(); 5531cb0ef41Sopenharmony_ci this.emit('unref'); 5541cb0ef41Sopenharmony_ci } 5551cb0ef41Sopenharmony_ci } 5561cb0ef41Sopenharmony_ci 5571cb0ef41Sopenharmony_ci ref() { 5581cb0ef41Sopenharmony_ci this.#refExplicitlySet = true; 5591cb0ef41Sopenharmony_ci this.#channel.ref(); 5601cb0ef41Sopenharmony_ci } 5611cb0ef41Sopenharmony_ci 5621cb0ef41Sopenharmony_ci unref() { 5631cb0ef41Sopenharmony_ci this.#refExplicitlySet = true; 5641cb0ef41Sopenharmony_ci this.#channel.unref(); 5651cb0ef41Sopenharmony_ci } 5661cb0ef41Sopenharmony_ci 5671cb0ef41Sopenharmony_ci get fd() { 5681cb0ef41Sopenharmony_ci return this.#channel ? this.#channel.fd : undefined; 5691cb0ef41Sopenharmony_ci } 5701cb0ef41Sopenharmony_ci} 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_ciconst channelDeprecationMsg = '_channel is deprecated. ' + 5731cb0ef41Sopenharmony_ci 'Use ChildProcess.channel instead.'; 5741cb0ef41Sopenharmony_ci 5751cb0ef41Sopenharmony_cilet serialization; 5761cb0ef41Sopenharmony_cifunction setupChannel(target, channel, serializationMode) { 5771cb0ef41Sopenharmony_ci const control = new Control(channel); 5781cb0ef41Sopenharmony_ci target.channel = control; 5791cb0ef41Sopenharmony_ci target[kChannelHandle] = channel; 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_ci ObjectDefineProperty(target, '_channel', { 5821cb0ef41Sopenharmony_ci __proto__: null, 5831cb0ef41Sopenharmony_ci get: deprecate(() => { 5841cb0ef41Sopenharmony_ci return target.channel; 5851cb0ef41Sopenharmony_ci }, channelDeprecationMsg, 'DEP0129'), 5861cb0ef41Sopenharmony_ci set: deprecate((val) => { 5871cb0ef41Sopenharmony_ci target.channel = val; 5881cb0ef41Sopenharmony_ci }, channelDeprecationMsg, 'DEP0129'), 5891cb0ef41Sopenharmony_ci configurable: true, 5901cb0ef41Sopenharmony_ci enumerable: false, 5911cb0ef41Sopenharmony_ci }); 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci target._handleQueue = null; 5941cb0ef41Sopenharmony_ci target._pendingMessage = null; 5951cb0ef41Sopenharmony_ci 5961cb0ef41Sopenharmony_ci if (serialization === undefined) 5971cb0ef41Sopenharmony_ci serialization = require('internal/child_process/serialization'); 5981cb0ef41Sopenharmony_ci const { 5991cb0ef41Sopenharmony_ci initMessageChannel, 6001cb0ef41Sopenharmony_ci parseChannelMessages, 6011cb0ef41Sopenharmony_ci writeChannelMessage, 6021cb0ef41Sopenharmony_ci } = serialization[serializationMode]; 6031cb0ef41Sopenharmony_ci 6041cb0ef41Sopenharmony_ci let pendingHandle = null; 6051cb0ef41Sopenharmony_ci initMessageChannel(channel); 6061cb0ef41Sopenharmony_ci channel.pendingHandle = null; 6071cb0ef41Sopenharmony_ci channel.onread = function(arrayBuffer) { 6081cb0ef41Sopenharmony_ci const recvHandle = channel.pendingHandle; 6091cb0ef41Sopenharmony_ci channel.pendingHandle = null; 6101cb0ef41Sopenharmony_ci if (arrayBuffer) { 6111cb0ef41Sopenharmony_ci const nread = streamBaseState[kReadBytesOrError]; 6121cb0ef41Sopenharmony_ci const offset = streamBaseState[kArrayBufferOffset]; 6131cb0ef41Sopenharmony_ci const pool = new Uint8Array(arrayBuffer, offset, nread); 6141cb0ef41Sopenharmony_ci if (recvHandle) 6151cb0ef41Sopenharmony_ci pendingHandle = recvHandle; 6161cb0ef41Sopenharmony_ci 6171cb0ef41Sopenharmony_ci for (const message of parseChannelMessages(channel, pool)) { 6181cb0ef41Sopenharmony_ci // There will be at most one NODE_HANDLE message in every chunk we 6191cb0ef41Sopenharmony_ci // read because SCM_RIGHTS messages don't get coalesced. Make sure 6201cb0ef41Sopenharmony_ci // that we deliver the handle with the right message however. 6211cb0ef41Sopenharmony_ci if (isInternal(message)) { 6221cb0ef41Sopenharmony_ci if (message.cmd === 'NODE_HANDLE') { 6231cb0ef41Sopenharmony_ci handleMessage(message, pendingHandle, true); 6241cb0ef41Sopenharmony_ci pendingHandle = null; 6251cb0ef41Sopenharmony_ci } else { 6261cb0ef41Sopenharmony_ci handleMessage(message, undefined, true); 6271cb0ef41Sopenharmony_ci } 6281cb0ef41Sopenharmony_ci } else { 6291cb0ef41Sopenharmony_ci handleMessage(message, undefined, false); 6301cb0ef41Sopenharmony_ci } 6311cb0ef41Sopenharmony_ci } 6321cb0ef41Sopenharmony_ci } else { 6331cb0ef41Sopenharmony_ci this.buffering = false; 6341cb0ef41Sopenharmony_ci target.disconnect(); 6351cb0ef41Sopenharmony_ci channel.onread = nop; 6361cb0ef41Sopenharmony_ci channel.close(); 6371cb0ef41Sopenharmony_ci target.channel = null; 6381cb0ef41Sopenharmony_ci maybeClose(target); 6391cb0ef41Sopenharmony_ci } 6401cb0ef41Sopenharmony_ci }; 6411cb0ef41Sopenharmony_ci 6421cb0ef41Sopenharmony_ci // Object where socket lists will live 6431cb0ef41Sopenharmony_ci channel.sockets = { got: {}, send: {} }; 6441cb0ef41Sopenharmony_ci 6451cb0ef41Sopenharmony_ci // Handlers will go through this 6461cb0ef41Sopenharmony_ci target.on('internalMessage', function(message, handle) { 6471cb0ef41Sopenharmony_ci // Once acknowledged - continue sending handles. 6481cb0ef41Sopenharmony_ci if (message.cmd === 'NODE_HANDLE_ACK' || 6491cb0ef41Sopenharmony_ci message.cmd === 'NODE_HANDLE_NACK') { 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci if (target._pendingMessage) { 6521cb0ef41Sopenharmony_ci if (message.cmd === 'NODE_HANDLE_ACK') { 6531cb0ef41Sopenharmony_ci closePendingHandle(target); 6541cb0ef41Sopenharmony_ci } else if (target._pendingMessage.retransmissions++ === 6551cb0ef41Sopenharmony_ci MAX_HANDLE_RETRANSMISSIONS) { 6561cb0ef41Sopenharmony_ci closePendingHandle(target); 6571cb0ef41Sopenharmony_ci process.emitWarning('Handle did not reach the receiving process ' + 6581cb0ef41Sopenharmony_ci 'correctly', 'SentHandleNotReceivedWarning'); 6591cb0ef41Sopenharmony_ci } 6601cb0ef41Sopenharmony_ci } 6611cb0ef41Sopenharmony_ci 6621cb0ef41Sopenharmony_ci assert(ArrayIsArray(target._handleQueue)); 6631cb0ef41Sopenharmony_ci const queue = target._handleQueue; 6641cb0ef41Sopenharmony_ci target._handleQueue = null; 6651cb0ef41Sopenharmony_ci 6661cb0ef41Sopenharmony_ci if (target._pendingMessage) { 6671cb0ef41Sopenharmony_ci target._send(target._pendingMessage.message, 6681cb0ef41Sopenharmony_ci target._pendingMessage.handle, 6691cb0ef41Sopenharmony_ci target._pendingMessage.options, 6701cb0ef41Sopenharmony_ci target._pendingMessage.callback); 6711cb0ef41Sopenharmony_ci } 6721cb0ef41Sopenharmony_ci 6731cb0ef41Sopenharmony_ci for (let i = 0; i < queue.length; i++) { 6741cb0ef41Sopenharmony_ci const args = queue[i]; 6751cb0ef41Sopenharmony_ci target._send(args.message, args.handle, args.options, args.callback); 6761cb0ef41Sopenharmony_ci } 6771cb0ef41Sopenharmony_ci 6781cb0ef41Sopenharmony_ci // Process a pending disconnect (if any). 6791cb0ef41Sopenharmony_ci if (!target.connected && target.channel && !target._handleQueue) 6801cb0ef41Sopenharmony_ci target._disconnect(); 6811cb0ef41Sopenharmony_ci 6821cb0ef41Sopenharmony_ci return; 6831cb0ef41Sopenharmony_ci } 6841cb0ef41Sopenharmony_ci 6851cb0ef41Sopenharmony_ci if (message.cmd !== 'NODE_HANDLE') return; 6861cb0ef41Sopenharmony_ci 6871cb0ef41Sopenharmony_ci // It is possible that the handle is not received because of some error on 6881cb0ef41Sopenharmony_ci // ancillary data reception such as MSG_CTRUNC. In this case, report the 6891cb0ef41Sopenharmony_ci // sender about it by sending a NODE_HANDLE_NACK message. 6901cb0ef41Sopenharmony_ci if (!handle) 6911cb0ef41Sopenharmony_ci return target._send({ cmd: 'NODE_HANDLE_NACK' }, null, true); 6921cb0ef41Sopenharmony_ci 6931cb0ef41Sopenharmony_ci // Acknowledge handle receival. Don't emit error events (for example if 6941cb0ef41Sopenharmony_ci // the other side has disconnected) because this call to send() is not 6951cb0ef41Sopenharmony_ci // initiated by the user and it shouldn't be fatal to be unable to ACK 6961cb0ef41Sopenharmony_ci // a message. 6971cb0ef41Sopenharmony_ci target._send({ cmd: 'NODE_HANDLE_ACK' }, null, true); 6981cb0ef41Sopenharmony_ci 6991cb0ef41Sopenharmony_ci const obj = handleConversion[message.type]; 7001cb0ef41Sopenharmony_ci 7011cb0ef41Sopenharmony_ci // Update simultaneous accepts on Windows 7021cb0ef41Sopenharmony_ci if (process.platform === 'win32') { 7031cb0ef41Sopenharmony_ci handle.setSimultaneousAccepts(false); 7041cb0ef41Sopenharmony_ci } 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_ci // Convert handle object 7071cb0ef41Sopenharmony_ci obj.got.call(this, message, handle, (handle) => { 7081cb0ef41Sopenharmony_ci handleMessage(message.msg, handle, isInternal(message.msg)); 7091cb0ef41Sopenharmony_ci }); 7101cb0ef41Sopenharmony_ci }); 7111cb0ef41Sopenharmony_ci 7121cb0ef41Sopenharmony_ci target.on('newListener', function() { 7131cb0ef41Sopenharmony_ci 7141cb0ef41Sopenharmony_ci process.nextTick(() => { 7151cb0ef41Sopenharmony_ci if (!target.channel || !target.listenerCount('message')) 7161cb0ef41Sopenharmony_ci return; 7171cb0ef41Sopenharmony_ci 7181cb0ef41Sopenharmony_ci const messages = target.channel[kPendingMessages]; 7191cb0ef41Sopenharmony_ci const { length } = messages; 7201cb0ef41Sopenharmony_ci if (!length) return; 7211cb0ef41Sopenharmony_ci 7221cb0ef41Sopenharmony_ci for (let i = 0; i < length; i++) { 7231cb0ef41Sopenharmony_ci ReflectApply(target.emit, target, messages[i]); 7241cb0ef41Sopenharmony_ci } 7251cb0ef41Sopenharmony_ci 7261cb0ef41Sopenharmony_ci target.channel[kPendingMessages] = []; 7271cb0ef41Sopenharmony_ci }); 7281cb0ef41Sopenharmony_ci }); 7291cb0ef41Sopenharmony_ci 7301cb0ef41Sopenharmony_ci target.send = function(message, handle, options, callback) { 7311cb0ef41Sopenharmony_ci if (typeof handle === 'function') { 7321cb0ef41Sopenharmony_ci callback = handle; 7331cb0ef41Sopenharmony_ci handle = undefined; 7341cb0ef41Sopenharmony_ci options = undefined; 7351cb0ef41Sopenharmony_ci } else if (typeof options === 'function') { 7361cb0ef41Sopenharmony_ci callback = options; 7371cb0ef41Sopenharmony_ci options = undefined; 7381cb0ef41Sopenharmony_ci } else if (options !== undefined) { 7391cb0ef41Sopenharmony_ci validateObject(options, 'options'); 7401cb0ef41Sopenharmony_ci } 7411cb0ef41Sopenharmony_ci 7421cb0ef41Sopenharmony_ci options = { swallowErrors: false, ...options }; 7431cb0ef41Sopenharmony_ci 7441cb0ef41Sopenharmony_ci if (this.connected) { 7451cb0ef41Sopenharmony_ci return this._send(message, handle, options, callback); 7461cb0ef41Sopenharmony_ci } 7471cb0ef41Sopenharmony_ci const ex = new ERR_IPC_CHANNEL_CLOSED(); 7481cb0ef41Sopenharmony_ci if (typeof callback === 'function') { 7491cb0ef41Sopenharmony_ci process.nextTick(callback, ex); 7501cb0ef41Sopenharmony_ci } else { 7511cb0ef41Sopenharmony_ci process.nextTick(() => this.emit('error', ex)); 7521cb0ef41Sopenharmony_ci } 7531cb0ef41Sopenharmony_ci return false; 7541cb0ef41Sopenharmony_ci }; 7551cb0ef41Sopenharmony_ci 7561cb0ef41Sopenharmony_ci target._send = function(message, handle, options, callback) { 7571cb0ef41Sopenharmony_ci assert(this.connected || this.channel); 7581cb0ef41Sopenharmony_ci 7591cb0ef41Sopenharmony_ci if (message === undefined) 7601cb0ef41Sopenharmony_ci throw new ERR_MISSING_ARGS('message'); 7611cb0ef41Sopenharmony_ci 7621cb0ef41Sopenharmony_ci // Non-serializable messages should not reach the remote 7631cb0ef41Sopenharmony_ci // end point; as any failure in the stringification there 7641cb0ef41Sopenharmony_ci // will result in error message that is weakly consumable. 7651cb0ef41Sopenharmony_ci // So perform a final check on message prior to sending. 7661cb0ef41Sopenharmony_ci if (typeof message !== 'string' && 7671cb0ef41Sopenharmony_ci typeof message !== 'object' && 7681cb0ef41Sopenharmony_ci typeof message !== 'number' && 7691cb0ef41Sopenharmony_ci typeof message !== 'boolean') { 7701cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE( 7711cb0ef41Sopenharmony_ci 'message', ['string', 'object', 'number', 'boolean'], message); 7721cb0ef41Sopenharmony_ci } 7731cb0ef41Sopenharmony_ci 7741cb0ef41Sopenharmony_ci // Support legacy function signature 7751cb0ef41Sopenharmony_ci if (typeof options === 'boolean') { 7761cb0ef41Sopenharmony_ci options = { swallowErrors: options }; 7771cb0ef41Sopenharmony_ci } 7781cb0ef41Sopenharmony_ci 7791cb0ef41Sopenharmony_ci let obj; 7801cb0ef41Sopenharmony_ci 7811cb0ef41Sopenharmony_ci // Package messages with a handle object 7821cb0ef41Sopenharmony_ci if (handle) { 7831cb0ef41Sopenharmony_ci // This message will be handled by an internalMessage event handler 7841cb0ef41Sopenharmony_ci message = { 7851cb0ef41Sopenharmony_ci cmd: 'NODE_HANDLE', 7861cb0ef41Sopenharmony_ci type: null, 7871cb0ef41Sopenharmony_ci msg: message, 7881cb0ef41Sopenharmony_ci }; 7891cb0ef41Sopenharmony_ci 7901cb0ef41Sopenharmony_ci if (handle instanceof net.Socket) { 7911cb0ef41Sopenharmony_ci message.type = 'net.Socket'; 7921cb0ef41Sopenharmony_ci } else if (handle instanceof net.Server) { 7931cb0ef41Sopenharmony_ci message.type = 'net.Server'; 7941cb0ef41Sopenharmony_ci } else if (handle instanceof TCP || handle instanceof Pipe) { 7951cb0ef41Sopenharmony_ci message.type = 'net.Native'; 7961cb0ef41Sopenharmony_ci } else if (handle instanceof dgram.Socket) { 7971cb0ef41Sopenharmony_ci message.type = 'dgram.Socket'; 7981cb0ef41Sopenharmony_ci } else if (handle instanceof UDP) { 7991cb0ef41Sopenharmony_ci message.type = 'dgram.Native'; 8001cb0ef41Sopenharmony_ci } else { 8011cb0ef41Sopenharmony_ci throw new ERR_INVALID_HANDLE_TYPE(); 8021cb0ef41Sopenharmony_ci } 8031cb0ef41Sopenharmony_ci 8041cb0ef41Sopenharmony_ci // Queue-up message and handle if we haven't received ACK yet. 8051cb0ef41Sopenharmony_ci if (this._handleQueue) { 8061cb0ef41Sopenharmony_ci ArrayPrototypePush(this._handleQueue, { 8071cb0ef41Sopenharmony_ci callback: callback, 8081cb0ef41Sopenharmony_ci handle: handle, 8091cb0ef41Sopenharmony_ci options: options, 8101cb0ef41Sopenharmony_ci message: message.msg, 8111cb0ef41Sopenharmony_ci }); 8121cb0ef41Sopenharmony_ci return this._handleQueue.length === 1; 8131cb0ef41Sopenharmony_ci } 8141cb0ef41Sopenharmony_ci 8151cb0ef41Sopenharmony_ci obj = handleConversion[message.type]; 8161cb0ef41Sopenharmony_ci 8171cb0ef41Sopenharmony_ci // convert TCP object to native handle object 8181cb0ef41Sopenharmony_ci handle = ReflectApply(handleConversion[message.type].send, 8191cb0ef41Sopenharmony_ci target, [message, handle, options]); 8201cb0ef41Sopenharmony_ci 8211cb0ef41Sopenharmony_ci // If handle was sent twice, or it is impossible to get native handle 8221cb0ef41Sopenharmony_ci // out of it - just send a text without the handle. 8231cb0ef41Sopenharmony_ci if (!handle) 8241cb0ef41Sopenharmony_ci message = message.msg; 8251cb0ef41Sopenharmony_ci 8261cb0ef41Sopenharmony_ci // Update simultaneous accepts on Windows 8271cb0ef41Sopenharmony_ci if (obj.simultaneousAccepts && process.platform === 'win32') { 8281cb0ef41Sopenharmony_ci handle.setSimultaneousAccepts(true); 8291cb0ef41Sopenharmony_ci } 8301cb0ef41Sopenharmony_ci } else if (this._handleQueue && 8311cb0ef41Sopenharmony_ci !(message && (message.cmd === 'NODE_HANDLE_ACK' || 8321cb0ef41Sopenharmony_ci message.cmd === 'NODE_HANDLE_NACK'))) { 8331cb0ef41Sopenharmony_ci // Queue request anyway to avoid out-of-order messages. 8341cb0ef41Sopenharmony_ci ArrayPrototypePush(this._handleQueue, { 8351cb0ef41Sopenharmony_ci callback: callback, 8361cb0ef41Sopenharmony_ci handle: null, 8371cb0ef41Sopenharmony_ci options: options, 8381cb0ef41Sopenharmony_ci message: message, 8391cb0ef41Sopenharmony_ci }); 8401cb0ef41Sopenharmony_ci return this._handleQueue.length === 1; 8411cb0ef41Sopenharmony_ci } 8421cb0ef41Sopenharmony_ci 8431cb0ef41Sopenharmony_ci const req = new WriteWrap(); 8441cb0ef41Sopenharmony_ci 8451cb0ef41Sopenharmony_ci const err = writeChannelMessage(channel, req, message, handle); 8461cb0ef41Sopenharmony_ci const wasAsyncWrite = streamBaseState[kLastWriteWasAsync]; 8471cb0ef41Sopenharmony_ci 8481cb0ef41Sopenharmony_ci if (err === 0) { 8491cb0ef41Sopenharmony_ci if (handle) { 8501cb0ef41Sopenharmony_ci if (!this._handleQueue) 8511cb0ef41Sopenharmony_ci this._handleQueue = []; 8521cb0ef41Sopenharmony_ci if (obj && obj.postSend) 8531cb0ef41Sopenharmony_ci obj.postSend(message, handle, options, callback, target); 8541cb0ef41Sopenharmony_ci } 8551cb0ef41Sopenharmony_ci 8561cb0ef41Sopenharmony_ci if (wasAsyncWrite) { 8571cb0ef41Sopenharmony_ci req.oncomplete = () => { 8581cb0ef41Sopenharmony_ci control.unrefCounted(); 8591cb0ef41Sopenharmony_ci if (typeof callback === 'function') 8601cb0ef41Sopenharmony_ci callback(null); 8611cb0ef41Sopenharmony_ci }; 8621cb0ef41Sopenharmony_ci control.refCounted(); 8631cb0ef41Sopenharmony_ci } else if (typeof callback === 'function') { 8641cb0ef41Sopenharmony_ci process.nextTick(callback, null); 8651cb0ef41Sopenharmony_ci } 8661cb0ef41Sopenharmony_ci } else { 8671cb0ef41Sopenharmony_ci // Cleanup handle on error 8681cb0ef41Sopenharmony_ci if (obj && obj.postSend) 8691cb0ef41Sopenharmony_ci obj.postSend(message, handle, options, callback); 8701cb0ef41Sopenharmony_ci 8711cb0ef41Sopenharmony_ci if (!options.swallowErrors) { 8721cb0ef41Sopenharmony_ci const ex = errnoException(err, 'write'); 8731cb0ef41Sopenharmony_ci if (typeof callback === 'function') { 8741cb0ef41Sopenharmony_ci process.nextTick(callback, ex); 8751cb0ef41Sopenharmony_ci } else { 8761cb0ef41Sopenharmony_ci process.nextTick(() => this.emit('error', ex)); 8771cb0ef41Sopenharmony_ci } 8781cb0ef41Sopenharmony_ci } 8791cb0ef41Sopenharmony_ci } 8801cb0ef41Sopenharmony_ci 8811cb0ef41Sopenharmony_ci /* If the primary is > 2 read() calls behind, please stop sending. */ 8821cb0ef41Sopenharmony_ci return channel.writeQueueSize < (65536 * 2); 8831cb0ef41Sopenharmony_ci }; 8841cb0ef41Sopenharmony_ci 8851cb0ef41Sopenharmony_ci // Connected will be set to false immediately when a disconnect() is 8861cb0ef41Sopenharmony_ci // requested, even though the channel might still be alive internally to 8871cb0ef41Sopenharmony_ci // process queued messages. The three states are distinguished as follows: 8881cb0ef41Sopenharmony_ci // - disconnect() never requested: channel is not null and connected 8891cb0ef41Sopenharmony_ci // is true 8901cb0ef41Sopenharmony_ci // - disconnect() requested, messages in the queue: channel is not null 8911cb0ef41Sopenharmony_ci // and connected is false 8921cb0ef41Sopenharmony_ci // - disconnect() requested, channel actually disconnected: channel is 8931cb0ef41Sopenharmony_ci // null and connected is false 8941cb0ef41Sopenharmony_ci target.connected = true; 8951cb0ef41Sopenharmony_ci 8961cb0ef41Sopenharmony_ci target.disconnect = function() { 8971cb0ef41Sopenharmony_ci if (!this.connected) { 8981cb0ef41Sopenharmony_ci this.emit('error', new ERR_IPC_DISCONNECTED()); 8991cb0ef41Sopenharmony_ci return; 9001cb0ef41Sopenharmony_ci } 9011cb0ef41Sopenharmony_ci 9021cb0ef41Sopenharmony_ci // Do not allow any new messages to be written. 9031cb0ef41Sopenharmony_ci this.connected = false; 9041cb0ef41Sopenharmony_ci 9051cb0ef41Sopenharmony_ci // If there are no queued messages, disconnect immediately. Otherwise, 9061cb0ef41Sopenharmony_ci // postpone the disconnect so that it happens internally after the 9071cb0ef41Sopenharmony_ci // queue is flushed. 9081cb0ef41Sopenharmony_ci if (!this._handleQueue) 9091cb0ef41Sopenharmony_ci this._disconnect(); 9101cb0ef41Sopenharmony_ci }; 9111cb0ef41Sopenharmony_ci 9121cb0ef41Sopenharmony_ci target._disconnect = function() { 9131cb0ef41Sopenharmony_ci assert(this.channel); 9141cb0ef41Sopenharmony_ci 9151cb0ef41Sopenharmony_ci // This marks the fact that the channel is actually disconnected. 9161cb0ef41Sopenharmony_ci this.channel = null; 9171cb0ef41Sopenharmony_ci this[kChannelHandle] = null; 9181cb0ef41Sopenharmony_ci 9191cb0ef41Sopenharmony_ci if (this._pendingMessage) 9201cb0ef41Sopenharmony_ci closePendingHandle(this); 9211cb0ef41Sopenharmony_ci 9221cb0ef41Sopenharmony_ci let fired = false; 9231cb0ef41Sopenharmony_ci function finish() { 9241cb0ef41Sopenharmony_ci if (fired) return; 9251cb0ef41Sopenharmony_ci fired = true; 9261cb0ef41Sopenharmony_ci 9271cb0ef41Sopenharmony_ci channel.close(); 9281cb0ef41Sopenharmony_ci target.emit('disconnect'); 9291cb0ef41Sopenharmony_ci } 9301cb0ef41Sopenharmony_ci 9311cb0ef41Sopenharmony_ci // If a message is being read, then wait for it to complete. 9321cb0ef41Sopenharmony_ci if (channel.buffering) { 9331cb0ef41Sopenharmony_ci this.once('message', finish); 9341cb0ef41Sopenharmony_ci this.once('internalMessage', finish); 9351cb0ef41Sopenharmony_ci 9361cb0ef41Sopenharmony_ci return; 9371cb0ef41Sopenharmony_ci } 9381cb0ef41Sopenharmony_ci 9391cb0ef41Sopenharmony_ci process.nextTick(finish); 9401cb0ef41Sopenharmony_ci }; 9411cb0ef41Sopenharmony_ci 9421cb0ef41Sopenharmony_ci function emit(event, message, handle) { 9431cb0ef41Sopenharmony_ci if ('internalMessage' === event || target.listenerCount('message')) { 9441cb0ef41Sopenharmony_ci target.emit(event, message, handle); 9451cb0ef41Sopenharmony_ci return; 9461cb0ef41Sopenharmony_ci } 9471cb0ef41Sopenharmony_ci 9481cb0ef41Sopenharmony_ci ArrayPrototypePush( 9491cb0ef41Sopenharmony_ci target.channel[kPendingMessages], 9501cb0ef41Sopenharmony_ci [event, message, handle], 9511cb0ef41Sopenharmony_ci ); 9521cb0ef41Sopenharmony_ci } 9531cb0ef41Sopenharmony_ci 9541cb0ef41Sopenharmony_ci function handleMessage(message, handle, internal) { 9551cb0ef41Sopenharmony_ci if (!target.channel) 9561cb0ef41Sopenharmony_ci return; 9571cb0ef41Sopenharmony_ci 9581cb0ef41Sopenharmony_ci const eventName = (internal ? 'internalMessage' : 'message'); 9591cb0ef41Sopenharmony_ci 9601cb0ef41Sopenharmony_ci process.nextTick(emit, eventName, message, handle); 9611cb0ef41Sopenharmony_ci } 9621cb0ef41Sopenharmony_ci 9631cb0ef41Sopenharmony_ci channel.readStart(); 9641cb0ef41Sopenharmony_ci return control; 9651cb0ef41Sopenharmony_ci} 9661cb0ef41Sopenharmony_ci 9671cb0ef41Sopenharmony_ciconst INTERNAL_PREFIX = 'NODE_'; 9681cb0ef41Sopenharmony_cifunction isInternal(message) { 9691cb0ef41Sopenharmony_ci return (message !== null && 9701cb0ef41Sopenharmony_ci typeof message === 'object' && 9711cb0ef41Sopenharmony_ci typeof message.cmd === 'string' && 9721cb0ef41Sopenharmony_ci message.cmd.length > INTERNAL_PREFIX.length && 9731cb0ef41Sopenharmony_ci StringPrototypeSlice(message.cmd, 0, INTERNAL_PREFIX.length) === 9741cb0ef41Sopenharmony_ci INTERNAL_PREFIX); 9751cb0ef41Sopenharmony_ci} 9761cb0ef41Sopenharmony_ci 9771cb0ef41Sopenharmony_ciconst nop = FunctionPrototype; 9781cb0ef41Sopenharmony_ci 9791cb0ef41Sopenharmony_cifunction getValidStdio(stdio, sync) { 9801cb0ef41Sopenharmony_ci let ipc; 9811cb0ef41Sopenharmony_ci let ipcFd; 9821cb0ef41Sopenharmony_ci 9831cb0ef41Sopenharmony_ci // Replace shortcut with an array 9841cb0ef41Sopenharmony_ci if (typeof stdio === 'string') { 9851cb0ef41Sopenharmony_ci stdio = stdioStringToArray(stdio); 9861cb0ef41Sopenharmony_ci } else if (!ArrayIsArray(stdio)) { 9871cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('stdio', stdio); 9881cb0ef41Sopenharmony_ci } 9891cb0ef41Sopenharmony_ci 9901cb0ef41Sopenharmony_ci // At least 3 stdio will be created 9911cb0ef41Sopenharmony_ci // Don't concat() a new Array() because it would be sparse, and 9921cb0ef41Sopenharmony_ci // stdio.reduce() would skip the sparse elements of stdio. 9931cb0ef41Sopenharmony_ci // See https://stackoverflow.com/a/5501711/3561 9941cb0ef41Sopenharmony_ci while (stdio.length < 3) ArrayPrototypePush(stdio, undefined); 9951cb0ef41Sopenharmony_ci 9961cb0ef41Sopenharmony_ci // Translate stdio into C++-readable form 9971cb0ef41Sopenharmony_ci // (i.e. PipeWraps or fds) 9981cb0ef41Sopenharmony_ci stdio = ArrayPrototypeReduce(stdio, (acc, stdio, i) => { 9991cb0ef41Sopenharmony_ci function cleanup() { 10001cb0ef41Sopenharmony_ci for (let i = 0; i < acc.length; i++) { 10011cb0ef41Sopenharmony_ci if ((acc[i].type === 'pipe' || acc[i].type === 'ipc') && acc[i].handle) 10021cb0ef41Sopenharmony_ci acc[i].handle.close(); 10031cb0ef41Sopenharmony_ci } 10041cb0ef41Sopenharmony_ci } 10051cb0ef41Sopenharmony_ci 10061cb0ef41Sopenharmony_ci // Defaults 10071cb0ef41Sopenharmony_ci if (stdio == null) { 10081cb0ef41Sopenharmony_ci stdio = i < 3 ? 'pipe' : 'ignore'; 10091cb0ef41Sopenharmony_ci } 10101cb0ef41Sopenharmony_ci 10111cb0ef41Sopenharmony_ci if (stdio === 'ignore') { 10121cb0ef41Sopenharmony_ci ArrayPrototypePush(acc, { type: 'ignore' }); 10131cb0ef41Sopenharmony_ci } else if (stdio === 'pipe' || stdio === 'overlapped' || 10141cb0ef41Sopenharmony_ci (typeof stdio === 'number' && stdio < 0)) { 10151cb0ef41Sopenharmony_ci const a = { 10161cb0ef41Sopenharmony_ci type: stdio === 'overlapped' ? 'overlapped' : 'pipe', 10171cb0ef41Sopenharmony_ci readable: i === 0, 10181cb0ef41Sopenharmony_ci writable: i !== 0, 10191cb0ef41Sopenharmony_ci }; 10201cb0ef41Sopenharmony_ci 10211cb0ef41Sopenharmony_ci if (!sync) 10221cb0ef41Sopenharmony_ci a.handle = new Pipe(PipeConstants.SOCKET); 10231cb0ef41Sopenharmony_ci 10241cb0ef41Sopenharmony_ci ArrayPrototypePush(acc, a); 10251cb0ef41Sopenharmony_ci } else if (stdio === 'ipc') { 10261cb0ef41Sopenharmony_ci if (sync || ipc !== undefined) { 10271cb0ef41Sopenharmony_ci // Cleanup previously created pipes 10281cb0ef41Sopenharmony_ci cleanup(); 10291cb0ef41Sopenharmony_ci if (!sync) 10301cb0ef41Sopenharmony_ci throw new ERR_IPC_ONE_PIPE(); 10311cb0ef41Sopenharmony_ci else 10321cb0ef41Sopenharmony_ci throw new ERR_IPC_SYNC_FORK(); 10331cb0ef41Sopenharmony_ci } 10341cb0ef41Sopenharmony_ci 10351cb0ef41Sopenharmony_ci ipc = new Pipe(PipeConstants.IPC); 10361cb0ef41Sopenharmony_ci ipcFd = i; 10371cb0ef41Sopenharmony_ci 10381cb0ef41Sopenharmony_ci ArrayPrototypePush(acc, { 10391cb0ef41Sopenharmony_ci type: 'pipe', 10401cb0ef41Sopenharmony_ci handle: ipc, 10411cb0ef41Sopenharmony_ci ipc: true, 10421cb0ef41Sopenharmony_ci }); 10431cb0ef41Sopenharmony_ci } else if (stdio === 'inherit') { 10441cb0ef41Sopenharmony_ci ArrayPrototypePush(acc, { 10451cb0ef41Sopenharmony_ci type: 'inherit', 10461cb0ef41Sopenharmony_ci fd: i, 10471cb0ef41Sopenharmony_ci }); 10481cb0ef41Sopenharmony_ci } else if (typeof stdio === 'number' || typeof stdio.fd === 'number') { 10491cb0ef41Sopenharmony_ci ArrayPrototypePush(acc, { 10501cb0ef41Sopenharmony_ci type: 'fd', 10511cb0ef41Sopenharmony_ci fd: typeof stdio === 'number' ? stdio : stdio.fd, 10521cb0ef41Sopenharmony_ci }); 10531cb0ef41Sopenharmony_ci } else if (getHandleWrapType(stdio) || getHandleWrapType(stdio.handle) || 10541cb0ef41Sopenharmony_ci getHandleWrapType(stdio._handle)) { 10551cb0ef41Sopenharmony_ci const handle = getHandleWrapType(stdio) ? 10561cb0ef41Sopenharmony_ci stdio : 10571cb0ef41Sopenharmony_ci getHandleWrapType(stdio.handle) ? stdio.handle : stdio._handle; 10581cb0ef41Sopenharmony_ci 10591cb0ef41Sopenharmony_ci ArrayPrototypePush(acc, { 10601cb0ef41Sopenharmony_ci type: 'wrap', 10611cb0ef41Sopenharmony_ci wrapType: getHandleWrapType(handle), 10621cb0ef41Sopenharmony_ci handle: handle, 10631cb0ef41Sopenharmony_ci _stdio: stdio, 10641cb0ef41Sopenharmony_ci }); 10651cb0ef41Sopenharmony_ci } else if (isArrayBufferView(stdio) || typeof stdio === 'string') { 10661cb0ef41Sopenharmony_ci if (!sync) { 10671cb0ef41Sopenharmony_ci cleanup(); 10681cb0ef41Sopenharmony_ci throw new ERR_INVALID_SYNC_FORK_INPUT(inspect(stdio)); 10691cb0ef41Sopenharmony_ci } 10701cb0ef41Sopenharmony_ci } else { 10711cb0ef41Sopenharmony_ci // Cleanup 10721cb0ef41Sopenharmony_ci cleanup(); 10731cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_VALUE('stdio', stdio); 10741cb0ef41Sopenharmony_ci } 10751cb0ef41Sopenharmony_ci 10761cb0ef41Sopenharmony_ci return acc; 10771cb0ef41Sopenharmony_ci }, []); 10781cb0ef41Sopenharmony_ci 10791cb0ef41Sopenharmony_ci return { stdio, ipc, ipcFd }; 10801cb0ef41Sopenharmony_ci} 10811cb0ef41Sopenharmony_ci 10821cb0ef41Sopenharmony_ci 10831cb0ef41Sopenharmony_cifunction getSocketList(type, worker, key) { 10841cb0ef41Sopenharmony_ci const sockets = worker[kChannelHandle].sockets[type]; 10851cb0ef41Sopenharmony_ci let socketList = sockets[key]; 10861cb0ef41Sopenharmony_ci if (!socketList) { 10871cb0ef41Sopenharmony_ci const Construct = type === 'send' ? SocketListSend : SocketListReceive; 10881cb0ef41Sopenharmony_ci socketList = sockets[key] = new Construct(worker, key); 10891cb0ef41Sopenharmony_ci } 10901cb0ef41Sopenharmony_ci return socketList; 10911cb0ef41Sopenharmony_ci} 10921cb0ef41Sopenharmony_ci 10931cb0ef41Sopenharmony_ci 10941cb0ef41Sopenharmony_cifunction maybeClose(subprocess) { 10951cb0ef41Sopenharmony_ci subprocess._closesGot++; 10961cb0ef41Sopenharmony_ci 10971cb0ef41Sopenharmony_ci if (subprocess._closesGot === subprocess._closesNeeded) { 10981cb0ef41Sopenharmony_ci subprocess.emit('close', subprocess.exitCode, subprocess.signalCode); 10991cb0ef41Sopenharmony_ci } 11001cb0ef41Sopenharmony_ci} 11011cb0ef41Sopenharmony_ci 11021cb0ef41Sopenharmony_cifunction spawnSync(options) { 11031cb0ef41Sopenharmony_ci const result = spawn_sync.spawn(options); 11041cb0ef41Sopenharmony_ci 11051cb0ef41Sopenharmony_ci if (result.output && options.encoding && options.encoding !== 'buffer') { 11061cb0ef41Sopenharmony_ci for (let i = 0; i < result.output.length; i++) { 11071cb0ef41Sopenharmony_ci if (!result.output[i]) 11081cb0ef41Sopenharmony_ci continue; 11091cb0ef41Sopenharmony_ci result.output[i] = result.output[i].toString(options.encoding); 11101cb0ef41Sopenharmony_ci } 11111cb0ef41Sopenharmony_ci } 11121cb0ef41Sopenharmony_ci 11131cb0ef41Sopenharmony_ci result.stdout = result.output && result.output[1]; 11141cb0ef41Sopenharmony_ci result.stderr = result.output && result.output[2]; 11151cb0ef41Sopenharmony_ci 11161cb0ef41Sopenharmony_ci if (result.error) { 11171cb0ef41Sopenharmony_ci result.error = errnoException(result.error, 'spawnSync ' + options.file); 11181cb0ef41Sopenharmony_ci result.error.path = options.file; 11191cb0ef41Sopenharmony_ci result.error.spawnargs = ArrayPrototypeSlice(options.args, 1); 11201cb0ef41Sopenharmony_ci } 11211cb0ef41Sopenharmony_ci 11221cb0ef41Sopenharmony_ci return result; 11231cb0ef41Sopenharmony_ci} 11241cb0ef41Sopenharmony_ci 11251cb0ef41Sopenharmony_cimodule.exports = { 11261cb0ef41Sopenharmony_ci ChildProcess, 11271cb0ef41Sopenharmony_ci kChannelHandle, 11281cb0ef41Sopenharmony_ci setupChannel, 11291cb0ef41Sopenharmony_ci getValidStdio, 11301cb0ef41Sopenharmony_ci stdioStringToArray, 11311cb0ef41Sopenharmony_ci spawnSync, 11321cb0ef41Sopenharmony_ci}; 1133