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

In Windows host, use WriteConsoleW for stdout and stderr, and locale enabled print for file output #102295

Merged
merged 10 commits into from
Jun 6, 2024
47 changes: 41 additions & 6 deletions src/native/corehost/hostmisc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,48 @@ namespace pal

inline FILE* file_open(const string_t& path, const char_t* mode) { return ::_wfsopen(path.c_str(), mode, _SH_DENYNO); }

inline void file_vprintf(FILE* f, const char_t* format, va_list vl) { ::vfwprintf(f, format, vl); ::fputwc(_X('\n'), f); }
inline void err_fputs(const char_t* message) { ::fputws(message, stderr); ::fputwc(_X('\n'), stderr); }
inline void out_vprintf(const char_t* format, va_list vl) { ::vfwprintf(stdout, format, vl); ::fputwc(_X('\n'), stdout); }

inline int str_vprintf(char_t* buffer, size_t count, const char_t* format, va_list vl) { return ::_vsnwprintf_s(buffer, count, _TRUNCATE, format, vl); }
inline int strlen_vprintf(const char_t* format, va_list vl) { return ::_vscwprintf(format, vl); }

inline void file_vprintf(FILE* f, const char_t* format, va_list vl)
elinor-fung marked this conversation as resolved.
Show resolved Hide resolved
{
_locale_t loc = _create_locale(LC_ALL, ".utf8");
::_vfwprintf_l(f, format, loc, vl);
::fputwc(_X('\n'), f);
_free_locale(loc);
}

inline void err_fputs(const char_t* message) {
elinor-fung marked this conversation as resolved.
Show resolved Hide resolved
HANDLE e = GetStdHandle(STD_ERROR_HANDLE);
elinor-fung marked this conversation as resolved.
Show resolved Hide resolved
WriteConsoleW(e, message, (int)strlen(message), NULL, NULL);
WriteConsoleW(e, _X("\n"), 1, NULL, NULL);
}

inline void out_vprintf(const char_t* format, va_list vl) {
elinor-fung marked this conversation as resolved.
Show resolved Hide resolved
// Get the length of the formatted string + newline + null terminator
int len = 2 + strlen_vprintf(format, vl);
elinor-fung marked this conversation as resolved.
Show resolved Hide resolved
if (len < 0)
{
return;
}
char_t* buffer = (char_t*) malloc((len) * sizeof(char_t));
elinor-fung marked this conversation as resolved.
Show resolved Hide resolved
if (buffer == nullptr)
{
return;
}
int written = str_vprintf(buffer, len - 1, format, vl);
if (written != len - 2)
{
free(buffer);
return;
}
buffer[len - 2] = _X('\n');
buffer[len - 1] = _X('\0');
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);

free(buffer);
}

inline const string_t strerror(int errnum)
{
// Windows does not provide strerrorlen to get the actual error length.
Expand All @@ -188,7 +223,7 @@ namespace pal
inline bool munmap(void* addr, size_t length) { return UnmapViewOfFile(addr) != 0; }
inline int get_pid() { return GetCurrentProcessId(); }
inline void sleep(uint32_t milliseconds) { Sleep(milliseconds); }
#else
#else // _WIN32
#ifdef EXPORT_SHARED_API
#define SHARED_API extern "C" __attribute__((__visibility__("default")))
#else
Expand Down Expand Up @@ -254,7 +289,7 @@ namespace pal
inline bool munmap(void* addr, size_t length) { return ::munmap(addr, length) == 0; }
inline int get_pid() { return getpid(); }
inline void sleep(uint32_t milliseconds) { usleep(milliseconds * 1000); }
#endif
#endif // _WIN32

inline int snwprintf(char_t* buffer, size_t count, const char_t* format, ...)
{
Expand Down
Loading