mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-12-25 05:07:12 +01:00
Try to convert OS::execute() output to Unicode on Windows
(cherry picked from commit a71e8081124eaf4eac6059bfeb3550a400bc2002)
This commit is contained in:
parent
e7f9cc8db3
commit
8790700593
@ -2780,6 +2780,31 @@ String OS_Windows::_quote_command_line_argument(const String &p_text) const {
|
|||||||
return p_text;
|
return p_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _append_to_pipe(char *p_bytes, int p_size, String *r_pipe, Mutex *p_pipe_mutex) {
|
||||||
|
// Try to convert from default ANSI code page to Unicode.
|
||||||
|
LocalVector<wchar_t> wchars;
|
||||||
|
int total_wchars = MultiByteToWideChar(CP_ACP, 0, p_bytes, p_size, nullptr, 0);
|
||||||
|
if (total_wchars > 0) {
|
||||||
|
wchars.resize(total_wchars);
|
||||||
|
if (MultiByteToWideChar(CP_ACP, 0, p_bytes, p_size, wchars.ptr(), total_wchars) == 0) {
|
||||||
|
wchars.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_pipe_mutex) {
|
||||||
|
p_pipe_mutex->lock();
|
||||||
|
}
|
||||||
|
if (wchars.empty()) {
|
||||||
|
// Let's hope it's compatible with UTF-8.
|
||||||
|
(*r_pipe) += String::utf8(p_bytes, p_size);
|
||||||
|
} else {
|
||||||
|
(*r_pipe) += String(wchars.ptr(), total_wchars);
|
||||||
|
}
|
||||||
|
if (p_pipe_mutex) {
|
||||||
|
p_pipe_mutex->unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
|
Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id, String *r_pipe, int *r_exitcode, bool read_stderr, Mutex *p_pipe_mutex, bool p_open_console) {
|
||||||
String path = p_path.replace("/", "\\");
|
String path = p_path.replace("/", "\\");
|
||||||
|
|
||||||
@ -2838,21 +2863,44 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
|
|||||||
if (p_blocking) {
|
if (p_blocking) {
|
||||||
if (r_pipe) {
|
if (r_pipe) {
|
||||||
CloseHandle(pipe[1]); // Close pipe write handle (only child process is writing).
|
CloseHandle(pipe[1]); // Close pipe write handle (only child process is writing).
|
||||||
char buf[4096];
|
|
||||||
|
LocalVector<char> bytes;
|
||||||
|
int bytes_in_buffer = 0;
|
||||||
|
|
||||||
|
const int CHUNK_SIZE = 4096;
|
||||||
DWORD read = 0;
|
DWORD read = 0;
|
||||||
for (;;) { // Read StdOut and StdErr from pipe.
|
for (;;) { // Read StdOut and StdErr from pipe.
|
||||||
bool success = ReadFile(pipe[0], buf, 4096, &read, NULL);
|
bytes.resize(bytes_in_buffer + CHUNK_SIZE);
|
||||||
|
const bool success = ReadFile(pipe[0], bytes.ptr() + bytes_in_buffer, CHUNK_SIZE, &read, NULL);
|
||||||
if (!success || read == 0) {
|
if (!success || read == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (p_pipe_mutex) {
|
// Assume that all possible encodings are ASCII-compatible.
|
||||||
p_pipe_mutex->lock();
|
// Break at newline to allow receiving long output in portions.
|
||||||
|
int newline_index = -1;
|
||||||
|
for (int i = read - 1; i >= 0; i--) {
|
||||||
|
if (bytes[bytes_in_buffer + i] == '\n') {
|
||||||
|
newline_index = i;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
(*r_pipe) += String::utf8(buf, read);
|
|
||||||
if (p_pipe_mutex) {
|
|
||||||
p_pipe_mutex->unlock();
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
if (newline_index == -1) {
|
||||||
|
bytes_in_buffer += read;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int bytes_to_convert = bytes_in_buffer + (newline_index + 1);
|
||||||
|
_append_to_pipe(bytes.ptr(), bytes_to_convert, r_pipe, p_pipe_mutex);
|
||||||
|
|
||||||
|
bytes_in_buffer = read - (newline_index + 1);
|
||||||
|
memmove(bytes.ptr(), bytes.ptr() + bytes_to_convert, bytes_in_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes_in_buffer > 0) {
|
||||||
|
_append_to_pipe(bytes.ptr(), bytes_in_buffer, r_pipe, p_pipe_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
CloseHandle(pipe[0]); // Close pipe read handle.
|
CloseHandle(pipe[0]); // Close pipe read handle.
|
||||||
} else {
|
} else {
|
||||||
WaitForSingleObject(pi.pi.hProcess, INFINITE);
|
WaitForSingleObject(pi.pi.hProcess, INFINITE);
|
||||||
@ -2874,7 +2922,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments,
|
|||||||
process_map->insert(pid, pi);
|
process_map->insert(pid, pi);
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
};
|
}
|
||||||
|
|
||||||
Error OS_Windows::kill(const ProcessID &p_pid) {
|
Error OS_Windows::kill(const ProcessID &p_pid) {
|
||||||
ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED);
|
ERR_FAIL_COND_V(!process_map->has(p_pid), FAILED);
|
||||||
|
Loading…
Reference in New Issue
Block a user