mirror of
https://github.com/DoneJS-Runtime/quickjs-done-nextgen.git
synced 2025-01-09 17:43:15 +00:00
Detect if stdout is a console in quickjs-libc (#642)
Use regular libc stdio (fwrite) when stdout is redirected, don't call WriteConsoleA because that circumvents the redirection. Fixes: https://github.com/quickjs-ng/quickjs/issues/635
This commit is contained in:
parent
df81c9940f
commit
c53a0a86da
1 changed files with 48 additions and 46 deletions
|
@ -3910,54 +3910,56 @@ JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name)
|
||||||
|
|
||||||
/**********************************************************/
|
/**********************************************************/
|
||||||
|
|
||||||
|
static JSValue js_print(JSContext *ctx, JSValue this_val,
|
||||||
|
int argc, JSValue *argv)
|
||||||
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static JSValue js_print(JSContext *ctx, JSValue this_val,
|
HANDLE handle;
|
||||||
int argc, JSValue *argv)
|
DWORD mode;
|
||||||
{
|
|
||||||
int i;
|
|
||||||
const char *str;
|
|
||||||
size_t len;
|
|
||||||
DWORD written;
|
|
||||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
if (hConsole == INVALID_HANDLE_VALUE)
|
|
||||||
return JS_EXCEPTION;
|
|
||||||
for(i = 0; i < argc; i++) {
|
|
||||||
if (i != 0)
|
|
||||||
WriteConsoleW(hConsole, L" ", 1, &written, NULL);
|
|
||||||
str = JS_ToCStringLen(ctx, &len, argv[i]);
|
|
||||||
if (!str)
|
|
||||||
return JS_EXCEPTION;
|
|
||||||
DWORD prev = GetConsoleOutputCP();
|
|
||||||
SetConsoleOutputCP(CP_UTF8);
|
|
||||||
WriteConsoleA(hConsole, str, len, &written, NULL);
|
|
||||||
SetConsoleOutputCP(prev);
|
|
||||||
JS_FreeCString(ctx, str);
|
|
||||||
}
|
|
||||||
WriteConsoleW(hConsole, L"\n", 1, &written, NULL);
|
|
||||||
FlushFileBuffers(hConsole);
|
|
||||||
return JS_UNDEFINED;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static JSValue js_print(JSContext *ctx, JSValue this_val,
|
|
||||||
int argc, JSValue *argv)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
const char *str;
|
|
||||||
size_t len;
|
|
||||||
for(i = 0; i < argc; i++) {
|
|
||||||
if (i != 0)
|
|
||||||
putchar(' ');
|
|
||||||
str = JS_ToCStringLen(ctx, &len, argv[i]);
|
|
||||||
if (!str)
|
|
||||||
return JS_EXCEPTION;
|
|
||||||
fwrite(str, 1, len, stdout);
|
|
||||||
JS_FreeCString(ctx, str);
|
|
||||||
}
|
|
||||||
putchar('\n');
|
|
||||||
fflush(stdout);
|
|
||||||
return JS_UNDEFINED;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
const char *s;
|
||||||
|
DynBuf b;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
dbuf_init(&b);
|
||||||
|
for(i = 0; i < argc; i++) {
|
||||||
|
s = JS_ToCString(ctx, argv[i]);
|
||||||
|
if (s) {
|
||||||
|
dbuf_printf(&b, "%s%s", &" "[!i], s);
|
||||||
|
JS_FreeCString(ctx, s);
|
||||||
|
} else {
|
||||||
|
dbuf_printf(&b, "%s<exception>", &" "[!i]);
|
||||||
|
JS_FreeValue(ctx, JS_GetException(ctx));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dbuf_putc(&b, '\n');
|
||||||
|
#ifdef _WIN32
|
||||||
|
// use WriteConsoleA with CP_UTF8 for better Unicode handling vis-a-vis
|
||||||
|
// the mangling that happens when going through msvcrt's stdio layer,
|
||||||
|
// *except* when stdout is redirected to something that is not a console
|
||||||
|
handle = (HANDLE)_get_osfhandle(/*STDOUT_FILENO*/1); // don't CloseHandle
|
||||||
|
if (GetFileType(handle) != FILE_TYPE_CHAR)
|
||||||
|
goto fallback;
|
||||||
|
if (!GetConsoleMode(handle, &mode))
|
||||||
|
goto fallback;
|
||||||
|
handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
|
goto fallback;
|
||||||
|
mode = GetConsoleOutputCP();
|
||||||
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
|
WriteConsoleA(handle, b.buf, b.size, NULL, NULL);
|
||||||
|
SetConsoleOutputCP(mode);
|
||||||
|
FlushFileBuffers(handle);
|
||||||
|
goto done;
|
||||||
|
fallback:
|
||||||
|
#endif
|
||||||
|
fwrite(b.buf, 1, b.size, stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
goto done; // avoid unused label warning
|
||||||
|
done:
|
||||||
|
dbuf_free(&b);
|
||||||
|
return JS_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
void js_std_add_helpers(JSContext *ctx, int argc, char **argv)
|
void js_std_add_helpers(JSContext *ctx, int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue