summaryrefslogtreecommitdiffstats
path: root/sal/osl/all
diff options
context:
space:
mode:
Diffstat (limited to 'sal/osl/all')
-rw-r--r--sal/osl/all/compat.cxx197
-rw-r--r--sal/osl/all/debugbase.cxx145
-rw-r--r--sal/osl/all/filepath.cxx113
-rw-r--r--sal/osl/all/loadmodulerelative.cxx60
-rw-r--r--sal/osl/all/log.cxx477
-rw-r--r--sal/osl/all/mutexshared.cxx20
-rw-r--r--sal/osl/all/signalshared.cxx141
-rw-r--r--sal/osl/all/utility.cxx49
8 files changed, 1202 insertions, 0 deletions
diff --git a/sal/osl/all/compat.cxx b/sal/osl/all/compat.cxx
new file mode 100644
index 000000000..8fafc628b
--- /dev/null
+++ b/sal/osl/all/compat.cxx
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <cstdlib>
+
+#include <osl/module.h>
+#include <osl/pipe.h>
+#include <osl/socket.h>
+#include <osl/time.h>
+#include <sal/types.h>
+
+// Stubs for removed functionality, to be killed when we bump sal SONAME
+
+extern "C" {
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL osl_acquireSemaphore(void *) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC void SAL_CALL osl_addToSocketSet(void *, oslSocket) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT int SAL_CALL osl_areCommandArgsSet() {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL osl_assertFailedLine(
+ char const *, sal_Int32, char const *)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL osl_breakDebug() {
+ std::abort();
+}
+
+SAL_DLLPUBLIC void SAL_CALL osl_clearSocketSet(void *) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL osl_createSemaphore(sal_uInt32) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC void * SAL_CALL osl_createSocketSet() {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC sal_Int32 SAL_CALL osl_demultiplexSocketEvents(
+ void *, void *, void *, TimeValue const *)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL osl_destroySemaphore(void *) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC void SAL_CALL osl_destroySocketSet(void *) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL osl_getEthernetAddress(sal_uInt8 *) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC sal_Bool SAL_CALL osl_isInSocketSet(void *, oslSocket) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT oslSocket SAL_CALL osl_receiveResourcePipe(oslPipe) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL osl_releaseSemaphore(void *) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Int32 SAL_CALL osl_reportError(
+ sal_uInt32, char const *)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC void SAL_CALL osl_removeFromSocketSet(void *, oslSocket) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL osl_sendResourcePipe(oslPipe, oslSocket)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+namespace {
+typedef void (* pfunc_osl_printDebugMessage)(char const *);
+}
+SAL_DLLPUBLIC_EXPORT pfunc_osl_printDebugMessage SAL_CALL
+osl_setDebugMessageFunc(pfunc_osl_printDebugMessage) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+namespace {
+typedef void (* pfunc_osl_printDetailedDebugMessage)(
+ char const *, sal_Int32, char const *);
+}
+SAL_DLLPUBLIC_EXPORT pfunc_osl_printDetailedDebugMessage SAL_CALL
+osl_setDetailedDebugMessageFunc(pfunc_osl_printDetailedDebugMessage) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL osl_trace(char const *, ...) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL osl_tryToAcquireSemaphore(void *) {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Int32 SAL_CALL rtl_addUnloadingListener(
+ void (SAL_CALL *)(void *), void *)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Int32 SAL_CALL rtl_compareMemory(
+ void const *, void const *, sal_Size)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_copyMemory(
+ void *, void const *, sal_Size)
+{
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_fillMemory(void *, sal_Size, sal_uInt8) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL rtl_findInMemory(
+ void const *, sal_uInt8, sal_Size)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_moveMemory(
+ void *, void const *, sal_Size)
+{
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL rtl_registerModuleForUnloading(oslModule)
+{
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_removeUnloadingListener(sal_Int32) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_unloadUnusedModules(TimeValue *) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_unregisterModuleForUnloading(oslModule) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_zeroMemory(void *, sal_Size) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_logfile_trace( const char*, ... ) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT void SAL_CALL rtl_logfile_longTrace(char const *, ...) {
+ std::abort();
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL rtl_logfile_hasLogFile() {
+ for (;;) { std::abort(); } // avoid "must return a value" warnings
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/all/debugbase.cxx b/sal/osl/all/debugbase.cxx
new file mode 100644
index 000000000..59848a883
--- /dev/null
+++ b/sal/osl/all/debugbase.cxx
@@ -0,0 +1,145 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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 .
+ */
+
+#include <rtl/strbuf.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/process.h>
+#include <osl/diagnose.hxx>
+#include <sal/log.hxx>
+#include <o3tl/string_view.hxx>
+
+#include <algorithm>
+#include <vector>
+
+namespace {
+
+struct StaticDebugBaseAddressFilter
+ : rtl::StaticWithInit<std::vector<OString>, StaticDebugBaseAddressFilter> {
+ std::vector<OString> operator()() const {
+ std::vector<OString> vec;
+ rtl_uString * pStr = nullptr;
+ OUString const name(
+ "OSL_DEBUGBASE_STORE_ADDRESSES" );
+ if (osl_getEnvironment( name.pData, &pStr ) == osl_Process_E_None) {
+ OUString const str(pStr);
+ rtl_uString_release(pStr);
+ sal_Int32 nIndex = 0;
+ do {
+ vec.push_back( OUStringToOString(
+ o3tl::getToken(str, 0, ';', nIndex ),
+ RTL_TEXTENCODING_ASCII_US ) );
+ }
+ while (nIndex >= 0);
+ }
+ return vec;
+ }
+};
+
+bool isSubStr( char const* pStr, OString const& subStr )
+{
+ return rtl_str_indexOfStr( pStr, subStr.getStr() ) >= 0;
+}
+
+} // anon namespace
+
+extern "C" {
+
+// These functions presumably should not be extern "C", but changing
+// that would break binary compatibility.
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
+#endif
+
+osl::Mutex & SAL_CALL osl_detail_ObjectRegistry_getMutex()
+ SAL_THROW_EXTERN_C()
+{
+ static osl::Mutex aMutex;
+ return aMutex;
+}
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+bool SAL_CALL osl_detail_ObjectRegistry_storeAddresses( char const* pName )
+ SAL_THROW_EXTERN_C()
+{
+ std::vector<OString> const& rVec = StaticDebugBaseAddressFilter::get();
+ if (rVec.empty())
+ return false;
+ // check for "all":
+ OString const& rFirst = rVec[0];
+ if ( rFirst == "all" )
+ return true;
+ auto const iEnd( rVec.cend() );
+ return std::any_of( rVec.begin(), iEnd,
+ [pName] (OString const& it) { return isSubStr(pName, it); });
+}
+
+bool SAL_CALL osl_detail_ObjectRegistry_checkObjectCount(
+ osl::detail::ObjectRegistryData const& rData, std::size_t nExpected )
+ SAL_THROW_EXTERN_C()
+{
+ std::size_t nSize;
+ if (rData.m_bStoreAddresses)
+ nSize = rData.m_addresses.size();
+ else
+ nSize = static_cast<std::size_t>(rData.m_nCount);
+
+ bool const bRet = (nSize == nExpected);
+ SAL_WARN_IF(
+ !bRet, "sal.osl",
+ "unexpected number of " << rData.m_pName << ": " << nSize
+ << "; Expected: " << nExpected);
+ return bRet;
+}
+
+void SAL_CALL osl_detail_ObjectRegistry_registerObject(
+ osl::detail::ObjectRegistryData & rData, void const* pObj )
+ SAL_THROW_EXTERN_C()
+{
+ if (rData.m_bStoreAddresses) {
+ osl::MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
+ std::pair<osl::detail::VoidPointerSet::iterator, bool> const insertion(
+ rData.m_addresses.insert(pObj) );
+ SAL_WARN_IF(!insertion.second, "sal.osl", "insertion failed!?");
+ }
+ else {
+ osl_atomic_increment(&rData.m_nCount);
+ }
+}
+
+void SAL_CALL osl_detail_ObjectRegistry_revokeObject(
+ osl::detail::ObjectRegistryData & rData, void const* pObj )
+ SAL_THROW_EXTERN_C()
+{
+ if (rData.m_bStoreAddresses) {
+ osl::MutexGuard const guard( osl_detail_ObjectRegistry_getMutex() );
+ std::size_t const n = rData.m_addresses.erase(pObj);
+ SAL_WARN_IF(n != 1, "sal.osl", "erased more than 1 entry!?");
+ }
+ else {
+ osl_atomic_decrement(&rData.m_nCount);
+ }
+}
+
+} // extern "C"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/all/filepath.cxx b/sal/osl/all/filepath.cxx
new file mode 100644
index 000000000..afba01739
--- /dev/null
+++ b/sal/osl/all/filepath.cxx
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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 .
+ */
+
+#include <osl/file.h>
+#include <rtl/ustring.h>
+#include <cassert>
+
+static sal_uInt32 osl_defCalcTextWidth( rtl_uString *ustrText )
+{
+ return ustrText ? ustrText->length : 0;
+}
+
+oslFileError SAL_CALL osl_abbreviateSystemPath( rtl_uString *ustrSystemPath, rtl_uString **pustrCompacted, sal_uInt32 uMaxWidth, oslCalcTextWidthFunc pfnCalcWidth )
+{
+ rtl_uString *ustrPath = nullptr;
+ rtl_uString *ustrFile = nullptr;
+ sal_uInt32 uPathWidth, uFileWidth;
+
+ if ( !pfnCalcWidth )
+ pfnCalcWidth = osl_defCalcTextWidth;
+
+ {
+ sal_Int32 iLastSlash = rtl_ustr_lastIndexOfChar_WithLength( ustrSystemPath->buffer, ustrSystemPath->length, SAL_PATHDELIMITER );
+
+ if ( iLastSlash >= 0 )
+ {
+ rtl_uString_newFromStr_WithLength( &ustrPath, ustrSystemPath->buffer, iLastSlash );
+ rtl_uString_newFromStr_WithLength( &ustrFile, &ustrSystemPath->buffer[iLastSlash], ustrSystemPath->length - iLastSlash );
+ }
+ else
+ {
+ rtl_uString_new( &ustrPath );
+ rtl_uString_newFromString( &ustrFile, ustrSystemPath );
+ }
+ }
+
+ assert(ustrPath && ustrFile);
+
+ uPathWidth = pfnCalcWidth( ustrPath );
+ uFileWidth = pfnCalcWidth( ustrFile );
+
+ /* First abbreviate the directory component of the path */
+
+ while ( uPathWidth + uFileWidth > uMaxWidth )
+ {
+ if ( ustrPath->length > 3 )
+ {
+ ustrPath->length--;
+ ustrPath->buffer[ustrPath->length-3] = '.';
+ ustrPath->buffer[ustrPath->length-2] = '.';
+ ustrPath->buffer[ustrPath->length-1] = '.';
+ ustrPath->buffer[ustrPath->length] = 0;
+
+ uPathWidth = pfnCalcWidth( ustrPath );
+ }
+ else
+ break;
+ }
+
+ /* Now abbreviate file component */
+
+ while ( uPathWidth + uFileWidth > uMaxWidth )
+ {
+ if ( ustrFile->length > 4 )
+ {
+ ustrFile->length--;
+ ustrFile->buffer[ustrFile->length-3] = '.';
+ ustrFile->buffer[ustrFile->length-2] = '.';
+ ustrFile->buffer[ustrFile->length-1] = '.';
+ ustrFile->buffer[ustrFile->length] = 0;
+
+ uFileWidth = pfnCalcWidth( ustrFile );
+ }
+ else
+ break;
+ }
+
+ rtl_uString_newConcat( pustrCompacted, ustrPath, ustrFile );
+
+ /* Event now if path was compacted to ".../..." it can be too large */
+
+ uPathWidth += uFileWidth;
+
+ while ( uPathWidth > uMaxWidth )
+ {
+ (*pustrCompacted)->length--;
+ (*pustrCompacted)->buffer[(*pustrCompacted)->length] = 0;
+ uPathWidth = pfnCalcWidth( *pustrCompacted );
+ }
+
+ rtl_uString_release(ustrPath);
+ rtl_uString_release(ustrFile);
+
+ return osl_File_E_None;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/all/loadmodulerelative.cxx b/sal/osl/all/loadmodulerelative.cxx
new file mode 100644
index 000000000..242bb6210
--- /dev/null
+++ b/sal/osl/all/loadmodulerelative.cxx
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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 .
+ */
+
+#include <sal/config.h>
+
+#include <cstddef>
+
+#include <sal/log.hxx>
+#include <osl/module.h>
+#include <osl/module.hxx>
+#include <rtl/malformeduriexception.hxx>
+#include <rtl/uri.hxx>
+#include <rtl/ustring.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+extern "C" {
+
+#ifndef DISABLE_DYNLOADING
+
+oslModule SAL_CALL osl_loadModuleRelative(
+ oslGenericFunction const baseModule, rtl_uString * const relativePath,
+ sal_Int32 const mode)
+{
+ OUString base;
+ if (!osl::Module::getUrlFromAddress(baseModule, base)) {
+ SAL_INFO("sal.osl","osl::Module::getUrlFromAddress failed");
+ return nullptr;
+ }
+ OUString abs;
+ try {
+ abs = rtl::Uri::convertRelToAbs(base, relativePath);
+ } catch (const rtl::MalformedUriException & e) {
+ SAL_INFO("sal.osl", "rtl::MalformedUriException <" << e.getMessage() << ">");
+ return nullptr;
+ }
+ return osl_loadModule(abs.pData, mode);
+}
+
+#endif // !DISABLE_DYNLOADING
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/all/log.cxx b/sal/osl/all/log.cxx
new file mode 100644
index 000000000..405d5599c
--- /dev/null
+++ b/sal/osl/all/log.cxx
@@ -0,0 +1,477 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <cassert>
+#include <cstdarg>
+#include <cstddef>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+#include <stdio.h>
+#include <string.h>
+#include <fstream>
+
+#include <config_global.h>
+#include <osl/thread.hxx>
+#include <rtl/string.h>
+#include <sal/detail/log.h>
+#include <sal/log.hxx>
+#include <sal/types.h>
+#include <backtraceasstring.hxx>
+#include <salusesyslog.hxx>
+
+#if defined ANDROID
+#include <android/log.h>
+#elif defined _WIN32
+#include <process.h>
+#include <windows.h>
+#define OSL_DETAIL_GETPID _getpid()
+#else
+#include <unistd.h>
+#define OSL_DETAIL_GETPID getpid()
+#endif
+
+#if HAVE_SYSLOG_H
+#include <syslog.h>
+// sal/osl/unx/salinit.cxx::sal_detail_initialize updates this:
+bool sal_use_syslog;
+#else
+bool const sal_use_syslog = false;
+#endif
+
+// Avoid the use of other sal code in this file as much as possible, so that
+// this code can be called from other sal code without causing endless
+// recursion.
+
+namespace {
+
+struct TimeContainer
+{
+ TimeValue aTime;
+ TimeContainer()
+ {
+ osl_getSystemTime(&aTime);
+ }
+};
+
+TimeContainer aStartTime;
+
+bool equalStrings(
+ char const * string1, std::size_t length1, char const * string2,
+ std::size_t length2)
+{
+ return length1 == length2 && std::memcmp(string1, string2, length1) == 0;
+}
+
+#if !defined ANDROID
+char const * toString(sal_detail_LogLevel level) {
+ switch (level) {
+ case SAL_DETAIL_LOG_LEVEL_INFO:
+ return "info";
+ case SAL_DETAIL_LOG_LEVEL_WARN:
+ return "warn";
+ case SAL_DETAIL_LOG_LEVEL_DEBUG:
+ return "debug";
+ default:
+ assert(false); // this cannot happen
+ return "broken";
+ }
+}
+#endif
+
+#ifdef _WIN32
+
+char const* setEnvFromLoggingIniFile(const char* env, const char* key)
+{
+ char const* sResult = nullptr;
+ wchar_t buffer[MAX_PATH];
+ GetModuleFileNameW(nullptr, buffer, MAX_PATH);
+ std::wstring sProgramDirectory(buffer);
+ std::wstring::size_type pos = sProgramDirectory.find_last_of(L"\\/");
+ sProgramDirectory = sProgramDirectory.substr(0, pos+1);
+ sProgramDirectory += L"logging.ini";
+
+ std::ifstream logFileStream(sProgramDirectory);
+ if (!logFileStream.good())
+ return sResult;
+
+ std::size_t n;
+ std::string aKey;
+ std::string sWantedKey(key);
+ std::string sLine;
+ while (std::getline(logFileStream, sLine)) {
+ if (sLine.find('#') == 0)
+ continue;
+ if ( ( n = sLine.find('=') ) != std::string::npos) {
+ aKey = sLine.substr(0, n);
+ if (aKey != sWantedKey)
+ continue;
+ _putenv_s(env, sLine.substr(n+1, sLine.length()).c_str());
+ sResult = std::getenv(env);
+ break;
+ }
+ }
+ return sResult;
+}
+#endif
+
+char const* pLogSelector = nullptr;
+
+char const* getLogLevelEnvVar() {
+ static char const* const pLevel = [] {
+ char const* pResult = nullptr;
+
+ // First check the environment variable, then the setting in logging.ini
+ char const* env = std::getenv("SAL_LOG");
+
+#ifdef _WIN32
+ if (!env)
+ env = setEnvFromLoggingIniFile("SAL_LOG", "LogLevel");
+#endif
+
+ if (env)
+ {
+ // Make a copy from the string in environment block
+ static std::string sLevel(env);
+ pResult = sLevel.c_str();
+ }
+ return pResult;
+ }();
+
+ return pLevel;
+}
+
+#if !defined ANDROID
+
+std::ofstream * getLogFile() {
+ static std::ofstream* const pFile = [] {
+ std::ofstream* pResult = nullptr;
+
+ // First check the environment variable, then the setting in logging.ini
+ char const* logFile = std::getenv("SAL_LOG_FILE");
+
+#ifdef _WIN32
+ if (!logFile)
+ logFile = setEnvFromLoggingIniFile("SAL_LOG_FILE", "LogFilePath");
+#endif
+
+ if (logFile)
+ {
+ // stays until process exits
+ static std::ofstream file(logFile, std::ios::app | std::ios::out);
+ pResult = &file;
+ }
+
+ return pResult;
+ }();
+
+ return pFile;
+}
+
+
+std::pair<bool, bool> getTimestampFlags(char const *selector)
+{
+ bool outputTimestamp = false;
+ bool outputRelativeTimer = false;
+ for (char const* p = selector; p && *p;)
+ {
+ if (*p++ == '+')
+ {
+ char const * p1 = p;
+ while (*p1 != '.' && *p1 != '+' && *p1 != '-' && *p1 != '\0') {
+ ++p1;
+ }
+ if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("TIMESTAMP")))
+ outputTimestamp = true;
+ else if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("RELATIVETIMER")))
+ outputRelativeTimer = true;
+ char const * p2 = p1;
+ while (*p2 != '+' && *p2 != '-' && *p2 != '\0') {
+ ++p2;
+ }
+ p = p2;
+ }
+ }
+ return std::pair(outputTimestamp, outputRelativeTimer);
+}
+
+void maybeOutputTimestamp(std::ostringstream &s) {
+ static const std::pair<bool, bool> aEnvFlags = getTimestampFlags(getLogLevelEnvVar());
+ const auto& [outputTimestamp, outputRelativeTimer] = (pLogSelector == nullptr ? aEnvFlags : getTimestampFlags(pLogSelector));
+
+ if (outputTimestamp)
+ {
+ char ts[100];
+ TimeValue systemTime;
+ osl_getSystemTime(&systemTime);
+ TimeValue localTime;
+ osl_getLocalTimeFromSystemTime(&systemTime, &localTime);
+ oslDateTime dateTime;
+ osl_getDateTimeFromTimeValue(&localTime, &dateTime);
+ struct tm tm;
+ tm.tm_sec = dateTime.Seconds;
+ tm.tm_min = dateTime.Minutes;
+ tm.tm_hour = dateTime.Hours;
+ tm.tm_mday = dateTime.Day;
+ tm.tm_wday = dateTime.DayOfWeek;
+ tm.tm_mon = dateTime.Month - 1;
+ tm.tm_year = dateTime.Year - 1900;
+ tm.tm_yday = 0;
+ strftime(ts, sizeof(ts), "%Y-%m-%d:%H:%M:%S", &tm);
+ char milliSecs[11];
+ snprintf(milliSecs, sizeof(milliSecs), "%03u",
+ static_cast<unsigned>(dateTime.NanoSeconds / 1000000));
+ s << ts << '.' << milliSecs << ':';
+ }
+ if (!outputRelativeTimer)
+ return;
+
+ TimeValue now;
+ osl_getSystemTime(&now);
+ int seconds = now.Seconds - aStartTime.aTime.Seconds;
+ int milliSeconds;
+ if (now.Nanosec < aStartTime.aTime.Nanosec)
+ {
+ seconds--;
+ milliSeconds = 1000 - (aStartTime.aTime.Nanosec - now.Nanosec) / 1000000;
+ }
+ else
+ milliSeconds = (now.Nanosec - aStartTime.aTime.Nanosec) / 1000000;
+ char relativeTimestamp[100];
+ snprintf(relativeTimestamp, sizeof(relativeTimestamp), "%d.%03d", seconds, milliSeconds);
+ s << relativeTimestamp << ':';
+}
+
+#endif
+
+}
+
+void sal_detail_log(
+ sal_detail_LogLevel level, char const * area, char const * where,
+ char const * message, sal_uInt32 backtraceDepth)
+{
+ std::ostringstream s;
+#if !defined ANDROID
+ // On Android, the area will be used as the "tag," and log info already
+ // contains timestamp and PID.
+ if (!sal_use_syslog) {
+ maybeOutputTimestamp(s);
+ s << toString(level) << ':';
+ }
+ if (level != SAL_DETAIL_LOG_LEVEL_DEBUG) {
+ s << area << ':';
+ }
+ s << OSL_DETAIL_GETPID << ':';
+#endif
+ s << osl::Thread::getCurrentIdentifier() << ':';
+ if (level == SAL_DETAIL_LOG_LEVEL_DEBUG) {
+ s << ' ';
+ } else {
+ const size_t nStrLen(std::strlen(SRCDIR "/"));
+ s << (where
+ + (std::strncmp(where, SRCDIR "/", nStrLen) == 0
+ ? nStrLen : 0));
+ }
+ s << message;
+ if (backtraceDepth != 0) {
+ s << " at:\n" << osl::detail::backtraceAsString(backtraceDepth);
+ }
+
+#if defined ANDROID
+ int android_log_level;
+ switch (level) {
+ case SAL_DETAIL_LOG_LEVEL_INFO:
+ android_log_level = ANDROID_LOG_INFO;
+ break;
+ case SAL_DETAIL_LOG_LEVEL_WARN:
+ android_log_level = ANDROID_LOG_WARN;
+ break;
+ case SAL_DETAIL_LOG_LEVEL_DEBUG:
+ android_log_level = ANDROID_LOG_DEBUG;
+ break;
+ default:
+ android_log_level = ANDROID_LOG_INFO;
+ break;
+ }
+ __android_log_print(
+ android_log_level, area == 0 ? "LibreOffice" : area, "%s",
+ s.str().c_str());
+#else
+ if (sal_use_syslog) {
+#if HAVE_SYSLOG_H
+ int prio;
+ switch (level) {
+ case SAL_DETAIL_LOG_LEVEL_INFO:
+ prio = LOG_INFO;
+ break;
+ case SAL_DETAIL_LOG_LEVEL_WARN:
+ prio = LOG_WARNING;
+ break;
+ case SAL_DETAIL_LOG_LEVEL_DEBUG:
+ prio = LOG_DEBUG;
+ break;
+ default:
+ assert(false); // this cannot happen
+ prio = LOG_WARNING;
+ }
+ syslog(prio, "%s", s.str().c_str());
+#endif
+ } else {
+ // avoid calling getLogFile() more than once
+ static std::ofstream * logFile = getLogFile();
+ if (logFile) {
+ *logFile << s.str() << std::endl;
+ }
+ else {
+ s << '\n';
+#ifdef _WIN32
+ // write to Windows debugger console, too
+ OutputDebugStringA(s.str().c_str());
+#endif
+ std::fputs(s.str().c_str(), stderr);
+ std::fflush(stderr);
+ }
+ }
+#endif
+}
+
+void sal_detail_set_log_selector(char const *logSelector)
+{
+ pLogSelector = logSelector;
+}
+
+void sal_detail_logFormat(
+ sal_detail_LogLevel level, char const * area, char const * where,
+ char const * format, ...)
+{
+ const sal_detail_LogAction eAction
+ = static_cast<sal_detail_LogAction>(sal_detail_log_report(level, area));
+ if (eAction == SAL_DETAIL_LOG_ACTION_IGNORE)
+ return;
+
+ std::va_list args;
+ va_start(args, format);
+ char buf[1024];
+ int const len = sizeof buf - RTL_CONSTASCII_LENGTH("...");
+ int n = vsnprintf(buf, len, format, args);
+ if (n < 0) {
+ std::strcpy(buf, "???");
+ } else if (n >= len) {
+ std::strcpy(buf + len - 1, "...");
+ }
+ sal_detail_log(level, area, where, buf, 0);
+ va_end(args);
+
+ if (eAction == SAL_DETAIL_LOG_ACTION_FATAL)
+ std::abort();
+}
+
+unsigned char sal_detail_log_report(sal_detail_LogLevel level, char const * area)
+{
+ if (level == SAL_DETAIL_LOG_LEVEL_DEBUG) {
+ return SAL_DETAIL_LOG_ACTION_LOG;
+ }
+ assert(area != nullptr);
+ static char const* const envEnv = [] {
+ char const* pResult = getLogLevelEnvVar();
+ if (!pResult)
+ pResult = "+WARN";
+ return pResult;
+ }();
+ char const* const env = (pLogSelector == nullptr ? envEnv : pLogSelector);
+ std::size_t areaLen = std::strlen(area);
+ enum Sense { POSITIVE = 0, NEGATIVE = 1 };
+ std::size_t senseLen[2] = { 0, 1 };
+ // initial senseLen[POSITIVE] < senseLen[NEGATIVE], so that if there are
+ // no matching switches at all, the result will be negative (and
+ // initializing with 1 is safe as the length of a valid switch, even
+ // without the "+"/"-" prefix, will always be > 1)
+ bool senseFatal[2] = { false, false };
+ bool seenWarn = false;
+ bool bFlagFatal = false;
+ for (char const * p = env;;) {
+ Sense sense;
+ switch (*p++) {
+ case '\0':
+ {
+ if (level == SAL_DETAIL_LOG_LEVEL_WARN && !seenWarn)
+ return sal_detail_log_report(SAL_DETAIL_LOG_LEVEL_INFO, area);
+
+ sal_detail_LogAction eAction = SAL_DETAIL_LOG_ACTION_IGNORE;
+ // if a specific item is positive and negative (==), default to positive
+ if (senseLen[POSITIVE] >= senseLen[NEGATIVE])
+ {
+ if (senseFatal[POSITIVE]) eAction = SAL_DETAIL_LOG_ACTION_FATAL;
+ else eAction = SAL_DETAIL_LOG_ACTION_LOG;
+ }
+ return eAction;
+ }
+ case '+':
+ sense = POSITIVE;
+ break;
+ case '-':
+ sense = NEGATIVE;
+ break;
+ default:
+ return SAL_DETAIL_LOG_ACTION_LOG; // upon an illegal SAL_LOG value, enable everything
+ }
+ char const * p1 = p;
+ while (*p1 != '.' && *p1 != '+' && *p1 != '-' && *p1 != '\0') {
+ ++p1;
+ }
+ bool match;
+ if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("INFO"))) {
+ match = level == SAL_DETAIL_LOG_LEVEL_INFO;
+ } else if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("WARN")))
+ {
+ match = level == SAL_DETAIL_LOG_LEVEL_WARN;
+ seenWarn = true;
+ } else if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("FATAL")))
+ {
+ bFlagFatal = (sense == POSITIVE);
+ match = false;
+ } else if (equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("TIMESTAMP")) ||
+ equalStrings(p, p1 - p, RTL_CONSTASCII_STRINGPARAM("RELATIVETIMER")))
+ {
+ // handled later
+ match = false;
+ } else {
+ return SAL_DETAIL_LOG_ACTION_LOG;
+ // upon an illegal SAL_LOG value, everything is considered
+ // positive
+ }
+ char const * p2 = p1;
+ while (*p2 != '+' && *p2 != '-' && *p2 != '\0') {
+ ++p2;
+ }
+ if (match) {
+ if (*p1 == '.') {
+ ++p1;
+ std::size_t n = p2 - p1;
+ if ((n == areaLen && equalStrings(p1, n, area, areaLen))
+ || (n < areaLen && area[n] == '.'
+ && equalStrings(p1, n, area, n)))
+ {
+ senseLen[sense] = p2 - p;
+ senseFatal[sense] = bFlagFatal;
+ }
+ } else {
+ senseLen[sense] = p1 - p;
+ senseFatal[sense] = bFlagFatal;
+ }
+ }
+ p = p2;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/all/mutexshared.cxx b/sal/osl/all/mutexshared.cxx
new file mode 100644
index 000000000..3de7f9930
--- /dev/null
+++ b/sal/osl/all/mutexshared.cxx
@@ -0,0 +1,20 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <sal/config.h>
+
+#include <osl/mutex.hxx>
+
+oslMutex* SAL_CALL osl_getGlobalMutex()
+{
+ static osl::Mutex g_Mutex;
+ return &g_Mutex.mutex;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sal/osl/all/signalshared.cxx b/sal/osl/all/signalshared.cxx
new file mode 100644
index 000000000..530413f26
--- /dev/null
+++ b/sal/osl/all/signalshared.cxx
@@ -0,0 +1,141 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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 .
+ */
+
+#include <sal/config.h>
+
+#include <stdlib.h>
+
+#include <signalshared.hxx>
+
+#include <osl/diagnose.h>
+#include <mutex>
+
+namespace
+{
+oslSignalHandlerImpl* SignalList;
+bool bInitSignal = false;
+
+std::mutex& getSignalMutex()
+{
+ static std::mutex aMutex;
+ return aMutex;
+}
+}
+
+oslSignalAction callSignalHandler(oslSignalInfo* pInfo)
+{
+ oslSignalHandlerImpl* pHandler = SignalList;
+ oslSignalAction Action = osl_Signal_ActCallNextHdl;
+
+ while (pHandler)
+ {
+ if ((Action = pHandler->Handler(pHandler->pData, pInfo)) != osl_Signal_ActCallNextHdl)
+ break;
+
+ pHandler = pHandler->pNext;
+ }
+
+ return Action;
+}
+
+oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction handler, void* pData)
+{
+ if (!handler)
+ return nullptr;
+
+ oslSignalHandlerImpl* pHandler
+ = static_cast<oslSignalHandlerImpl*>(calloc(1, sizeof(oslSignalHandlerImpl)));
+
+ std::scoped_lock aGuard(getSignalMutex());
+
+ if (!bInitSignal)
+ bInitSignal = onInitSignal();
+
+ if (pHandler)
+ {
+ pHandler->Handler = handler;
+ pHandler->pData = pData;
+
+ pHandler->pNext = SignalList;
+ SignalList = pHandler;
+
+ return pHandler;
+ }
+
+ return nullptr;
+}
+
+sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler handler)
+{
+ std::scoped_lock aGuard(getSignalMutex());
+
+ if (!bInitSignal)
+ bInitSignal = onInitSignal();
+
+ oslSignalHandlerImpl* pHandler = SignalList;
+ oslSignalHandlerImpl* pPrevious = nullptr;
+
+ while (pHandler)
+ {
+ if (pHandler == handler)
+ {
+ if (pPrevious)
+ pPrevious->pNext = pHandler->pNext;
+ else
+ SignalList = pHandler->pNext;
+
+ if (SignalList == nullptr)
+ bInitSignal = onDeInitSignal();
+
+ free(pHandler);
+
+ return true;
+ }
+
+ pPrevious = pHandler;
+ pHandler = pHandler->pNext;
+ }
+
+ return false;
+}
+
+oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 userSignal, void* userData)
+{
+ std::scoped_lock aGuard(getSignalMutex());
+
+ if (!bInitSignal)
+ bInitSignal = onInitSignal();
+
+ oslSignalInfo info;
+ info.Signal = osl_Signal_User;
+ info.UserSignal = userSignal;
+ info.UserData = userData;
+
+ oslSignalAction action = callSignalHandler(&info);
+
+ return action;
+}
+
+sal_Bool SAL_CALL osl_setErrorReporting(sal_Bool /*bEnable*/)
+{
+ // this is part of the stable API
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sal/osl/all/utility.cxx b/sal/osl/all/utility.cxx
new file mode 100644
index 000000000..e22bdd3de
--- /dev/null
+++ b/sal/osl/all/utility.cxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you 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 .
+ */
+
+#include <osl/time.h>
+
+/*
+ * mfe : maybe it would be wishful to include initialization
+ * of the global timer in dllmain or _init directly.
+ * But nonetheless this (should) work too.
+ */
+namespace osl
+{
+
+namespace {
+
+class OGlobalTimer
+{
+
+public:
+
+ OGlobalTimer() {
+ osl_getGlobalTimer();
+ }
+
+};
+
+}
+
+static OGlobalTimer aGlobalTimer;
+
+} // namespace osl
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */