Skip to content

Environment problems => investigation and solution ? #71

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...

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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