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