xpcom/threads/nsEnvironment.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsEnvironment.h"
     7 #include "prenv.h"
     8 #include "prprf.h"
     9 #include "nsBaseHashtable.h"
    10 #include "nsHashKeys.h"
    11 #include "nsPromiseFlatString.h"
    12 #include "nsDependentString.h"
    13 #include "nsNativeCharsetUtils.h"
    15 using namespace mozilla;
    17 NS_IMPL_ISUPPORTS(nsEnvironment, nsIEnvironment)
    19 nsresult
    20 nsEnvironment::Create(nsISupports *aOuter, REFNSIID aIID,
    21                       void **aResult)
    22 {
    23     nsresult rv;
    24     *aResult = nullptr;
    26     if (aOuter != nullptr) {
    27         return NS_ERROR_NO_AGGREGATION;
    28     }
    30     nsEnvironment* obj = new nsEnvironment();
    31     if (!obj) {
    32         return NS_ERROR_OUT_OF_MEMORY;
    33     }
    35     rv = obj->QueryInterface(aIID, aResult);
    36     if (NS_FAILED(rv)) {
    37       delete obj;
    38     }
    39     return rv;
    40 }
    42 nsEnvironment::~nsEnvironment()
    43 {
    44 }
    46 NS_IMETHODIMP
    47 nsEnvironment::Exists(const nsAString& aName, bool *aOutValue)
    48 {
    49     nsAutoCString nativeName;
    50     nsresult rv = NS_CopyUnicodeToNative(aName, nativeName);
    51     if (NS_WARN_IF(NS_FAILED(rv)))
    52         return rv;
    54     nsAutoCString nativeVal;
    55 #if defined(XP_UNIX)
    56     /* For Unix/Linux platforms we follow the Unix definition:
    57      * An environment variable exists when |getenv()| returns a non-nullptr
    58      * value. An environment variable does not exist when |getenv()| returns
    59      * nullptr.
    60      */
    61     const char *value = PR_GetEnv(nativeName.get());
    62     *aOutValue = value && *value;
    63 #else
    64     /* For non-Unix/Linux platforms we have to fall back to a 
    65      * "portable" definition (which is incorrect for Unix/Linux!!!!)
    66      * which simply checks whether the string returned by |Get()| is empty
    67      * or not.
    68      */
    69     nsAutoString value;
    70     Get(aName, value);
    71     *aOutValue = !value.IsEmpty();
    72 #endif /* XP_UNIX */
    74     return NS_OK;
    75 }
    77 NS_IMETHODIMP
    78 nsEnvironment::Get(const nsAString& aName, nsAString& aOutValue)
    79 {
    80     nsAutoCString nativeName;
    81     nsresult rv = NS_CopyUnicodeToNative(aName, nativeName);
    82     if (NS_WARN_IF(NS_FAILED(rv)))
    83         return rv;
    85     nsAutoCString nativeVal;
    86     const char *value = PR_GetEnv(nativeName.get());
    87     if (value && *value) {
    88         rv = NS_CopyNativeToUnicode(nsDependentCString(value), aOutValue);
    89     } else {
    90         aOutValue.Truncate();
    91         rv = NS_OK;
    92     }
    94     return rv;
    95 }
    97 /* Environment strings must have static duration; We're gonna leak all of this
    98  * at shutdown: this is by design, caused how Unix/Linux implement environment
    99  * vars. 
   100  */
   102 typedef nsBaseHashtableET<nsCharPtrHashKey,char*> EnvEntryType;
   103 typedef nsTHashtable<EnvEntryType> EnvHashType;
   105 static EnvHashType *gEnvHash = nullptr;
   107 static bool
   108 EnsureEnvHash()
   109 {
   110     if (gEnvHash)
   111         return true;
   113     gEnvHash = new EnvHashType;
   114     if (!gEnvHash)
   115         return false;
   117     return true;
   118 }
   120 NS_IMETHODIMP
   121 nsEnvironment::Set(const nsAString& aName, const nsAString& aValue)
   122 {
   123     nsAutoCString nativeName;
   124     nsAutoCString nativeVal;
   126     nsresult rv = NS_CopyUnicodeToNative(aName, nativeName);
   127     if (NS_WARN_IF(NS_FAILED(rv)))
   128         return rv;
   130     rv = NS_CopyUnicodeToNative(aValue, nativeVal);
   131     if (NS_WARN_IF(NS_FAILED(rv)))
   132         return rv;
   134     MutexAutoLock lock(mLock);
   136     if (!EnsureEnvHash()){
   137         return NS_ERROR_UNEXPECTED;
   138     }
   140     EnvEntryType* entry = gEnvHash->PutEntry(nativeName.get());
   141     if (!entry) {
   142         return NS_ERROR_OUT_OF_MEMORY;
   143     }
   145     char* newData = PR_smprintf("%s=%s",
   146                                 nativeName.get(),
   147                                 nativeVal.get());
   148     if (!newData) {
   149         return NS_ERROR_OUT_OF_MEMORY;
   150     } 
   152     PR_SetEnv(newData);
   153     if (entry->mData) {
   154         PR_smprintf_free(entry->mData);
   155     }
   156     entry->mData = newData;
   157     return NS_OK;
   158 }

mercurial