diff options
author | Tad Marshall <tad@10gen.com> | 2013-06-17 19:25:26 -0400 |
---|---|---|
committer | Tad Marshall <tad@10gen.com> | 2013-06-17 19:25:26 -0400 |
commit | 75b4cddd29af46fb3902fd5a064bb7093fe68bea (patch) | |
tree | 0f5a8b4d12f99367d2a8f5fa812ef1f0a4bdd95d /src/mongo/platform | |
parent | fda4a2342614e4ca1fb26c868a5adef0e050eb5e (diff) | |
download | mongo-75b4cddd29af46fb3902fd5a064bb7093fe68bea.tar.gz |
SERVER-9786 Link to strcasestr at runtime for Solaris
For the Solaris/SmartOS build, do not make direct calls to strcasestr,
which is present in Solaris 11 but not in Solaris 10. Instead, see if
it is available in a loaded library (which will be libc.so.1) at runtime
and either call it or call an emulation. Use the emulated version on
Windows, which is also missing this function.
Diffstat (limited to 'src/mongo/platform')
-rw-r--r-- | src/mongo/platform/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/platform/strcasestr.cpp | 100 | ||||
-rw-r--r-- | src/mongo/platform/strcasestr.h | 35 |
3 files changed, 136 insertions, 0 deletions
diff --git a/src/mongo/platform/SConscript b/src/mongo/platform/SConscript index 66aad9a87cb..0c668a4e436 100644 --- a/src/mongo/platform/SConscript +++ b/src/mongo/platform/SConscript @@ -5,6 +5,7 @@ Import("env") env.Library('platform', [ 'process_id.cpp', 'random.cpp', + 'strcasestr.cpp', ]) env.CppUnitTest('atomic_word_test', 'atomic_word_test.cpp') diff --git a/src/mongo/platform/strcasestr.cpp b/src/mongo/platform/strcasestr.cpp new file mode 100644 index 00000000000..748f1bf0cca --- /dev/null +++ b/src/mongo/platform/strcasestr.cpp @@ -0,0 +1,100 @@ +/* Copyright 2013 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mongo/platform/strcasestr.h" + +#if defined(__sunos__) +#include <dlfcn.h> + +#include "mongo/base/init.h" +#include "mongo/base/status.h" +#endif + +#if defined(_WIN32) || defined(__sunos__) + +#include <algorithm> +#include <cctype> +#include <cstring> +#include <string> + +#if defined(__sunos__) +#define STRCASESTR_EMULATION_NAME strcasestr_emulation +#else +#define STRCASESTR_EMULATION_NAME strcasestr +#endif + +namespace mongo { +namespace pal { + + /** + * strcasestr -- case-insensitive search for a substring within another string. + * + * @param haystack ptr to C-string to search + * @param needle ptr to C-string to try to find within 'haystack' + * @return ptr to start of 'needle' within 'haystack' if found, NULL otherwise + */ + const char* STRCASESTR_EMULATION_NAME(const char* haystack, const char* needle) { + + std::string haystackLower(haystack); + std::transform(haystackLower.begin(), + haystackLower.end(), + haystackLower.begin(), + ::tolower); + + std::string needleLower(needle); + std::transform(needleLower.begin(), + needleLower.end(), + needleLower.begin(), + ::tolower); + + return strstr(haystackLower.c_str(), needleLower.c_str()); + } + +#if defined(__sunos__) + + typedef const char* (*StrCaseStrFunc)(const char* haystack, const char* needle); + static StrCaseStrFunc strcasestr_switcher = mongo::pal::strcasestr_emulation; + + const char* strcasestr(const char* haystack, const char* needle) { + return strcasestr_switcher(haystack, needle); + } + +#endif // #if defined(__sunos__) + +} // namespace pal +} // namespace mongo + +#endif // #if defined(_WIN32) || defined(__sunos__) + +#if defined(__sunos__) + +namespace mongo { + + // 'strcasestr()' on Solaris will call the emulation if the symbol is not found + // + MONGO_INITIALIZER_GENERAL(SolarisStrCaseCmp, + MONGO_NO_PREREQUISITES, + ("default"))(InitializerContext* context) { + void* functionAddress = dlsym(RTLD_DEFAULT, "strcasestr"); + if (functionAddress != NULL) { + mongo::pal::strcasestr_switcher = + reinterpret_cast<mongo::pal::StrCaseStrFunc>(functionAddress); + } + return Status::OK(); + } + +} // namespace mongo + +#endif // __sunos__ diff --git a/src/mongo/platform/strcasestr.h b/src/mongo/platform/strcasestr.h new file mode 100644 index 00000000000..844374f6915 --- /dev/null +++ b/src/mongo/platform/strcasestr.h @@ -0,0 +1,35 @@ +/* Copyright 2013 10gen Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#if defined(_WIN32) || defined(__sunos__) + +namespace mongo { +namespace pal { + const char* strcasestr(const char* haystack, const char* needle); +} + using mongo::pal::strcasestr; +} + +#else + +#include <cstring> + +namespace mongo { + using ::strcasestr; +} + +#endif |