blob: be0f909eb31aef047aea638de261fd196d7bad4c [file] [log] [blame]
/*
* Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "EnvironmentVariables.h"
#include <crt_externs.h>
namespace WebKit {
EnvironmentVariables::EnvironmentVariables()
: m_environmentPointer(*_NSGetEnviron())
{
}
EnvironmentVariables::~EnvironmentVariables()
{
size_t size = m_allocatedStrings.size();
for (size_t i = 0; i < size; ++i)
fastFree(m_allocatedStrings[i]);
}
void EnvironmentVariables::set(const char* name, const char* value)
{
// Check if we need to copy the environment.
if (m_environmentPointer == *_NSGetEnviron())
copyEnvironmentVariables();
// Allocate a string for the name and value.
const char* nameAndValue = createStringForVariable(name, value);
for (size_t i = 0; i < m_environmentVariables.size() - 1; ++i) {
if (valueIfVariableHasName(m_environmentVariables[i], name)) {
// Just replace the environment variable.
m_environmentVariables[i] = const_cast<char*>(nameAndValue);
return;
}
}
// Append the new string.
ASSERT(!m_environmentVariables.last());
m_environmentVariables.last() = const_cast<char*>(nameAndValue);
m_environmentVariables.append(static_cast<char*>(0));
m_environmentPointer = m_environmentVariables.data();
}
const char* EnvironmentVariables::get(const char* name) const
{
for (size_t i = 0; m_environmentPointer[i]; ++i) {
if (const char* value = valueIfVariableHasName(m_environmentPointer[i], name))
return value;
}
return 0;
}
void EnvironmentVariables::appendValue(const char* name, const char* value, char separator)
{
const char* existingValue = get(name);
if (!existingValue) {
set(name, value);
return;
}
Vector<char, 128> newValue;
newValue.append(existingValue, strlen(existingValue));
newValue.append(separator);
newValue.append(value, strlen(value) + 1);
set(name, newValue.data());
}
const char* EnvironmentVariables::valueIfVariableHasName(const char* environmentVariable, const char* name) const
{
// Find the environment variable name.
const char* equalsLocation = strchr(environmentVariable, '=');
ASSERT(equalsLocation);
size_t nameLength = equalsLocation - environmentVariable;
if (strlen(name) != nameLength)
return 0;
if (memcmp(environmentVariable, name, nameLength))
return 0;
return equalsLocation + 1;
}
const char* EnvironmentVariables::createStringForVariable(const char* name, const char* value)
{
int nameLength = strlen(name);
int valueLength = strlen(value);
// Allocate enough room to hold 'name=value' and the null character.
char* string = static_cast<char*>(fastMalloc(nameLength + 1 + valueLength + 1));
memcpy(string, name, nameLength);
string[nameLength] = '=';
memcpy(string + nameLength + 1, value, valueLength);
string[nameLength + 1 + valueLength] = '\0';
m_allocatedStrings.append(string);
return string;
}
void EnvironmentVariables::copyEnvironmentVariables()
{
for (size_t i = 0; (*_NSGetEnviron())[i]; i++)
m_environmentVariables.append((*_NSGetEnviron())[i]);
// Null-terminate the array.
m_environmentVariables.append(static_cast<char*>(0));
// Update the environment pointer.
m_environmentPointer = m_environmentVariables.data();
}
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
const char* EnvironmentVariables::preexistingProcessServiceNameKey()
{
return "WEBKIT_PREEXISTING_PROCESS_SERVICE_NAME";
}
const char* EnvironmentVariables::preexistingProcessTypeKey()
{
return "WEBKIT_PREEXISTING_PROCESS_TYPE";
}
#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
} // namespace WebKit