Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Environment problems => investigation and solution ? #71

Closed
dabretin opened this issue May 19, 2014 · 1 comment
Closed

Environment problems => investigation and solution ? #71

dabretin opened this issue May 19, 2014 · 1 comment

Comments

@dabretin
Copy link

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

@dabretin
Copy link
Author

=> pull request submitted (#72)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant