diff --git a/dom/system/OSFileConstants.cpp b/dom/system/OSFileConstants.cpp index 1e7edc29e32..ff12e438c61 100644 --- a/dom/system/OSFileConstants.cpp +++ b/dom/system/OSFileConstants.cpp @@ -46,6 +46,7 @@ #include "nsIObserver.h" #include "nsDirectoryServiceUtils.h" #include "nsIXULRuntime.h" +#include "nsIPropertyBag2.h" #include "nsXPCOMCIDInternal.h" #include "nsServiceManagerUtils.h" #include "nsString.h" @@ -163,6 +164,12 @@ struct Paths { */ Paths* gPaths = nullptr; +/** + * (Unix) the umask, which goes in OS.Constants.Sys but + * can only be looked up (via the system-info service) + * on the main thread. + */ +uint32_t gUserUmask = 0; } /** @@ -297,6 +304,19 @@ nsresult InitOSFileConstants() #endif // defined(XP_MACOSX) gPaths = paths.forget(); + + // Get the umask from the system-info service. + // The property will always be present, but it will be zero on + // non-Unix systems. + nsCOMPtr infoService = + do_GetService("@mozilla.org/system-info;1"); + MOZ_ASSERT(infoService, "Could not access the system information service"); + rv = infoService->GetPropertyAsUint32(NS_LITERAL_STRING("umask"), + &gUserUmask); + if (NS_FAILED(rv)) { + return rv; + } + return NS_OK; } @@ -853,6 +873,14 @@ bool DefineOSFileConstants(JSContext *cx, JS::Handle global) } #endif + dom::ConstantSpec umask_cs[] = { + { "umask", UINT_TO_JSVAL(gUserUmask) }, + PROP_END + }; + if (!dom::DefineConstants(cx, objSys, umask_cs)) { + return false; + } + // Build OS.Constants.Path JS::Rooted objPath(cx); diff --git a/dom/system/tests/test_constants.xul b/dom/system/tests/test_constants.xul index e3a52ddf5df..b4b1c3dc564 100644 --- a/dom/system/tests/test_constants.xul +++ b/dom/system/tests/test_constants.xul @@ -64,6 +64,14 @@ function test_debugBuildMainThread(isDebugBuild) { is(isDebugBuild, !!OS.Constants.Sys.DEBUG, "OS.Constants.Sys.DEBUG is set properly on main thread"); } +// Test that OS.Constants.Sys.umask is set properly on main thread +function test_umaskMainThread(umask) { + is(umask, OS.Constants.Sys.umask, + "OS.Constants.Sys.umask is set properly on main thread: " + + ("0000"+umask.toString(8)).slice(-4)); +} + + function test() { ok(true, "test_constants.xul: Starting test"); @@ -80,6 +88,11 @@ function test() { .getService(Components.interfaces.nsIDebug2).isDebugBuild; test_debugBuildMainThread(isDebugBuild); + let umask = Components.classes["@mozilla.org/system-info;1"]. + getService(Components.interfaces.nsIPropertyBag2). + getProperty("umask"); + test_umaskMainThread(umask); + // Test 2: Load libxul from chrome thread worker = new ChromeWorker("worker_constants.js"); SimpleTest.waitForExplicitFinish(); @@ -108,8 +121,12 @@ function test() { } }; - // nsIDebug2 is inaccessible from ChromeWorker. We need to pass isDebugBuild to the worker - worker.postMessage(isDebugBuild); + // pass expected values that are unavailable off-main-thread + // to the worker + worker.postMessage({ + isDebugBuild: isDebugBuild, + umask: umask + }); ok(true, "test_constants.xul: Test in progress"); }; ]]> diff --git a/dom/system/tests/worker_constants.js b/dom/system/tests/worker_constants.js index aafe665ea87..ace36906b90 100644 --- a/dom/system/tests/worker_constants.js +++ b/dom/system/tests/worker_constants.js @@ -13,11 +13,12 @@ self.onmessage = function(msg) { self.onmessage = function(msg) { log("ignored message "+JSON.stringify(msg.data)); }; - let isDebugBuild = msg.data; + let { isDebugBuild, umask } = msg.data; try { test_name(); test_xul(); test_debugBuildWorkerThread(isDebugBuild); + test_umaskWorkerThread(umask); } catch (x) { log("Catching error: " + x); log("Stack: " + x.stack); @@ -51,6 +52,13 @@ function test_debugBuildWorkerThread(isDebugBuild) { is(isDebugBuild, !!OS.Constants.Sys.DEBUG, "OS.Constants.Sys.DEBUG is set properly on worker thread"); } +// Test that OS.Constants.Sys.umask is set properly in ChromeWorker thread +function test_umaskWorkerThread(umask) { + is(umask, OS.Constants.Sys.umask, + "OS.Constants.Sys.umask is set properly on worker thread: " + + ("0000"+umask.toString(8)).slice(-4)); +} + // Test that OS.Constants.Path.libxul lets us open libxul function test_xul() { let lib;