diff options
-rw-r--r-- | packages/bun-types/globals.d.ts | 17 | ||||
-rw-r--r-- | src/bun.js/bindings/Process.cpp | 41 | ||||
-rw-r--r-- | test/bun.js/process.test.js | 13 |
3 files changed, 66 insertions, 5 deletions
diff --git a/packages/bun-types/globals.d.ts b/packages/bun-types/globals.d.ts index 9abf66736..02a9eaa68 100644 --- a/packages/bun-types/globals.d.ts +++ b/packages/bun-types/globals.d.ts @@ -374,6 +374,23 @@ interface Process { * The original argv[0] passed to Bun */ readonly argv0: string; + + /** + * Number of seconds the process has been running + * + * This uses a high-resolution timer, but divides from nanoseconds to seconds + * so there may be some loss of precision. + * + * For a more precise value, use `performance.timeOrigin` and `performance.now()` instead. + */ + uptime(): number; + + /** + * Bun process's file mode creation mask. + * + * @returns Bun process's file mode creation mask. + */ + umask(mask?: number): number; } declare var process: Process; diff --git a/src/bun.js/bindings/Process.cpp b/src/bun.js/bindings/Process.cpp index f7110767b..579796b9f 100644 --- a/src/bun.js/bindings/Process.cpp +++ b/src/bun.js/bindings/Process.cpp @@ -7,6 +7,7 @@ #include "headers.h" #include "JSEnvironmentVariableMap.h" #include "ImportMetaObject.h" +#include <sys/stat.h> #pragma mark - Node.js Process namespace Zig { @@ -280,8 +281,34 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionDlopen, return napi_register_module_v1(globalObject, JSC::JSValue::encode(exports)); } -static JSC_DECLARE_HOST_FUNCTION(Process_functionExit); -static JSC_DEFINE_HOST_FUNCTION(Process_functionExit, +JSC_DEFINE_HOST_FUNCTION(Process_functionUmask, + (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) +{ + if (callFrame->argumentCount() == 0) { + return JSC::JSValue::encode(JSC::jsNumber(umask(0))); + } + + auto& vm = globalObject->vm(); + auto throwScope = DECLARE_THROW_SCOPE(vm); + int umaskValue = callFrame->argument(0).toInt32(globalObject); + RETURN_IF_EXCEPTION(throwScope, JSC::JSValue::encode(JSC::JSValue {})); + + return JSC::JSValue::encode(JSC::jsNumber(umask(umaskValue))); +} + +extern "C" uint64_t Bun__readOriginTimer(void*); +extern "C" double Bun__readOriginTimerStart(void*); + +JSC_DEFINE_HOST_FUNCTION(Process_functionUptime, + (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) +{ + Zig::GlobalObject* globalObject_ = reinterpret_cast<Zig::GlobalObject*>(globalObject); + double now = static_cast<double>(Bun__readOriginTimer(globalObject_->bunVM())); + double result = (now / 1000000.0) / 1000.0; + return JSC::JSValue::encode(JSC::jsNumber(result)); +} + +JSC_DEFINE_HOST_FUNCTION(Process_functionExit, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) { if (callFrame->argumentCount() == 0) { @@ -296,9 +323,7 @@ static JSC_DEFINE_HOST_FUNCTION(Process_functionExit, extern "C" uint64_t Bun__readOriginTimer(void*); -static JSC_DECLARE_HOST_FUNCTION(Process_functionHRTime); - -static JSC_DEFINE_HOST_FUNCTION(Process_functionHRTime, +JSC_DEFINE_HOST_FUNCTION(Process_functionHRTime, (JSC::JSGlobalObject * globalObject_, JSC::CallFrame* callFrame)) { Zig::GlobalObject* globalObject @@ -637,6 +662,12 @@ void Process::finishCreation(JSC::VM& vm) this->putDirectCustomAccessor(vm, JSC::PropertyName(JSC::Identifier::fromString(vm, "execPath"_s)), JSC::CustomGetterSetter::create(vm, Process_lazyExecPathGetter, Process_defaultSetter), 0); + + this->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(this->vm(), "uptime"_s), + 0, Process_functionUptime, ImplementationVisibility::Public, NoIntrinsic, 0); + + this->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(this->vm(), "umask"_s), + 1, Process_functionUmask, ImplementationVisibility::Public, NoIntrinsic, 0); } const JSC::ClassInfo Process::s_info = { "Process"_s, &Base::s_info, nullptr, nullptr, diff --git a/test/bun.js/process.test.js b/test/bun.js/process.test.js index cd9e7cc7e..9c15892a9 100644 --- a/test/bun.js/process.test.js +++ b/test/bun.js/process.test.js @@ -112,3 +112,16 @@ it("process.argv0", () => { it("process.execPath", () => { expect(process.execPath).toBe(realpathSync(process.argv0)); }); + +it("process.uptime()", () => { + expect(process.uptime()).toBeGreaterThan(0); + expect(Math.floor(process.uptime())).toBe( + Math.floor(performance.now() / 1000), + ); +}); + +it("process.umask()", () => { + const orig = process.umask(777); + expect(orig).toBeGreaterThan(0); + expect(process.umask(orig)).toBe(777); +}); |