Bug 1001842 part 1: record the umask in NS_InitXPCOM2 and expose it to JS via nsSystemInfo. r=bsmedberg
authorZack Weinberg <zackw@panix.com>
Sat, 26 Apr 2014 10:56:54 -0400
changeset 200033 5fe8306c6409dfe6cd8151f06ae27ab1e29dd552
parent 200032 b9ed93ef1d238e04ae9a9ee107538fc6ddc20d11
child 200034 ea4471fb806febd3454ccd076ca7ef4cddf55a72
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs1001842
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1001842 part 1: record the umask in NS_InitXPCOM2 and expose it to JS via nsSystemInfo. r=bsmedberg
xpcom/base/nsSystemInfo.cpp
xpcom/base/nsSystemInfo.h
xpcom/build/nsXPComInit.cpp
xpcom/tests/unit/test_systemInfo.js
--- a/xpcom/base/nsSystemInfo.cpp
+++ b/xpcom/base/nsSystemInfo.cpp
@@ -35,16 +35,23 @@ using namespace mozilla::widget::android
 #endif
 
 #ifdef ANDROID
 extern "C" {
 NS_EXPORT int android_sdk_version;
 }
 #endif
 
+// Slot for NS_InitXPCOM2 to pass information to nsSystemInfo::Init.
+// Only set to nonzero (potentially) if XP_UNIX.  On such systems, the
+// system call to discover the appropriate value is not thread-safe,
+// so we must call it before going multithreaded, but nsSystemInfo::Init
+// only happens well after that point.
+uint32_t nsSystemInfo::gUserUmask = 0;
+
 #if defined(XP_WIN)
 namespace {
 nsresult GetHDDInfo(const char* aSpecialDirName, nsAutoCString& aModel,
                     nsAutoCString& aRevision)
 {
     aModel.Truncate();
     aRevision.Truncate();
 
@@ -193,16 +200,17 @@ nsSystemInfo::Init()
 #endif
 
     // Additional informations not available through PR_GetSystemInfo.
     SetInt32Property(NS_LITERAL_STRING("pagesize"), PR_GetPageSize());
     SetInt32Property(NS_LITERAL_STRING("pageshift"), PR_GetPageShift());
     SetInt32Property(NS_LITERAL_STRING("memmapalign"), PR_GetMemMapAlignment());
     SetInt32Property(NS_LITERAL_STRING("cpucount"), PR_GetNumberOfProcessors());
     SetUint64Property(NS_LITERAL_STRING("memsize"), PR_GetPhysicalMemorySize());
+    SetUint32Property(NS_LITERAL_STRING("umask"), nsSystemInfo::gUserUmask);
 
     for (uint32_t i = 0; i < ArrayLength(cpuPropItems); i++) {
         rv = SetPropertyAsBool(NS_ConvertASCIItoUTF16(cpuPropItems[i].name),
                                cpuPropItems[i].propfun());
         if (NS_WARN_IF(NS_FAILED(rv)))
           return rv;
     }
 
@@ -302,16 +310,29 @@ nsSystemInfo::SetInt32Property(const nsA
     nsresult rv =
 #endif
       SetPropertyAsInt32(aPropertyName, aValue);
     NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to set property");
   }
 }
 
 void
+nsSystemInfo::SetUint32Property(const nsAString &aPropertyName,
+                                const uint32_t aValue)
+{
+  // Only one property is currently set via this function.
+  // It may legitimately be zero.
+#ifdef DEBUG
+  nsresult rv =
+#endif
+    SetPropertyAsUint32(aPropertyName, aValue);
+  NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Unable to set property");
+}
+
+void
 nsSystemInfo::SetUint64Property(const nsAString &aPropertyName,
                                 const uint64_t aValue)
 {
   NS_WARN_IF_FALSE(aValue > 0, "Unable to read system value");
   if (aValue > 0) {
 #ifdef DEBUG
     nsresult rv =
 #endif
--- a/xpcom/base/nsSystemInfo.h
+++ b/xpcom/base/nsSystemInfo.h
@@ -9,19 +9,25 @@
 #include "nsHashPropertyBag.h"
 
 class nsSystemInfo : public nsHashPropertyBag {
 public:
     nsSystemInfo();
 
     nsresult Init();
 
+    // Slot for NS_InitXPCOM2 to pass information to nsSystemInfo::Init.
+    // See comments above the variable definition and in NS_InitXPCOM2.
+    static uint32_t gUserUmask;
+
 protected:
     void SetInt32Property(const nsAString &aPropertyName,
                           const int32_t aValue);
+    void SetUint32Property(const nsAString &aPropertyName,
+                           const uint32_t aValue);
     void SetUint64Property(const nsAString &aPropertyName,
                            const uint64_t aValue);
 
 private:
     ~nsSystemInfo();
 };
 
 #define NS_SYSTEMINFO_CONTRACTID "@mozilla.org/system-info;1"
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -456,16 +456,27 @@ NS_InitXPCOM2(nsIServiceManager* *result
 
      // We are not shutting down
     gXPCOMShuttingDown = false;
 
     // Initialize the available memory tracker before other threads have had a
     // chance to start up, because the initialization is not thread-safe.
     mozilla::AvailableMemoryTracker::Init();
 
+#ifdef XP_UNIX
+    // Discover the current value of the umask, and save it where
+    // nsSystemInfo::Init can retrieve it when necessary.  There is no way
+    // to read the umask without changing it, and the setting is process-
+    // global, so this must be done while we are still single-threaded; the
+    // nsSystemInfo object is typically created much later, when some piece
+    // of chrome JS wants it.  The system call is specified as unable to fail.
+    nsSystemInfo::gUserUmask = ::umask(0777);
+    ::umask(nsSystemInfo::gUserUmask);
+#endif
+
     NS_LogInit();
 
     // Set up chromium libs
     NS_ASSERTION(!sExitManager && !sMessageLoop, "Bad logic!");
 
     if (!AtExitManager::AlreadyRegistered()) {
         sExitManager = new AtExitManager();
     }
--- a/xpcom/tests/unit/test_systemInfo.js
+++ b/xpcom/tests/unit/test_systemInfo.js
@@ -8,9 +8,13 @@ function run_test() {
   let sysInfo = Components.classes["@mozilla.org/system-info;1"].
                 getService(Components.interfaces.nsIPropertyBag2);
 
   PROPERTIES.forEach(function(aPropertyName) {
     print("Testing property: " + aPropertyName);
     let value = sysInfo.getProperty(aPropertyName);
     do_check_true(!!value);
   });
+
+  // This property must exist, but its value might be zero.
+  print("Testing property: umask")
+  do_check_eq(typeof sysInfo.getProperty("umask"), "number");
 }