Skip to content

Environment problems => investigation and solution ? #71

@dabretin

Description

@dabretin

Hi !
First of all, thx for this wonderful work !!!

Now, there are some problems with the environment...
In fact, all the vars are passed without delimitors, soo cmd.exe can only see a big var with all the values (type SET and you'll see).

Agent read a wstring from pipe, and the serialize/unserialize process can enable us to send all the environment vars with '\0' delimitors...

First, we have to modify winpty_start_process
It's responsible to send the "start process" packet to the pipe.
It must not use a wchar_t* (because the putWString of the Buffer Class only send part before the first NULL)...
winpty.h

#include <string>
...
WINPTY_API int winpty_start_process(winpty_t *pc,
                                    const wchar_t *appname,
                                    const wchar_t *cmdline,
                                    const wchar_t *cwd,
                                    std::wstring env);

winpty.cc

WINPTY_API int winpty_start_process(winpty_t *pc,
                                    const wchar_t *appname,
                                    const wchar_t *cmdline,
                                    const wchar_t *cwd,
                                    std::wstring env)
{

    WriteBuffer packet;
    packet.putInt(AgentMsg::StartProcess);
    packet.putWString(appname ? appname : L"");
    packet.putWString(cmdline ? cmdline : L"");
    packet.putWString(cwd ? cwd : L"");
    packet.putWString(env);
    packet.putWString(getDesktopFullName());
    writePacket(pc, packet);
    return readInt32(pc);
}

Now the pty.cc
It calls winpty_start_process
It must create a std::wstring with all the vars separated by a NULL and finishing by 2*NULL:

static NAN_METHOD(PtyStartProcess) {
  NanScope();

  if (args.Length() != 5
    || !args[0]->IsNumber() // pid
    || !args[1]->IsString() // file
    || !args[2]->IsString() // cmdline
    || !args[3]->IsArray() // env
    || !args[4]->IsString()) // cwd
  {
    return NanThrowError(
        "Usage: pty.startProcess(pid, file, cmdline, env, cwd)");
  }

  // Get winpty_t by control pipe handle
  int pid = args[0]->Int32Value();

  winpty_t *pc = get_pipe_handle(pid);
  assert(pc != nullptr);

  const wchar_t *file = to_wstring(String::Utf8Value(args[1]->ToString()));
  const wchar_t *cmdline = to_wstring(String::Utf8Value(args[2]->ToString()));
  const wchar_t *cwd = to_wstring(String::Utf8Value(args[4]->ToString()));

  // create environment block
  std::wstring          env;
  const Handle<Array>   envValues       = Handle<Array>::Cast(args[3]);
  uint32_t              envValueCount   = envValues->Length();
  if (envValueCount > 0)
  {
      for(uint32_t i=0; i<envValueCount; i++)
      {
          env.append(to_wstring(String::Utf8Value(envValues->Get(i)->ToString())));
          env.push_back(L'\0');
      }
      env.push_back(L'\0');
  }

  /*
  wchar_t *env = NULL;
  const Handle<Array> envValues = Handle<Array>::Cast(args[3]);
  if(!envValues.IsEmpty()) {
      OutputDebugStringW(L"NOT EMPTY");
      if (envValues->Length() == 0) OutputDebugStringW(L"-> 0");
      if (envValues->Length() == 1) OutputDebugStringW(L"-> 1");
      if (envValues->Length() == 2) OutputDebugStringW(L"-> 2");

    std::wstringstream envBlock;

    for(uint32_t i = 0; i < envValues->Length(); i++) {
      std::wstring envValue(to_wstring(String::Utf8Value(envValues->Get(i)->ToString())));
      OutputDebugStringW(L"-----");
      OutputDebugStringW(envValue.c_str());
      envBlock << envValue << L' ';
    }

    std::wstring output = envBlock.str();

    size_t count = output.size();
    env = new wchar_t[count + 2];
    wcsncpy(env, output.c_str(), count);

    wcscat(env, L"\0");
  }
*/
  // Start new terminal
  int result = winpty_start_process(pc, file, cmdline, cwd, env);
  //delete env;

  assert(0 == result);

  NanReturnUndefined();
}

I hope this could help other people ;)
PS: sorry for my soooo bad English...

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions