start method

  1. @override
Future<ShellSession> start(
  1. ShellRequest request
)
override

Starts a session for request, returning a live ShellSession.

May throw if the command is invalid or the node is at capacity; the node runtime translates failures into a node.session.rejected message.

Implementation

@override
Future<ShellSession> start(ShellRequest request) async {
  final spec = request.pty;
  if (spec == null || !Platform.isWindows) {
    return fallback.start(request);
  }

  // The system and user variables as the registry holds them now, not as
  // they were when the node started (see `live_environment`), with the
  // profile over them: the environment the session gets.
  final live = liveProcessEnvironment();
  final env = mergeEnvironment([
    live,
    baseEnvironmentFor?.call(live) ?? baseEnvironment,
  ]);
  // Bash and the winpty.dll beside it, resolved per session from that
  // environment's `PATH` (both cached until it changes): a Git install added,
  // moved or removed while the node runs is followed, and the DLL always
  // matches the bash it drives. Without them this session uses pipes.
  final bash = resolveWindowsBash(environment: env);
  final dll = bash == null ? null : _winptyDllFor(bash);
  if (bash == null || dll == null || _failedDlls.contains(dll)) {
    return _fallBack(request, env);
  }

  if (allowCommand != null && !allowCommand!(request)) {
    throw ProcessException(
      request.command ?? defaultShell,
      request.args,
      'Command not permitted by node policy',
    );
  }

  try {
    return _spawn(request, spec, env, bash, dll);
  } on _ChildSpawnError catch (e) {
    // This request's child could not start; winpty itself is fine, so it
    // stays in use for later sessions.
    onWarning?.call('winpty could not start this session, using pipes: $e');
    return _fallBack(request, env);
  } on Object catch (e) {
    // Stop using this winpty for the rest of the process and fall back so the
    // session still works (with env-var geometry) instead of being rejected.
    _failedDlls.add(dll);
    onWarning?.call(
      'winpty PTY backend unavailable, using pipe fallback: $e',
    );
    return _fallBack(request, env);
  }
}