| 141 | } |
| 142 | |
| 143 | void BackendServer::startProcess() { |
| 144 | process_ = new uv_process_t{}; |
| 145 | // create pipes for stdio of the child process |
| 146 | stdoutPipe_ = createStdoutPipe(); |
| 147 | stdoutReadBuf_.clear(); |
| 148 | stdinPipe_ = createStdinPipe(); |
| 149 | stderrPipe_ = createStderrPipe(); |
| 150 | |
| 151 | constexpr auto pipeFlags = uv_stdio_flags(UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE); |
| 152 | uv_stdio_container_t stdio_containers[3]; |
| 153 | stdio_containers[0].data.stream = stdinPipe_->streamHandle(); |
| 154 | stdio_containers[0].flags = pipeFlags; |
| 155 | stdio_containers[1].data.stream = stdoutPipe_->streamHandle(); |
| 156 | stdio_containers[1].flags = pipeFlags; |
| 157 | stdio_containers[2].data.stream = stderrPipe_->streamHandle(); |
| 158 | stdio_containers[2].flags = pipeFlags; |
| 159 | |
| 160 | auto utf8CurrentDirPath = getUtf8CurrentDir(); |
| 161 | auto executablePath = utf8CurrentDirPath + '\\' + command_; |
| 162 | const char* argv[] = { |
| 163 | executablePath.c_str(), |
| 164 | params_.c_str(), |
| 165 | nullptr |
| 166 | }; |
| 167 | uv_process_options_t options = { 0 }; |
| 168 | options.flags = UV_PROCESS_WINDOWS_HIDE; // UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; |
| 169 | options.file = executablePath.c_str(); |
| 170 | options.args = const_cast<char**>(argv); |
| 171 | |
| 172 | auto backendWorkingDirPath = utf8CurrentDirPath + '\\' + workingDir_; |
| 173 | options.cwd = backendWorkingDirPath.c_str(); |
| 174 | |
| 175 | // build our own new environments |
| 176 | auto utf8EnvVars = getUtf8EnvironmentVariables(); |
| 177 | // add our own environment variables |
| 178 | // NOTE: Force python to output UTF-8 encoded strings |
| 179 | // Reference: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONIOENCODING |
| 180 | // By default, python uses ANSI encoding in Windows and this breaks our unicode support. |
| 181 | // FIXME: makes this configurable from backend.json. |
| 182 | utf8EnvVars.emplace_back("PYTHONIOENCODING=utf-8:ignore"); |
| 183 | |
| 184 | // convert to a null terminated char* array. |
| 185 | std::vector<const char*> env; |
| 186 | for (auto& v : utf8EnvVars) { |
| 187 | env.emplace_back(v.c_str()); |
| 188 | } |
| 189 | env.emplace_back(nullptr); |
| 190 | options.env = const_cast<char**>(env.data()); |
| 191 | |
| 192 | options.stdio_count = 3; |
| 193 | options.stdio = stdio_containers; |
| 194 | int ret = uv_spawn(uv_default_loop(), process_, &options); |
| 195 | if (ret < 0) { |
| 196 | delete process_; |
| 197 | process_ = nullptr; |
| 198 | closeStdioPipes(); |
| 199 | return; |
| 200 | } |
nothing calls this directly
no test coverage detected