From 460fb89851eb588ee4a1119bc2ceb3c17b1692ef Mon Sep 17 00:00:00 2001 From: Bryan Roe Date: Fri, 17 Jun 2022 21:07:02 -0700 Subject: [PATCH] 1. Fixed process.stdin for POSIX 2. Added support for console.echo and console.canonical --- microscript/ILibDuktape_Polyfills.c | 106 ++++++++++++++++++++++ microscript/ILibDuktape_ScriptContainer.c | 34 ++++++- 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/microscript/ILibDuktape_Polyfills.c b/microscript/ILibDuktape_Polyfills.c index 8f18f22..ca414d6 100644 --- a/microscript/ILibDuktape_Polyfills.c +++ b/microscript/ILibDuktape_Polyfills.c @@ -32,6 +32,14 @@ limitations under the License. #include "../microstack/ILibCrypto.h" #include "../microstack/ILibRemoteLogging.h" +#ifdef _POSIX + #ifdef __APPLE__ + #include + #else + #include + #endif +#endif + #define ILibDuktape_Timer_Ptrs "\xFF_DuktapeTimer_PTRS" #define ILibDuktape_Queue_Ptr "\xFF_Queue" @@ -852,6 +860,102 @@ duk_ret_t ILibDuktape_Polyfills_Console_setInfoMask(duk_context *ctx) ILIBLOGMESSAGEX2_SetMask(duk_require_uint(ctx, 0)); return(0); } +duk_ret_t ILibDuktape_Polyfills_Console_canonical_get(duk_context *ctx) +{ +#if defined(WIN32) + DWORD mode = 0; + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); + duk_push_boolean(ctx, (mode & ENABLE_LINE_INPUT) == ENABLE_LINE_INPUT); +#elif defined(_POSIX) + struct termios term; + tcgetattr(fileno(stdin), &term); + duk_push_boolean(ctx, (term.c_lflag & ICANON) == ICANON); +#else + duk_push_boolean(ctx, 1); +#endif + return(1); +} +duk_ret_t ILibDuktape_Polyfills_Console_canonical_set(duk_context *ctx) +{ + int val = duk_require_boolean(ctx, 0) ? 1 : 0; + +#if defined(WIN32) + DWORD mode = 0; + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); + if (val == 0) + { + mode = mode & 0xFFFFFFFD; + } + else + { + mode |= ENABLE_LINE_INPUT; + } + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode); +#elif defined(_POSIX) + struct termios term; + tcgetattr(fileno(stdin), &term); + + if (val == 0) + { + term.c_lflag &= ~ICANON; + } + else + { + term.c_lflag |= ICANON; + } + tcsetattr(fileno(stdin), 0, &term); +#else + duk_push_boolean(ctx, 1); +#endif + return(0); +} +duk_ret_t ILibDuktape_Polyfills_Console_echo_get(duk_context *ctx) +{ +#if defined(WIN32) + DWORD mode = 0; + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); + duk_push_boolean(ctx, (mode & ENABLE_ECHO_INPUT) == ENABLE_ECHO_INPUT); +#elif defined(_POSIX) + struct termios term; + tcgetattr(fileno(stdin), &term); + duk_push_boolean(ctx, (term.c_lflag & ECHO) == ECHO); +#else + duk_push_boolean(ctx, 1); +#endif + return(1); +} +duk_ret_t ILibDuktape_Polyfills_Console_echo_set(duk_context *ctx) +{ + int val = duk_require_boolean(ctx, 0) ? 1 : 0; + +#if defined(WIN32) + DWORD mode = 0; + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); + if (val == 0) + { + mode = mode & 0xFFFFFFFB; + } + else + { + mode |= ENABLE_ECHO_INPUT; + } + SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), mode); +#elif defined(_POSIX) + struct termios term; + tcgetattr(fileno(stdin), &term); + + if (val == 0) + { + term.c_lflag &= ~ECHO; + } + else + { + term.c_lflag |= ECHO; + } + tcsetattr(fileno(stdin), 0, &term); +#endif + return(0); +} duk_ret_t ILibDuktape_Polyfills_Console_rawLog(duk_context *ctx) { char *val = (char*)duk_require_string(ctx, 0); @@ -892,6 +996,8 @@ void ILibDuktape_Polyfills_Console(duk_context *ctx) ILibDuktape_CreateInstanceMethod(ctx, "setDestination", ILibDuktape_Polyfills_Console_setDestination, DUK_VARARGS); ILibDuktape_CreateInstanceMethod(ctx, "setInfoLevel", ILibDuktape_Polyfills_Console_setInfoLevel, 1); ILibDuktape_CreateInstanceMethod(ctx, "setInfoMask", ILibDuktape_Polyfills_Console_setInfoMask, 1); + ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "echo", ILibDuktape_Polyfills_Console_echo_get, ILibDuktape_Polyfills_Console_echo_set); + ILibDuktape_CreateEventWithGetterAndSetterEx(ctx, "canonical", ILibDuktape_Polyfills_Console_canonical_get, ILibDuktape_Polyfills_Console_canonical_set); duk_push_object(ctx); duk_push_int(ctx, ILibDuktape_Console_DestinationFlags_DISABLED); duk_put_prop_string(ctx, -2, "DISABLED"); diff --git a/microscript/ILibDuktape_ScriptContainer.c b/microscript/ILibDuktape_ScriptContainer.c index 2b849a8..8731b6b 100644 --- a/microscript/ILibDuktape_ScriptContainer.c +++ b/microscript/ILibDuktape_ScriptContainer.c @@ -773,6 +773,30 @@ duk_ret_t ILibDuktape_Process_stdin_finalizer(duk_context *ctx) free(data); return(0); } +#ifdef _POSIX +duk_ret_t ILibDuktape_Process_stdin_readset(duk_context *ctx) +{ + ILibDuktape_readableStream *rs; + + duk_push_this(ctx); // [descriptorevents] + duk_get_prop_string(ctx, -1, "stdin"); // [descriptorevents][stdin] + + rs = (ILibDuktape_readableStream*)Duktape_GetBufferProperty(ctx, -1, ILibDuktape_readableStream_RSPTRS); + + char buffer[1024]; + int bufferLen; + duk_push_this(ctx); // [descriptorevents] + duk_get_prop_string(ctx, -1, "stdin"); // [descriptorevents][stdin] + + bufferLen = read(0, buffer, sizeof(buffer)); + + if (bufferLen > 0) + { + ILibDuktape_readableStream_WriteData(rs, buffer, bufferLen); + } + return(0); +} +#endif duk_ret_t ILibDuktape_Process_stdin_get(duk_context *ctx) { duk_push_this(ctx); // [process] @@ -794,8 +818,16 @@ duk_ret_t ILibDuktape_Process_stdin_get(duk_context *ctx) #ifdef WIN32 ((ILibDuktape_Process_StdIn_Data*)rs->user)->resumeEvent = CreateEvent(NULL, TRUE, TRUE, NULL); ((ILibDuktape_Process_StdIn_Data*)rs->user)->workerThread = ILibSpawnNormalThread(ILibDuktape_Process_stdin_WindowsRunLoop, rs->user); +#else + duk_push_heap_stash(ctx); // [stash] + duk_eval_string(ctx, "require('DescriptorEvents').addDescriptor(0, { readset: true });"); // [stash][descriptorevents] + duk_dup(ctx, -3); + duk_put_prop_string(ctx, -2, "stdin"); + ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "readset", ILibDuktape_Process_stdin_readset); + duk_put_prop_string(ctx, -2, "FD_STDIN"); // [stash] + duk_pop(ctx); // ... #endif - + ILibDuktape_EventEmitter_AddOnEx(ctx, -1, "~", ILibDuktape_Process_stdin_finalizer); return(1); }