summaryrefslogtreecommitdiff
path: root/src/mongo/platform
diff options
context:
space:
mode:
authorTad Marshall <tad@10gen.com>2013-06-17 19:25:26 -0400
committerTad Marshall <tad@10gen.com>2013-06-17 19:25:26 -0400
commit75b4cddd29af46fb3902fd5a064bb7093fe68bea (patch)
tree0f5a8b4d12f99367d2a8f5fa812ef1f0a4bdd95d /src/mongo/platform
parentfda4a2342614e4ca1fb26c868a5adef0e050eb5e (diff)
downloadmongo-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/SConscript1
-rw-r--r--src/mongo/platform/strcasestr.cpp100
-rw-r--r--src/mongo/platform/strcasestr.h35
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