private async startCore()

in src/utils/InteractiveChildProcess.ts [74:137]


    private async startCore(): Promise<void> {
        this._startTime = Date.now();
        const formattedArgs: string = this._options.args.join(' ');

        const workingDirectory = this._options.workingDirectory || os.tmpdir();
        const options: cp.SpawnOptions = {
            cwd: workingDirectory,

            // Using shell=true would mean that we can pass paths that will be resolved by the shell, but since
            //   the command is run in the shell, handling errors (such as command not found) would be more indirect,
            //   coming through STDERR instead of the error event
            shell: false
        };

        this.writeLineToOutputChannel(`Starting executable: "${this._options.command}" ${formattedArgs}`);
        this._childProc = cp.spawn(this._options.command, this._options.args, options);

        this._childProc.stdout?.on('data', (data: string | Buffer) => {
            const text = data.toString();
            this._onStdOutEmitter.fire(text);
            this.writeLineToOutputChannel(text);
        });

        this._childProc.stderr?.on('data', (data: string | Buffer) => {
            const text = data.toString();
            this._onStdErrEmitter.fire(text);
            this.writeLineToOutputChannel(text, stdErrPrefix);
        });

        this._childProc.on('error', (error: unknown) => {
            const improvedError = improveError(error);
            this.setError(improvedError);
        });

        this._childProc.on('close', (code: number | null) => {
            if (isNumber(code) && code !== 0) {
                this.setError(`The process exited with code ${code}.`);
            } else if (!this._isKilling) {
                this.setError(`The process exited prematurely.`);
            }
        });

        // Wait for the process to start up
        // eslint-disable-next-line @typescript-eslint/no-misused-promises, no-async-promise-executor
        await new Promise<void>(async (resolve, reject) => {
            const started = Date.now();
            // eslint-disable-next-line no-constant-condition
            while (true) {
                if (!!this._error || this._isKilling) {
                    reject(this._error);
                    break;
                } else if (this._childProc.pid) {
                    resolve();
                    break;
                } else {
                    if (Date.now() > started + processStartupTimeout) {
                        reject("The process did not start in a timely manner");
                        break;
                    }
                    await delay(50);
                }
            }
        });
    }