static NAN_METHOD()

in src/win/conpty.cc [160:234]


static NAN_METHOD(PtyStartProcess) {
  Nan::HandleScope scope;

  v8::Local<v8::Object> marshal;
  std::wstring inName, outName;
  BOOL fSuccess = FALSE;
  std::unique_ptr<wchar_t[]> mutableCommandline;
  PROCESS_INFORMATION _piClient{};

  if (info.Length() != 6 ||
      !info[0]->IsString() ||
      !info[1]->IsNumber() ||
      !info[2]->IsNumber() ||
      !info[3]->IsBoolean() ||
      !info[4]->IsString() ||
      !info[5]->IsBoolean()) {
    Nan::ThrowError("Usage: pty.startProcess(file, cols, rows, debug, pipeName, inheritCursor)");
    return;
  }

  const std::wstring filename(path_util::to_wstring(Nan::Utf8String(info[0])));
  const SHORT cols = info[1]->Uint32Value(Nan::GetCurrentContext()).FromJust();
  const SHORT rows = info[2]->Uint32Value(Nan::GetCurrentContext()).FromJust();
  const bool debug = Nan::To<bool>(info[3]).FromJust();
  const std::wstring pipeName(path_util::to_wstring(Nan::Utf8String(info[4])));
  const bool inheritCursor = Nan::To<bool>(info[5]).FromJust();

  // use environment 'Path' variable to determine location of
  // the relative path that we have recieved (e.g cmd.exe)
  std::wstring shellpath;
  if (::PathIsRelativeW(filename.c_str())) {
    shellpath = path_util::get_shell_path(filename.c_str());
  } else {
    shellpath = filename;
  }

  std::string shellpath_(shellpath.begin(), shellpath.end());

  if (shellpath.empty() || !path_util::file_exists(shellpath)) {
    std::stringstream why;
    why << "File not found: " << shellpath_;
    Nan::ThrowError(why.str().c_str());
    return;
  }

  HANDLE hIn, hOut;
  HPCON hpc;
  HRESULT hr = CreateNamedPipesAndPseudoConsole({cols, rows}, inheritCursor ? 1/*PSEUDOCONSOLE_INHERIT_CURSOR*/ : 0, &hIn, &hOut, &hpc, inName, outName, pipeName);

  // Restore default handling of ctrl+c
  SetConsoleCtrlHandler(NULL, FALSE);

  // Set return values
  marshal = Nan::New<v8::Object>();

  if (SUCCEEDED(hr)) {
    // We were able to instantiate a conpty
    const int ptyId = InterlockedIncrement(&ptyCounter);
    Nan::Set(marshal, Nan::New<v8::String>("pty").ToLocalChecked(), Nan::New<v8::Number>(ptyId));
    ptyHandles.insert(ptyHandles.end(), new pty_baton(ptyId, hIn, hOut, hpc));
  } else {
    Nan::ThrowError("Cannot launch conpty");
    return;
  }

  Nan::Set(marshal, Nan::New<v8::String>("fd").ToLocalChecked(), Nan::New<v8::Number>(-1));
  {
    std::string coninPipeNameStr(inName.begin(), inName.end());
    Nan::Set(marshal, Nan::New<v8::String>("conin").ToLocalChecked(), Nan::New<v8::String>(coninPipeNameStr).ToLocalChecked());

    std::string conoutPipeNameStr(outName.begin(), outName.end());
    Nan::Set(marshal, Nan::New<v8::String>("conout").ToLocalChecked(), Nan::New<v8::String>(conoutPipeNameStr).ToLocalChecked());
  }
  info.GetReturnValue().Set(marshal);
}