diff options
author | 2023-07-17 21:21:32 -0700 | |
---|---|---|
committer | 2023-07-17 21:21:43 -0700 | |
commit | 728c8fdcdb4e9276a7bd0721bad3b5d0cbed67fa (patch) | |
tree | 83084ab477feef9b58e91f999cbf0b0bc67ca493 /src/bun.js/bindings/Process.cpp | |
parent | 13b54fbdb8cc36bbe027238654360f159ecaefbb (diff) | |
download | bun-728c8fdcdb4e9276a7bd0721bad3b5d0cbed67fa.tar.gz bun-728c8fdcdb4e9276a7bd0721bad3b5d0cbed67fa.tar.zst bun-728c8fdcdb4e9276a7bd0721bad3b5d0cbed67fa.zip |
Implement `process.{stdout, stderr}.{columns, rows, getWindowSize}`
Diffstat (limited to 'src/bun.js/bindings/Process.cpp')
-rw-r--r-- | src/bun.js/bindings/Process.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/src/bun.js/bindings/Process.cpp b/src/bun.js/bindings/Process.cpp index dd5c41c44..a7798bf9f 100644 --- a/src/bun.js/bindings/Process.cpp +++ b/src/bun.js/bindings/Process.cpp @@ -15,6 +15,9 @@ #include <JavaScriptCore/LazyProperty.h> #include <JavaScriptCore/LazyPropertyInlines.h> #include <JavaScriptCore/VMTrapsInlines.h> +#include <termios.h> +#include <errno.h> +#include <sys/ioctl.h> #pragma mark - Node.js Process @@ -109,7 +112,53 @@ JSC_DEFINE_CUSTOM_SETTER(Process_defaultSetter, return true; } -JSC_DECLARE_HOST_FUNCTION(Process_functionNextTick); +static bool getWindowSize(int fd, size_t* width, size_t* height) +{ + struct winsize ws; + int err; + do + err = ioctl(fd, TIOCGWINSZ, &ws); + while (err == -1 && errno == EINTR); + + if (err == -1) + return false; + + *width = ws.ws_col; + *height = ws.ws_row; + + return true; +} + +JSC_DEFINE_HOST_FUNCTION(Process_functionInternalGetWindowSize, + (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) +{ + JSC::VM& vm = globalObject->vm(); + auto argCount = callFrame->argumentCount(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + if (argCount == 0) { + JSC::throwTypeError(globalObject, throwScope, "getWindowSize requires 2 argument (a file descriptor)"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + int fd = callFrame->uncheckedArgument(0).toInt32(globalObject); + RETURN_IF_EXCEPTION(throwScope, {}); + JSC::JSArray* array = jsDynamicCast<JSC::JSArray*>(callFrame->uncheckedArgument(1)); + if (!array || array->length() < 2) { + JSC::throwTypeError(globalObject, throwScope, "getWindowSize requires 2 argument (an array)"_s); + return JSC::JSValue::encode(JSC::JSValue {}); + } + + size_t width, height; + if (!getWindowSize(fd, &width, &height)) { + return JSC::JSValue::encode(jsBoolean(false)); + } + + array->putDirectIndex(globalObject, 0, jsNumber(width)); + array->putDirectIndex(globalObject, 1, jsNumber(height)); + + return JSC::JSValue::encode(jsBoolean(true)); +} + JSC_DEFINE_HOST_FUNCTION(Process_functionNextTick, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) { @@ -855,9 +904,13 @@ static JSValue constructStdioWriteStream(JSC::JSGlobalObject* globalObject, int { auto& vm = globalObject->vm(); auto scope = DECLARE_THROW_SCOPE(vm); + JSC::JSFunction* getWindowSizeFunction = JSC::JSFunction::create(vm, globalObject, 2, + String("getWindowSize"_s), Process_functionInternalGetWindowSize, ImplementationVisibility::Public); + JSC::JSFunction* getStdioWriteStream = JSC::JSFunction::create(vm, processObjectInternalsGetStdioWriteStreamCodeGenerator(vm), globalObject); JSC::MarkedArgumentBuffer args; args.append(JSC::jsNumber(fd)); + args.append(getWindowSizeFunction); auto clientData = WebCore::clientData(vm); JSC::CallData callData = JSC::getCallData(getStdioWriteStream); |