LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sal/osl/unx - signal.c (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 94 185 50.8 %
Date: 2013-07-09 Functions: 7 13 53.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : /* system headers */
      22             : #include "system.h"
      23             : 
      24             : #if defined( MACOSX )
      25             : 
      26             : #if defined( INTEL )
      27             : #include "backtrace.h"
      28             : #define INCLUDE_BACKTRACE
      29             : #ifdef SAL_ENABLE_CRASH_REPORT
      30             : #define STACKTYPE "MacOsX_X86"
      31             : #endif
      32             : #endif /* INTEL */
      33             : 
      34             : #endif /* MACOSX */
      35             : 
      36             : #ifdef LINUX
      37             : #include <execinfo.h>
      38             : #include <link.h>
      39             : #define INCLUDE_BACKTRACE
      40             : #if defined SAL_ENABLE_CRASH_REPORT
      41             : #define STACKTYPE "Linux"
      42             : #endif
      43             : #endif
      44             : 
      45             : #ifdef SOLARIS
      46             : 
      47             : #include "backtrace.h"
      48             : #define INCLUDE_BACKTRACE
      49             : 
      50             : #if defined SAL_ENABLE_CRASH_REPORT
      51             : #if defined( SPARC )
      52             : #define STACKTYPE "Solaris_Sparc"
      53             : #elif defined( INTEL )
      54             : #define STACKTYPE "Solaris_X86"
      55             : #else
      56             : #define STACKTYPE "Solaris_Unknown"
      57             : #endif
      58             : #endif
      59             : 
      60             : #endif /* defined SOLARIS */
      61             : 
      62             : #if defined INCLUDE_BACKTRACE
      63             : #define MAX_STACK_FRAMES 256
      64             : #endif
      65             : 
      66             : #include <osl/diagnose.h>
      67             : #include <osl/mutex.h>
      68             : #include <osl/signal.h>
      69             : #include <osl/process.h>
      70             : #include <osl/thread.h>
      71             : #include <sal/macros.h>
      72             : #include <rtl/bootstrap.h>
      73             : #include <rtl/digest.h>
      74             : 
      75             : #include "file_path_helper.h"
      76             : 
      77             : #define ACT_IGNORE  1
      78             : #define ACT_EXIT    2
      79             : #define ACT_SYSTEM  3
      80             : #define ACT_HIDE    4
      81             : #ifdef SAL_ENABLE_CRASH_REPORT
      82             : #    define ACT_ABORT   5
      83             : #else
      84             : #    define ACT_ABORT   ACT_SYSTEM
      85             : #endif
      86             : 
      87             : #if defined HAVE_VALGRIND_HEADERS
      88             : #include <valgrind/memcheck.h>
      89             : #endif
      90             : 
      91             : typedef struct _oslSignalHandlerImpl
      92             : {
      93             :     oslSignalHandlerFunction      Handler;
      94             :     void*                         pData;
      95             :     struct _oslSignalHandlerImpl* pNext;
      96             : } oslSignalHandlerImpl;
      97             : 
      98             : static struct SignalAction
      99             : {
     100             :     int Signal;
     101             :     int Action;
     102             :     void (*Handler)(int);
     103             : } Signals[] =
     104             : {
     105             :     { SIGHUP,    ACT_HIDE, NULL },    /* hangup */
     106             :     { SIGINT,    ACT_EXIT,   NULL },    /* interrupt (rubout) */
     107             :     { SIGQUIT,   ACT_EXIT,  NULL },    /* quit (ASCII FS) */
     108             :     { SIGILL,    ACT_SYSTEM,  NULL },    /* illegal instruction (not reset when caught) */
     109             : /* changed from ACT_ABOUT to ACT_SYSTEM to try and get collector to run*/
     110             :     { SIGTRAP,   ACT_ABORT,  NULL },    /* trace trap (not reset when caught) */
     111             : #if ( SIGIOT != SIGABRT )
     112             :     { SIGIOT,    ACT_ABORT,  NULL },    /* IOT instruction */
     113             : #endif
     114             :     { SIGABRT,   ACT_ABORT,  NULL },    /* used by abort, replace SIGIOT in the future */
     115             : #ifdef SIGEMT
     116             :     { SIGEMT,    ACT_SYSTEM,  NULL },    /* EMT instruction */
     117             : /* changed from ACT_ABORT to ACT_SYSTEM to remove handler*/
     118             : /* SIGEMT may also be used by the profiler - so it is probably not a good
     119             : plan to have the new handler use this signal*/
     120             : #endif
     121             :     { SIGFPE,    ACT_ABORT,  NULL },    /* floating point exception */
     122             :     { SIGKILL,   ACT_SYSTEM, NULL },    /* kill (cannot be caught or ignored) */
     123             :     { SIGBUS,    ACT_ABORT,  NULL },    /* bus error */
     124             :     { SIGSEGV,   ACT_ABORT,  NULL },    /* segmentation violation */
     125             : #ifdef SIGSYS
     126             :     { SIGSYS,    ACT_ABORT,  NULL },    /* bad argument to system call */
     127             : #endif
     128             :     { SIGPIPE,   ACT_HIDE,   NULL },    /* write on a pipe with no one to read it */
     129             :     { SIGALRM,   ACT_EXIT,   NULL },    /* alarm clock */
     130             :     { SIGTERM,   ACT_EXIT,   NULL },    /* software termination signal from kill */
     131             :     { SIGUSR1,   ACT_SYSTEM, NULL },    /* user defined signal 1 */
     132             :     { SIGUSR2,   ACT_SYSTEM, NULL },    /* user defined signal 2 */
     133             :     { SIGCHLD,   ACT_SYSTEM, NULL },    /* child status change */
     134             : #ifdef SIGPWR
     135             :     { SIGPWR,    ACT_IGNORE, NULL },    /* power-fail restart */
     136             : #endif
     137             :     { SIGWINCH,  ACT_IGNORE, NULL },    /* window size change */
     138             :     { SIGURG,    ACT_EXIT,   NULL },    /* urgent socket condition */
     139             : #ifdef SIGPOLL
     140             :     { SIGPOLL,   ACT_EXIT,   NULL },    /* pollable event occurred */
     141             : #endif
     142             :     { SIGSTOP,   ACT_SYSTEM, NULL },    /* stop (cannot be caught or ignored) */
     143             :     { SIGTSTP,   ACT_SYSTEM, NULL },    /* user stop requested from tty */
     144             :     { SIGCONT,   ACT_SYSTEM, NULL },    /* stopped process has been continued */
     145             :     { SIGTTIN,   ACT_SYSTEM, NULL },    /* background tty read attempted */
     146             :     { SIGTTOU,   ACT_SYSTEM, NULL },    /* background tty write attempted */
     147             :     { SIGVTALRM, ACT_EXIT,   NULL },    /* virtual timer expired */
     148             :     { SIGPROF,   ACT_SYSTEM,   NULL },    /* profiling timer expired */
     149             : /*Change from ACT_EXIT to ACT_SYSTEM for SIGPROF is so that profiling signals do
     150             : not get taken by the new handler - the new handler does not pass on context
     151             : information which causes 'collect' to crash. This is a way of avoiding
     152             : what looks like a bug in the new handler*/
     153             :     { SIGXCPU,   ACT_ABORT,  NULL },    /* exceeded cpu limit */
     154             :     { SIGXFSZ,   ACT_ABORT,  NULL }     /* exceeded file size limit */
     155             : };
     156             : const int NoSignals = sizeof(Signals) / sizeof(struct SignalAction);
     157             : 
     158             : static sal_Bool               bErrorReportingEnabled = sal_True;
     159             : static sal_Bool               bInitSignal = sal_False;
     160             : static oslMutex               SignalListMutex;
     161             : static oslSignalHandlerImpl*  SignalList;
     162             : static sal_Bool               bDoHardKill = sal_False;
     163             : static sal_Bool               bSetSEGVHandler = sal_False;
     164             : static sal_Bool               bSetWINCHHandler = sal_False;
     165             : static sal_Bool               bSetILLHandler = sal_False;
     166             : 
     167             : static void SignalHandlerFunction(int);
     168             : 
     169         151 : static void getExecutableName_Impl (rtl_String ** ppstrProgName)
     170             : {
     171         151 :     rtl_uString * ustrProgFile = 0;
     172         151 :     osl_getExecutableFile (&ustrProgFile);
     173         151 :     if (ustrProgFile)
     174             :     {
     175         150 :         rtl_uString * ustrProgName = 0;
     176         150 :         osl_systemPathGetFileNameOrLastDirectoryPart (ustrProgFile, &ustrProgName);
     177         150 :         if (ustrProgName != 0)
     178             :         {
     179         300 :             rtl_uString2String (
     180             :                 ppstrProgName,
     181         150 :                 rtl_uString_getStr (ustrProgName), rtl_uString_getLength (ustrProgName),
     182         150 :                 osl_getThreadTextEncoding(),
     183             :                 OUSTRING_TO_OSTRING_CVTFLAGS);
     184         150 :             rtl_uString_release (ustrProgName);
     185             :         }
     186         150 :         rtl_uString_release (ustrProgFile);
     187             :     }
     188         151 : }
     189             : 
     190         151 : static sal_Bool is_soffice_Impl (void)
     191             : {
     192         151 :     sal_Int32    idx       = -1;
     193         151 :     rtl_String * strProgName = 0;
     194             : 
     195         151 :     getExecutableName_Impl (&strProgName);
     196         151 :     if (strProgName)
     197             :     {
     198         150 :         idx = rtl_str_indexOfStr (rtl_string_getStr (strProgName), "soffice");
     199         150 :         rtl_string_release (strProgName);
     200             :     }
     201         151 :     return (idx != -1);
     202             : }
     203             : 
     204         151 : static sal_Bool InitSignal()
     205             : {
     206             :     int i;
     207             :     struct sigaction act;
     208             :     struct sigaction oact;
     209             :     sigset_t unset;
     210             : 
     211         151 :     if (is_soffice_Impl())
     212             :     {
     213             :         sal_uInt32  argi;
     214             :         sal_uInt32  argc;
     215          83 :         rtl_uString *ustrCommandArg = 0;
     216             : 
     217          83 :         argc = osl_getCommandArgCount();
     218         749 :         for ( argi = 0; argi < argc; argi++ )
     219             :         {
     220         666 :             if (osl_Process_E_None == osl_getCommandArg (argi, &ustrCommandArg))
     221             :             {
     222         666 :                 if (0 == rtl_ustr_ascii_compare (rtl_uString_getStr (ustrCommandArg), "-bean"))
     223             :                 {
     224           0 :                     bDoHardKill = sal_True;
     225           0 :                     break;
     226             :                 }
     227             :             }
     228             :         }
     229          83 :         if (ustrCommandArg)
     230             :         {
     231          83 :             rtl_uString_release (ustrCommandArg);
     232          83 :             ustrCommandArg = 0;
     233             :         }
     234             : 
     235             :         // WORKAROUND FOR SEGV HANDLER CONFLICT
     236             :         //
     237             :         // the java jit needs SIGSEGV for proper work
     238             :         // and we need SIGSEGV for the office crashguard
     239             :         //
     240             :         // TEMPORARY SOLUTION:
     241             :         //   the office sets the signal handler during startup
     242             :         //   java can than overwrite it, if needed
     243          83 :         bSetSEGVHandler = sal_True;
     244             : 
     245             :         // WORKAROUND FOR WINCH HANDLER (SEE ABOVE)
     246          83 :         bSetWINCHHandler = sal_True;
     247             : 
     248             :         // WORKAROUND FOR ILLEGAL INSTRUCTION HANDLER (SEE ABOVE)
     249          83 :         bSetILLHandler = sal_True;
     250             :     }
     251             : 
     252             : #ifdef DBG_UTIL
     253             :     bSetSEGVHandler = bSetWINCHHandler = bSetILLHandler = bDoHardKill = sal_False;
     254             : #endif
     255             : 
     256         151 :     SignalListMutex = osl_createMutex();
     257             : 
     258         151 :     act.sa_handler = SignalHandlerFunction;
     259         151 :     act.sa_flags   = SA_RESTART;
     260             : 
     261         151 :     sigfillset(&(act.sa_mask));
     262             : 
     263             :     /* Initialize the rest of the signals */
     264        4681 :     for (i = 0; i < NoSignals; ++i)
     265             :     {
     266             : #if defined HAVE_VALGRIND_HEADERS
     267             :         if (Signals[i].Signal == SIGUSR2 && RUNNING_ON_VALGRIND)
     268             :             Signals[i].Action = ACT_IGNORE;
     269             : #endif
     270             : 
     271             :         /* hack: stomcatd is attaching JavaVM which does not work with an sigaction(SEGV) */
     272        4530 :         if ((bSetSEGVHandler || Signals[i].Signal != SIGSEGV)
     273        4462 :         && (bSetWINCHHandler || Signals[i].Signal != SIGWINCH)
     274        4394 :         && (bSetILLHandler   || Signals[i].Signal != SIGILL))
     275             :         {
     276        4326 :             if (Signals[i].Action != ACT_SYSTEM)
     277             :             {
     278        1593 :                 if (Signals[i].Action == ACT_HIDE)
     279             :                 {
     280             :                     struct sigaction ign;
     281             : 
     282         302 :                     ign.sa_handler = SIG_IGN;
     283         302 :                     ign.sa_flags   = 0;
     284         302 :                     sigemptyset(&ign.sa_mask);
     285             : 
     286         302 :                     if (sigaction(Signals[i].Signal, &ign, &oact) == 0)
     287         302 :                         Signals[i].Handler = oact.sa_handler;
     288             :                     else
     289           0 :                         Signals[i].Handler = SIG_DFL;
     290             :                 }
     291             :                 else
     292             :                 {
     293        1291 :                     if (sigaction(Signals[i].Signal, &act, &oact) == 0)
     294        1291 :                         Signals[i].Handler = oact.sa_handler;
     295             :                     else
     296           0 :                         Signals[i].Handler = SIG_DFL;
     297             :                 }
     298             :             }
     299             :         }
     300             :     }
     301             : 
     302             :     /* Clear signal mask inherited from parent process (on Mac OS X, upon a
     303             :        crash soffice re-execs itself from within the signal handler, so the
     304             :        second soffice would have the guilty signal blocked and would freeze upon
     305             :        encountering a similar crash again): */
     306         151 :     if (sigemptyset(&unset) < 0 ||
     307         151 :         pthread_sigmask(SIG_SETMASK, &unset, NULL) < 0)
     308             :     {
     309             :         OSL_TRACE("sigemptyset or pthread_sigmask failed");
     310             :     }
     311             : 
     312         151 :     return sal_True;
     313             : }
     314             : 
     315          94 : static sal_Bool DeInitSignal()
     316             : {
     317             :     int i;
     318             :     struct sigaction act;
     319             : 
     320          94 :     act.sa_flags   = 0;
     321          94 :     sigemptyset(&(act.sa_mask));
     322             : 
     323             :     /* Initialize the rest of the signals */
     324        2914 :     for (i = NoSignals - 1; i >= 0; i--)
     325        2820 :         if (Signals[i].Action != ACT_SYSTEM)
     326             :         {
     327        1034 :             act.sa_handler = Signals[i].Handler;
     328             : 
     329        1034 :             sigaction(Signals[i].Signal, &act, NULL);
     330             :         }
     331             : 
     332          94 :     osl_destroyMutex(SignalListMutex);
     333             : 
     334          94 :     return sal_False;
     335             : }
     336             : 
     337             : #if defined (SAL_ENABLE_CRASH_REPORT) && defined(INCLUDE_BACKTRACE)
     338             : 
     339             : /*****************************************************************************/
     340             : /* Generate MD5 checksum    */
     341             : /*****************************************************************************/
     342             : 
     343             : static sal_uInt32 calc_md5_checksum( const char *filename, sal_uInt8 *pChecksum, sal_uInt32 nChecksumLen )
     344             : {
     345             :     sal_uInt32  nBytesProcessed = 0;
     346             : 
     347             :     FILE *fp = fopen( filename, "r" );
     348             : 
     349             :     if ( fp )
     350             :     {
     351             :         rtlDigest digest = rtl_digest_createMD5();
     352             : 
     353             :         if ( digest )
     354             :         {
     355             :             size_t          nBytesRead;
     356             :             sal_uInt8       buffer[4096];
     357             :             rtlDigestError  error = rtl_Digest_E_None;
     358             : 
     359             :             while ( rtl_Digest_E_None == error &&
     360             :                 0 != (nBytesRead = fread( buffer, 1, sizeof(buffer), fp )) )
     361             :             {
     362             :                 error = rtl_digest_updateMD5( digest, buffer, nBytesRead );
     363             :                 nBytesProcessed += nBytesRead;
     364             :             }
     365             : 
     366             :             if ( rtl_Digest_E_None == error )
     367             :             {
     368             :                 error = rtl_digest_getMD5( digest, pChecksum, nChecksumLen );
     369             :             }
     370             : 
     371             :             if ( rtl_Digest_E_None != error )
     372             :                 nBytesProcessed = 0;
     373             : 
     374             :             rtl_digest_destroyMD5( digest );
     375             :         }
     376             : 
     377             :         fclose( fp );
     378             :     }
     379             : 
     380             :     return nBytesProcessed;
     381             : }
     382             : 
     383             : /*****************************************************************************/
     384             : /* Call crash reporter  */
     385             : /*****************************************************************************/
     386             : 
     387             : /* Helper function to encode and write a string to a stream */
     388             : 
     389             : static int fputs_xml( const char *string, FILE *stream )
     390             : {
     391             :     int result = 0;
     392             : 
     393             :     while ( result >= 0 && *string )
     394             :     {
     395             :         switch( *string )
     396             :         {
     397             :         case '&':
     398             :             result = fputs( "&amp;", stream );
     399             :             break;
     400             :         case '<':
     401             :             result = fputs( "&lt;", stream );
     402             :             break;
     403             :         case '>':
     404             :             result = fputs( "&gt;", stream );
     405             :             break;
     406             :         default:
     407             :             result = fputc( *string, stream );
     408             :             break;
     409             :         }
     410             : 
     411             :         string++;
     412             :     }
     413             : 
     414             :     return result;
     415             : }
     416             : #endif
     417             : 
     418             : /* Create intermediate files and run crash reporter */
     419             : 
     420             : #if defined SAL_ENABLE_CRASH_REPORT && defined INCLUDE_BACKTRACE && \
     421             :     defined LINUX
     422             : 
     423             : typedef struct
     424             : {
     425             :     const char *name;
     426             :     ElfW(Off) offset;
     427             : } dynamic_entry;
     428             : 
     429             : static int
     430             : callback(struct dl_phdr_info *info, size_t size, void *data)
     431             : {
     432             :     const ElfW(Phdr) *pDynamic = NULL;
     433             : 
     434             :     if (size == sizeof(struct dl_phdr_info))
     435             :     {
     436             :         int i;
     437             :         for (i = 0; i < info->dlpi_phnum; ++i)
     438             :         {
     439             :             if (info->dlpi_phdr[i].p_type == PT_DYNAMIC)
     440             :             {
     441             :                 pDynamic = &(info->dlpi_phdr[i]);
     442             :                 break;
     443             :             }
     444             :         }
     445             :     }
     446             : 
     447             :     if (pDynamic)
     448             :     {
     449             :         char buffer[100];
     450             :         int len;
     451             :         char exe[PATH_MAX];
     452             :         const char *dsoname = info->dlpi_name;
     453             : 
     454             :         dynamic_entry* entry = (dynamic_entry*)data;
     455             : 
     456             :         if (strcmp(dsoname, "") == 0)
     457             :         {
     458             :             snprintf(buffer, sizeof(buffer), "/proc/%d/exe", getpid());
     459             :             if ((len = readlink(buffer, exe, PATH_MAX)) != -1)
     460             :             {
     461             :                 exe[len] = '\0';
     462             :                 dsoname = exe;
     463             :             }
     464             :         }
     465             : 
     466             :         if (strcmp(dsoname, entry->name) == 0)
     467             :         {
     468             :             entry->offset = pDynamic->p_offset;
     469             :             return 1;
     470             :         }
     471             :     }
     472             :     return 0;
     473             : }
     474             : 
     475             : /* Get the location of the .dynamic section offset for the given elf file.
     476             :  * i.e. same as the "Offset" value shown for DYNAMIC from readelf -l foo
     477             :  *
     478             :  * We want to know this value so that if the binaries have been modifed
     479             :  * by prelink then we can still process the call stack on server side
     480             :  * by comparing this value to that of an "un-prelinked but known to be
     481             :  * otherwise equivalent" version of those binaries and adjust the call
     482             :  * stack addresses by the differences between .dynamic addresses so as
     483             :  * to be able to map the prelinked addresses back to the unprelinked
     484             :  * addresses
     485             :  *
     486             :  * cmc@openoffice.org
     487             :  */
     488             : static ElfW(Off)
     489             : dynamic_section_offset(const char *name)
     490             : {
     491             :     dynamic_entry entry;
     492             : 
     493             :     entry.name = name;
     494             :     entry.offset = 0;
     495             : 
     496             :     dl_iterate_phdr(callback, &entry);
     497             : 
     498             :     return entry.offset;
     499             : }
     500             : #endif
     501             : 
     502           0 : static int ReportCrash( int Signal )
     503             : {
     504             : #ifdef SAL_ENABLE_CRASH_REPORT
     505             : 
     506             : #define REPORTENV_PARAM     "-crashreportenv:"
     507             : 
     508             :     static sal_Bool bCrashReporterExecuted = sal_False;
     509             :     sal_Bool        bAutoCrashReport = sal_False;
     510             : 
     511             :     sal_uInt32  argi;
     512             :     sal_uInt32  argc;
     513             :     rtl_uString *ustrCommandArg = NULL;
     514             : 
     515             :     if ( !bErrorReportingEnabled )
     516             :         return -1;
     517             : 
     518             :     argc = osl_getCommandArgCount();
     519             : 
     520             :     for ( argi = 0; argi < argc; argi++ )
     521             :     {
     522             :         if ( osl_Process_E_None == osl_getCommandArg( argi, &ustrCommandArg ) )
     523             :         {
     524             :             if ( 0 == rtl_ustr_ascii_compare( rtl_uString_getStr( ustrCommandArg ), "--nocrashreport" ) )
     525             :             {
     526             :                 rtl_uString_release( ustrCommandArg );
     527             :                 return -1;
     528             :             }
     529             :             else if ( 0 == rtl_ustr_ascii_compare( rtl_uString_getStr( ustrCommandArg ), "--autocrashreport" ) )
     530             :             {
     531             :                 bAutoCrashReport = sal_True;
     532             :             }
     533             :             else if ( 0 == rtl_ustr_ascii_shortenedCompare_WithLength(
     534             :                 rtl_uString_getStr( ustrCommandArg ), rtl_uString_getLength( ustrCommandArg ),
     535             :                 REPORTENV_PARAM, strlen(REPORTENV_PARAM) )
     536             :                 )
     537             :             {
     538             :                 rtl_uString *ustrEnvironment = NULL;
     539             :                 rtl_String *strEnv = NULL;
     540             : 
     541             :                 rtl_uString_newFromStr( &ustrEnvironment, rtl_uString_getStr( ustrCommandArg ) + strlen(REPORTENV_PARAM) );
     542             : 
     543             :                 if ( ustrEnvironment )
     544             :                 {
     545             :                     rtl_uString2String(
     546             :                         &strEnv,
     547             :                         rtl_uString_getStr( ustrEnvironment ), rtl_uString_getLength( ustrEnvironment ),
     548             :                         osl_getThreadTextEncoding(), OUSTRING_TO_OSTRING_CVTFLAGS
     549             :                         );
     550             : 
     551             :                     if ( strEnv )
     552             :                     {
     553             :                         putenv( rtl_string_getStr( strEnv ) );
     554             :                         rtl_string_release( strEnv );
     555             :                     }
     556             : 
     557             :                     rtl_uString_release( ustrEnvironment );
     558             :                 }
     559             : 
     560             :             }
     561             : 
     562             :         }
     563             :     }
     564             : 
     565             :     if ( ustrCommandArg )
     566             :         rtl_uString_release( ustrCommandArg );
     567             : 
     568             :     if ( !bCrashReporterExecuted )
     569             :     {
     570             :         int i;
     571             :         /* struct sigaction act; */
     572             : 
     573             :         for (i = 0; i < NoSignals; i++)
     574             :         {
     575             :             if (Signals[i].Signal == Signal && Signals[i].Action == ACT_ABORT )
     576             :             {
     577             :                 int  ret;
     578             :                 char szShellCmd[512] = { '\0' };
     579             :                 char *pXMLTempName = NULL;
     580             :                 char *pStackTempName = NULL;
     581             :                 char *pChecksumTempName = NULL;
     582             : 
     583             : #ifdef INCLUDE_BACKTRACE
     584             :                 char szXMLTempNameBuffer[L_tmpnam];
     585             :                 char szChecksumTempNameBuffer[L_tmpnam];
     586             :                 char szStackTempNameBuffer[L_tmpnam];
     587             : 
     588             :                 void *stackframes[MAX_STACK_FRAMES];
     589             :                 int  iFrame;
     590             :                 int  nFrames = backtrace( stackframes, SAL_N_ELEMENTS(stackframes) );
     591             : 
     592             :                 FILE *xmlout = NULL, *stackout = NULL, *checksumout = NULL;
     593             :                 int fdxml, fdstk, fdchksum;
     594             : 
     595             :                 strncpy( szXMLTempNameBuffer, P_tmpdir, sizeof(szXMLTempNameBuffer) );
     596             :                 strncat( szXMLTempNameBuffer, "/crxmlXXXXXX", sizeof(szXMLTempNameBuffer) - strlen(szXMLTempNameBuffer) - 1 );
     597             : 
     598             :                 strncpy( szStackTempNameBuffer, P_tmpdir, sizeof(szStackTempNameBuffer) );
     599             :                 strncat( szStackTempNameBuffer, "/crstkXXXXXX", sizeof(szStackTempNameBuffer) - strlen(szStackTempNameBuffer) - 1 );
     600             : 
     601             :                 strncpy( szChecksumTempNameBuffer, P_tmpdir, sizeof(szChecksumTempNameBuffer) );
     602             :                 strncat( szChecksumTempNameBuffer, "/crchkXXXXXX", sizeof(szChecksumTempNameBuffer) - strlen(szChecksumTempNameBuffer) - 1 );
     603             : 
     604             :                 fdxml = mkstemp(szXMLTempNameBuffer);
     605             :                 fdstk = mkstemp(szStackTempNameBuffer);
     606             :                 fdchksum = mkstemp(szChecksumTempNameBuffer);
     607             : 
     608             :                 xmlout = fdopen( fdxml , "w" );
     609             :                 stackout = fdopen( fdstk , "w" );
     610             :                 checksumout = fdopen( fdchksum, "w" );
     611             : 
     612             :                 pXMLTempName = szXMLTempNameBuffer;
     613             :                 pStackTempName = szStackTempNameBuffer;
     614             :                 pChecksumTempName = szChecksumTempNameBuffer;
     615             : 
     616             : 
     617             :                 if ( xmlout && stackout && checksumout )
     618             :                 {
     619             :                     fprintf( xmlout, "<errormail:Stack type=\"%s\">\n", STACKTYPE );
     620             : 
     621             :                     fprintf( checksumout, "<errormail:Checksums type=\"MD5\">\n" );
     622             : 
     623             :                     for ( iFrame = 0; iFrame < nFrames; iFrame++ )
     624             :                     {
     625             :                         Dl_info dl_info;
     626             : 
     627             :                         fprintf( stackout, "0x%" SAL_PRIxUINTPTR ":",
     628             :                             SAL_INT_CAST(sal_uIntPtr, stackframes[iFrame]) );
     629             : 
     630             :                         fprintf( xmlout, "<errormail:StackInfo pos=\"%d\" ip=\"0x%" SAL_PRIxUINTPTR "\"",
     631             :                             iFrame,
     632             :                             SAL_INT_CAST(sal_uIntPtr, stackframes[iFrame])
     633             :                             );
     634             : 
     635             :                         memset( &dl_info, 0, sizeof(dl_info) );
     636             : 
     637             :                         /* dladdr may fail */
     638             :                         if ( dladdr( stackframes[iFrame], &dl_info) )
     639             :                         {
     640             :                             const char *dli_fname = NULL;
     641             :                             char *dli_fdir = NULL;
     642             :                             char szDirectory[PATH_MAX];
     643             :                             char szCanonicDirectory[PATH_MAX];
     644             : 
     645             :                             /* Don't expect that dladdr filled all members of dl_info */
     646             : 
     647             :                             dli_fname = dl_info.dli_fname ? strrchr(  dl_info.dli_fname, '/' ) : NULL;
     648             :                             if ( dli_fname )
     649             :                             {
     650             :                                 ++dli_fname;
     651             :                                 memcpy( szDirectory, dl_info.dli_fname, dli_fname - dl_info.dli_fname );
     652             :                                 szDirectory[dli_fname - dl_info.dli_fname] = 0;
     653             : 
     654             :                                 dli_fdir = realpath( szDirectory, szCanonicDirectory ) ? szCanonicDirectory : szDirectory;
     655             : 
     656             :                                 if ( *dli_fdir && dli_fdir[ strlen(dli_fdir) - 1 ] != '/' )
     657             :                                     strcat( dli_fdir, "/" );
     658             :                             }
     659             :                             else
     660             :                                 dli_fname = dl_info.dli_fname;
     661             : 
     662             :                             /* create checksum of library on stack */
     663             :                             if ( dli_fname )
     664             :                             {
     665             :                                 sal_uInt8   checksum[RTL_DIGEST_LENGTH_MD5];
     666             : 
     667             :                                 sal_uInt32 nBytesProcessed = calc_md5_checksum(
     668             :                                     dl_info.dli_fname, checksum, sizeof(checksum) );
     669             :                                 if ( nBytesProcessed )
     670             :                                 {
     671             :                                     int j;
     672             : 
     673             :                                     fprintf( checksumout, "<errormail:Checksum sum=\"0x" );
     674             :                                     for ( j = 0; j < 16; fprintf( checksumout, "%02X", checksum[j++] ) );
     675             :                                     fprintf( checksumout,
     676             :                                         "\" bytes=\"%lu\" file=\"%s\"/>\n",
     677             :                                         SAL_INT_CAST(
     678             :                                             unsigned long, nBytesProcessed),
     679             :                                         dli_fname );
     680             :                                 }
     681             :                             }
     682             : 
     683             :                             if ( dl_info.dli_fbase && dl_info.dli_fname )
     684             :                             {
     685             : #ifdef LINUX
     686             :                                 ElfW(Off) dynamic_offset = dynamic_section_offset(dl_info.dli_fname);
     687             :                                 fprintf( stackout, " 0x%" SAL_PRI_SIZET "x:", dynamic_offset);
     688             : #endif
     689             : 
     690             :                                 fprintf( stackout, " %s + 0x%" SAL_PRI_PTRDIFFT "x",
     691             :                                     dl_info.dli_fname,
     692             :                                     (char*)stackframes[iFrame] - (char*)dl_info.dli_fbase
     693             :                                     );
     694             : 
     695             :                                 fprintf( xmlout, " rel=\"0x%" SAL_PRI_PTRDIFFT "x\"", (char *)stackframes[iFrame] - (char *)dl_info.dli_fbase );
     696             :                                 if ( dli_fname )
     697             :                                     fprintf( xmlout, " name=\"%s\"", dli_fname );
     698             : 
     699             :                                 if ( dli_fdir )
     700             :                                     fprintf( xmlout, " path=\"%s\"", dli_fdir );
     701             : 
     702             : #ifdef LINUX
     703             :                                 fprintf( xmlout, " dynamicoffset=\"0x%" SAL_PRI_SIZET "x\"", dynamic_offset );
     704             : #endif
     705             :                             }
     706             :                             else
     707             :                                 fprintf( stackout, " ????????" );
     708             : 
     709             :                             if ( dl_info.dli_sname && dl_info.dli_saddr )
     710             :                             {
     711             :                                 fputs( " (", stackout );
     712             :                                 fputs_xml( dl_info.dli_sname, stackout );
     713             :                                 fprintf( stackout, " + 0x%" SAL_PRI_PTRDIFFT "x)",
     714             :                                     (char*)stackframes[iFrame] - (char*)dl_info.dli_saddr );
     715             : 
     716             :                                 fputs( " ordinal=\"", xmlout );
     717             :                                 fputs_xml( dl_info.dli_sname, xmlout );
     718             :                                 fprintf( xmlout, "+0x%" SAL_PRI_PTRDIFFT "x\"",
     719             :                                     (char *)stackframes[iFrame] - (char *)dl_info.dli_saddr );
     720             :                             }
     721             : 
     722             :                         }
     723             :                         else /* dladdr failed */
     724             :                         {
     725             :                             fprintf( stackout, " ????????" );
     726             :                         }
     727             : 
     728             :                         fprintf( stackout, "\n" );
     729             :                         fprintf( xmlout, "/>\n" );
     730             : 
     731             :                     }
     732             : 
     733             :                     fprintf( xmlout, "</errormail:Stack>\n" );
     734             :                     fprintf( checksumout, "</errormail:Checksums>\n" );
     735             :                 }
     736             :                 else
     737             :                 {
     738             :                     pXMLTempName = NULL;
     739             :                     pStackTempName = NULL;
     740             :                     pChecksumTempName = NULL;
     741             :                 }
     742             : 
     743             :                 if ( stackout )
     744             :                     fclose( stackout );
     745             :                 if ( xmlout )
     746             :                     fclose( xmlout );
     747             :                 if ( checksumout )
     748             :                     fclose( checksumout );
     749             : 
     750             :                 if ( pXMLTempName && pChecksumTempName && pStackTempName )
     751             : #endif /* INCLUDE_BACKTRACE */
     752             :                 {
     753             :                     rtl_uString * crashrep_url = NULL;
     754             :                     rtl_uString * crashrep_path = NULL;
     755             :                     rtl_String  * crashrep_path_system = NULL;
     756             :                     rtl_string2UString(
     757             :                         &crashrep_url,
     758             :                         RTL_CONSTASCII_USTRINGPARAM(
     759             :                             "$BRAND_BASE_DIR/program/crashrep"),
     760             :                         OSTRING_TO_OUSTRING_CVTFLAGS);
     761             :                     rtl_bootstrap_expandMacros(&crashrep_url);
     762             :                     osl_getSystemPathFromFileURL(crashrep_url, &crashrep_path);
     763             :                     rtl_uString2String(
     764             :                         &crashrep_path_system,
     765             :                         rtl_uString_getStr(crashrep_path),
     766             :                         rtl_uString_getLength(crashrep_path),
     767             :                         osl_getThreadTextEncoding(),
     768             :                         (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
     769             :                          | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR));
     770             :                     rtl_uString_release(crashrep_url);
     771             :                     rtl_uString_release(crashrep_path);
     772             : #if defined INCLUDE_BACKTRACE && (defined LINUX || defined MACOSX)
     773             :                     snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
     774             :                         "%s -p %d -s %d -xml %s -chksum %s -stack %s -noui%s",
     775             :                         rtl_string_getStr(crashrep_path_system),
     776             :                         getpid(),
     777             :                         Signal,
     778             :                         pXMLTempName,
     779             :                         pChecksumTempName,
     780             :                         pStackTempName,
     781             :                         bAutoCrashReport ? " -send" : "" );
     782             : #elif defined INCLUDE_BACKTRACE && defined SOLARIS
     783             :                     snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
     784             :                         "%s -p %d -s %d -xml %s -chksum %s -noui%s",
     785             :                         rtl_string_getStr(crashrep_path_system),
     786             :                         getpid(),
     787             :                         Signal,
     788             :                         pXMLTempName,
     789             :                         pChecksumTempName,
     790             :                         bAutoCrashReport ? " -send" : "" );
     791             : #else
     792             :                     snprintf( szShellCmd, SAL_N_ELEMENTS(szShellCmd),
     793             :                         "%s -p %d -s %d -noui%s",
     794             :                         rtl_string_getStr(crashrep_path_system),
     795             :                         getpid(), Signal, bAutoCrashReport ? " -send" : "" );
     796             : #endif
     797             :                     rtl_string_release(crashrep_path_system);
     798             :                 }
     799             : 
     800             :                 ret = szShellCmd[0] == '\0' ? -1 : system( szShellCmd );
     801             : 
     802             :                 if ( pXMLTempName )
     803             :                     unlink( pXMLTempName );
     804             : 
     805             :                 if ( pStackTempName )
     806             :                     unlink( pStackTempName );
     807             : 
     808             :                 if ( pChecksumTempName )
     809             :                     unlink( pChecksumTempName );
     810             : 
     811             :                 if ( -1 != ret )
     812             :                 {
     813             :                     bCrashReporterExecuted = sal_True;
     814             :                     return 1;
     815             :                 }
     816             :                 else
     817             :                     return -1;
     818             : 
     819             :             }
     820             :         }
     821             : 
     822             :         return 0;
     823             :     }
     824             : 
     825             :     return 1;
     826             : #else /* defined SAL_ENABLE_CRASH_REPORT */
     827             :     /* the utility crash_report is not build, so do the same as when
     828             :        the option -nocrashreport is used */
     829             :     (void) Signal; // avoid warnings
     830           0 :     return -1;
     831             : #endif /* defined SAL_ENABLE_CRASH_REPORT */
     832             : }
     833             : 
     834           0 : static void PrintStack( int sig )
     835             : {
     836             : #ifdef INCLUDE_BACKTRACE
     837             :     void *buffer[MAX_STACK_FRAMES];
     838           0 :     int size = backtrace( buffer, SAL_N_ELEMENTS(buffer) );
     839             : #endif
     840             : 
     841           0 :     fprintf( stderr, "\n\nFatal exception: Signal %d\n", sig );
     842             : 
     843             : #if defined( MACOSX ) && !defined( INCLUDE_BACKTRACE )
     844             :     fprintf( stderr, "Please turn on Enable Crash Reporting and\nAutomatic Display of Crashlogs in the Console application\n" );
     845             : #else
     846             : #ifdef INCLUDE_BACKTRACE
     847           0 :     if ( size > 0 )
     848             :     {
     849           0 :         fputs( "Stack:\n", stderr );
     850           0 :         backtrace_symbols_fd( buffer, size, fileno(stderr) );
     851             :     }
     852             : #endif
     853             : #endif
     854           0 : }
     855             : 
     856           0 : static oslSignalAction CallSignalHandler(oslSignalInfo *pInfo)
     857             : {
     858           0 :     oslSignalHandlerImpl* pHandler = SignalList;
     859           0 :     oslSignalAction Action = osl_Signal_ActCallNextHdl;
     860             : 
     861           0 :     while (pHandler != NULL)
     862             :     {
     863           0 :         if ((Action = pHandler->Handler(pHandler->pData, pInfo))
     864             :             != osl_Signal_ActCallNextHdl)
     865           0 :             break;
     866             : 
     867           0 :         pHandler = pHandler->pNext;
     868             :     }
     869             : 
     870           0 :     return Action;
     871             : }
     872             : 
     873           0 : void CallSystemHandler(int Signal)
     874             : {
     875             :     int i;
     876             :     struct sigaction act;
     877             : 
     878           0 :     for (i = 0; i < NoSignals; i++)
     879             :     {
     880           0 :         if (Signals[i].Signal == Signal)
     881           0 :             break;
     882             :     }
     883             : 
     884           0 :     if (i < NoSignals)
     885             :     {
     886           0 :         if ((Signals[i].Handler == NULL)    ||
     887           0 :             (Signals[i].Handler == SIG_DFL) ||
     888           0 :             (Signals[i].Handler == SIG_IGN) ||
     889           0 :              (Signals[i].Handler == SIG_ERR))
     890             :         {
     891           0 :             switch (Signals[i].Action)
     892             :             {
     893             :                 case ACT_EXIT:      /* terminate */
     894             :                     /* prevent dumping core on exit() */
     895           0 :                     _exit(255);
     896             :                     break;
     897             : 
     898             :                 case ACT_ABORT:     /* terminate witch core dump */
     899           0 :                     ReportCrash( Signal );
     900           0 :                     act.sa_handler = SIG_DFL;
     901           0 :                     act.sa_flags   = 0;
     902           0 :                     sigemptyset(&(act.sa_mask));
     903           0 :                     sigaction(SIGABRT, &act, NULL);
     904           0 :                     PrintStack( Signal );
     905           0 :                     abort();
     906             :                     break;
     907             : 
     908             :                 case ACT_IGNORE:    /* ignore */
     909           0 :                     break;
     910             : 
     911             :                 default:            /* should never happen */
     912             :                     OSL_ASSERT(0);
     913             :             }
     914           0 :         }
     915             :         else
     916           0 :             (*Signals[i].Handler)(Signal);
     917             :     }
     918           0 : }
     919             : 
     920             : #if defined HAVE_VALGRIND_HEADERS
     921             : static void DUMPCURRENTALLOCS()
     922             : {
     923             :     VALGRIND_PRINTF( "=== start memcheck dump of active allocations ===\n" );
     924             : 
     925             : #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
     926             : #   pragma GCC diagnostic push
     927             : #   pragma GCC diagnostic ignored "-Wunused-but-set-variable"
     928             : #endif
     929             : 
     930             :     VALGRIND_DO_LEAK_CHECK;
     931             : 
     932             : #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
     933             : #   pragma GCC diagnostic pop
     934             : #endif
     935             : 
     936             :     VALGRIND_PRINTF( "=== end memcheck dump of active allocations ===\n" );
     937             : }
     938             : #endif
     939             : 
     940             : /*****************************************************************************/
     941             : /* SignalHandlerFunction    */
     942             : /*****************************************************************************/
     943           0 : void SignalHandlerFunction(int Signal)
     944             : {
     945             :     oslSignalInfo    Info;
     946             :     struct sigaction act;
     947             : 
     948           0 :     Info.UserSignal = Signal;
     949           0 :     Info.UserData   = NULL;
     950             : 
     951           0 :     switch (Signal)
     952             :     {
     953             :         case SIGBUS:
     954             :         case SIGILL:
     955             :         case SIGSEGV:
     956             :         case SIGIOT:
     957             : #if ( SIGIOT != SIGABRT )
     958             :         case SIGABRT:
     959             : #endif
     960           0 :             Info.Signal = osl_Signal_AccessViolation;
     961           0 :             break;
     962             : 
     963             :         case -1:
     964           0 :             Info.Signal = osl_Signal_IntegerDivideByZero;
     965           0 :             break;
     966             : 
     967             :         case SIGFPE:
     968           0 :             Info.Signal = osl_Signal_FloatDivideByZero;
     969           0 :             break;
     970             : 
     971             :         case SIGINT:
     972             :         case SIGTERM:
     973             :         case SIGQUIT:
     974           0 :             Info.Signal = osl_Signal_Terminate;
     975           0 :             break;
     976             : 
     977             : #if defined HAVE_VALGRIND_HEADERS
     978             :         case SIGUSR2:
     979             :             if (RUNNING_ON_VALGRIND)
     980             :                 DUMPCURRENTALLOCS();
     981             :             Info.Signal = osl_Signal_System;
     982             :             break;
     983             : #endif
     984             : 
     985             :         default:
     986           0 :             Info.Signal = osl_Signal_System;
     987           0 :             break;
     988             :     }
     989             : 
     990           0 :     ReportCrash( Signal );
     991             : 
     992             :     /* Portal Demo HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
     993           0 :     if (bDoHardKill && (Info.Signal == osl_Signal_AccessViolation))
     994           0 :         _exit(255);
     995             :     /* Portal Demo HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
     996             : 
     997             : 
     998           0 :     switch (CallSignalHandler(&Info))
     999             :     {
    1000             :     case osl_Signal_ActCallNextHdl:
    1001           0 :         CallSystemHandler(Signal);
    1002           0 :         break;
    1003             : 
    1004             :     case osl_Signal_ActAbortApp:
    1005           0 :         ReportCrash( Signal );
    1006           0 :         act.sa_handler = SIG_DFL;
    1007           0 :         act.sa_flags   = 0;
    1008           0 :         sigemptyset(&(act.sa_mask));
    1009           0 :         sigaction(SIGABRT, &act, NULL);
    1010           0 :         PrintStack( Signal );
    1011           0 :         abort();
    1012             :         break;
    1013             : 
    1014             :     case osl_Signal_ActKillApp:
    1015             :         /* prevent dumping core on exit() */
    1016           0 :         _exit(255);
    1017             :         break;
    1018             :     default:
    1019           0 :         break;
    1020             :     }
    1021           0 : }
    1022             : 
    1023             : /*****************************************************************************/
    1024             : /* osl_addSignalHandler */
    1025             : /*****************************************************************************/
    1026         234 : oslSignalHandler SAL_CALL osl_addSignalHandler(oslSignalHandlerFunction Handler, void* pData)
    1027             : {
    1028             :     oslSignalHandlerImpl* pHandler;
    1029             : 
    1030             :     OSL_ASSERT(Handler != NULL);
    1031         234 :     if ( Handler == 0 )
    1032             :     {
    1033           0 :         return 0;
    1034             :     }
    1035             : 
    1036         234 :     if (! bInitSignal)
    1037         151 :         bInitSignal = InitSignal();
    1038             : 
    1039         234 :     pHandler = (oslSignalHandlerImpl*) calloc(1, sizeof(oslSignalHandlerImpl));
    1040             : 
    1041         234 :     if (pHandler != NULL)
    1042             :     {
    1043         234 :         pHandler->Handler = Handler;
    1044         234 :         pHandler->pData   = pData;
    1045             : 
    1046         234 :         osl_acquireMutex(SignalListMutex);
    1047             : 
    1048         234 :         pHandler->pNext = SignalList;
    1049         234 :         SignalList      = pHandler;
    1050             : 
    1051         234 :         osl_releaseMutex(SignalListMutex);
    1052             : 
    1053         234 :         return (pHandler);
    1054             :     }
    1055             : 
    1056           0 :     return (NULL);
    1057             : }
    1058             : 
    1059             : /*****************************************************************************/
    1060             : /* osl_removeSignalHandler */
    1061             : /*****************************************************************************/
    1062         177 : sal_Bool SAL_CALL osl_removeSignalHandler(oslSignalHandler Handler)
    1063             : {
    1064         177 :     oslSignalHandlerImpl *pHandler, *pPrevious = NULL;
    1065             : 
    1066             :     OSL_ASSERT(Handler != NULL);
    1067             : 
    1068         177 :     if (! bInitSignal)
    1069           0 :         bInitSignal = InitSignal();
    1070             : 
    1071         177 :     osl_acquireMutex(SignalListMutex);
    1072             : 
    1073         177 :     pHandler = SignalList;
    1074             : 
    1075         354 :     while (pHandler != NULL)
    1076             :     {
    1077         177 :         if (pHandler == Handler)
    1078             :         {
    1079         177 :             if (pPrevious)
    1080           0 :                 pPrevious->pNext = pHandler->pNext;
    1081             :             else
    1082         177 :                 SignalList = pHandler->pNext;
    1083             : 
    1084         177 :             osl_releaseMutex(SignalListMutex);
    1085             : 
    1086         177 :             if (SignalList == NULL)
    1087          94 :                 bInitSignal = DeInitSignal();
    1088             : 
    1089         177 :             free(pHandler);
    1090             : 
    1091         177 :             return (sal_True);
    1092             :         }
    1093             : 
    1094           0 :         pPrevious = pHandler;
    1095           0 :         pHandler  = pHandler->pNext;
    1096             :     }
    1097             : 
    1098           0 :     osl_releaseMutex(SignalListMutex);
    1099             : 
    1100           0 :     return (sal_False);
    1101             : }
    1102             : 
    1103             : /*****************************************************************************/
    1104             : /* osl_raiseSignal */
    1105             : /*****************************************************************************/
    1106           0 : oslSignalAction SAL_CALL osl_raiseSignal(sal_Int32 UserSignal, void* UserData)
    1107             : {
    1108             :     oslSignalInfo   Info;
    1109             :     oslSignalAction Action;
    1110             : 
    1111           0 :     if (! bInitSignal)
    1112           0 :         bInitSignal = InitSignal();
    1113             : 
    1114           0 :     osl_acquireMutex(SignalListMutex);
    1115             : 
    1116           0 :     Info.Signal     = osl_Signal_User;
    1117           0 :     Info.UserSignal = UserSignal;
    1118           0 :     Info.UserData   = UserData;
    1119             : 
    1120           0 :     Action = CallSignalHandler(&Info);
    1121             : 
    1122           0 :     osl_releaseMutex(SignalListMutex);
    1123             : 
    1124           0 :     return (Action);
    1125             : }
    1126             : 
    1127             : /*****************************************************************************/
    1128             : /* osl_setErrorReporting */
    1129             : /*****************************************************************************/
    1130          83 : sal_Bool SAL_CALL osl_setErrorReporting( sal_Bool bEnable )
    1131             : {
    1132          83 :     sal_Bool bOld = bErrorReportingEnabled;
    1133          83 :     bErrorReportingEnabled = bEnable;
    1134             : 
    1135          83 :     return bOld;
    1136             : }
    1137             : 
    1138             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10