示例#1
0
void
os_processModuleExit(void)
{
#if !defined INTEGRITY && !defined VXWORKS_RTP
    int sig = -1;
    void *thread_result;

    /* deinstall signal handlers */
    _SIGACTION_(SIGINT);
    _SIGACTION_(SIGQUIT);
    _SIGACTION_(SIGHUP);
    _SIGACTION_(SIGTERM);


    if(isSignallingSafe(0)){
        _SIGACTION_(SIGILL);
        _SIGACTION_(SIGABRT);
        _SIGACTION_(SIGFPE);
        _SIGACTION_(SIGSEGV);
        _SIGACTION_(SIGPIPE);
        _SIGACTION_(SIGALRM);
        _SIGACTION_(SIGUSR1);
        _SIGACTION_(SIGUSR2);
        _SIGACTION_(SIGTTIN);
    }
    _ospl_signalHandlerThreadTerminate = OSPL_SIGNALHANDLERTHREAD_TERMINATE;
    if (pthread_self() != _ospl_signalHandlerThreadId) {
        write(_ospl_signalpipe[1], &sig, sizeof(sig));
        pthread_join(_ospl_signalHandlerThreadId, &thread_result);
    }
#endif
}
示例#2
0
os_result
os_signalHandlerEnableExceptionSignals (
    void)
{
    os_signalHandler _this = signalHandlerObj;
    unsigned i, iException;
    int r;

    if (isSignallingSafe(0) && _this) {

        for (i = 0; i < lengthof(exceptions); i++) {
            const int sig = exceptions[i];
            r = os_sigsetDel(&_this->action.sa_mask, sig);
            if (r < 0) {
                OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0,
                        "os_sigsetDel(0x%"PA_PRIxADDR", %d) failed, result = %d",
                        (os_address)&_this->action, sig, r);
                goto err_exceptionSigSetDel;
            }
        }

        for (iException = 0; iException < lengthof(exceptions); iException++) {
            const int sig = exceptions[iException];
            /* For exceptions we always set our own signal handler, since
             * applications that cause an exception are not in a position
             * to ignore it. However, we will chain the old handler to our
             * own. */
            r = os_sigactionSet(sig, &_this->action, &old_signalHandler[sig]);
            if (r < 0) {
                OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0,
                        "os_sigactionSet(%d, 0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR") failed, result = %d",
                        sig, (os_address)&_this->action, (os_address)&old_signalHandler[sig], r);
                goto err_exceptionSigSet;
            }
        }

        _this->handleExceptions = OS_TRUE;
    }

    return os_resultSuccess;

err_exceptionSigSet:
    while(iException) {
        const int sig = exceptions[--iException];
        r = os_sigactionSet(sig, &old_signalHandler[sig], NULL);
        if (r < 0) {
            OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0,
                      "Failed to restore original handler: os_sigactionSet(%d, 0x%"PA_PRIxADDR", NULL) failed, result = %d",
                       sig, (os_address)&old_signalHandler[sig], r);
        }
    }
err_exceptionSigSetDel:
    /* No undo needed for os_sigsetDel(...) */
    return os_resultFail;
}
示例#3
0
void
os_signalHandlerFree(
    void)
{
#if !defined INTEGRITY && !defined VXWORKS_RTP
    int i;
    os_ssize_t r;
    os_signalHandler _this = signalHandlerObj;

    if (isSignallingSafe(0) && _this) {
        if (_this->handleExceptions) {
            for (i=0; i<lengthof(exceptions); i++) {
                const int sig = exceptions[i];
                r = os_sigactionSet(sig, &old_signalHandler[sig], NULL);
                if (r<0) {
                    OS_REPORT(OS_ERROR,
                            "os_signalHandlerFree", 0,
                            "os_sigactionSet(%d, 0x%"PA_PRIxADDR", NULL) failed, result = %"PA_PRIdSIZE,
                            sig, (os_address)&old_signalHandler[sig], r);
                    assert(OS_FALSE);
                }
            }
        }
        for (i=0; i<lengthof(quits); i++) {
            const int sig = quits[i];
            r = os_sigactionSet(sig, &old_signalHandler[sig], NULL);
            if (r<0) {
                OS_REPORT(OS_ERROR,
                        "os_signalHandlerFree", 0,
                        "os_sigactionSet(%d, 0x%"PA_PRIxADDR", NULL) failed, result = %"PA_PRIdSIZE,
                        sig, (os_address)&old_signalHandler[sig], r);
                assert(OS_FALSE);
            }
        }
        os__signalHandlerThreadStop(_this);
        close(_this->pipeIn[0]);
        close(_this->pipeIn[1]);
        close(_this->pipeOut[0]);
        close(_this->pipeOut[1]);

        os__signalHandlerCallbackDeinit(&_this->callbackInfo);

        os_free(_this);
        signalHandlerObj = NULL;
    }
#endif
}
示例#4
0
void
os_signalHandlerFree(
    void)
{
#if !defined INTEGRITY && !defined VXWORKS_RTP
    void *thread_result;
    int i, r;
    os_signalHandler _this = signalHandlerObj;
    struct sig_context info;

    if (isSignallingSafe(0) && _this) {
        for (i=0; i<lengthof(exceptions); i++) {
            const int sig = exceptions[i];
            r = os_sigactionSet(sig, &old_signalHandler[sig], NULL);
            if (r<0) {
                OS_REPORT_3(OS_ERROR,
                            "os_signalHandlerFree", 0,
                            "os_sigactionSet(%d, 0x%x, NULL) failed, result = %d",
                            sig, &old_signalHandler[sig], r);
                assert(OS_FALSE);
            }
        }
        memset (&info, 0, sizeof(info));
        info.info.si_signo = SIGNAL_THREAD_STOP;
        r = write(_this->pipeIn[1], &info, sizeof(info));
        /* when signalhandler is the exiting thread itself, this can happen when an exit call is done in the signalhandler of the customer
         * do not call os_threadWaitExit but just let this thread run out of its main function */
        if (os_threadIdSelf() != _this->threadId ) {
            os_threadWaitExit(_this->threadId, &thread_result);
        }
        close(_this->pipeIn[0]);
        close(_this->pipeIn[1]);
        close(_this->pipeOut[0]);
        close(_this->pipeOut[1]);
        os_free(_this);
        signalHandlerObj = NULL;
    }
#endif
}
示例#5
0
static os_result
os_signalHandlerEnableExitSignals (
    void)
{
    os_signalHandler _this = signalHandlerObj;
    unsigned iExit;
    int r;

    if (isSignallingSafe(0) && _this) {

        for (iExit = 0; iExit < quits_len; iExit++) {
            const int sig = quits[iExit];
            /* By passing NULL we only retrieve the currently set handler. If
             * the signal should be ignored, we don't do anything. Otherwise we
             * chain the old handler to our own.
             * man-page of sigaction only states behaviour when new
             * action is non-NULL, but all known implementations act as
             * expected. That is: return the currently set signal-hand-
             * ler (and not the previous, as the man-pages state).
             * NOTE: Not MT-safe */
            r = os_sigactionSet(sig, NULL, &old_signalHandler[sig]);
            if (r < 0) {
                OS_REPORT(OS_ERROR, "os_signalHandlerEnableQuitSignals", 0,
                        "Could not retrieve currently set signal-handler for signal %d", sig);
                goto err_exitSigSet;
            }
            if(old_signalHandler[sig].sa_handler != SIG_IGN){
                /* We don't know if the oldHandler has been modified in the mean
                 * time, since there is no way to make the signal handler reentrant.
                 * It doesn't make sense to look for modifications now, since a
                 * new modification could be on its way while we are processing
                 * the current modification.
                 * For that reason we will ignore any intermediate modifications
                 * and continue setting our own handler. Processes should therefore
                 * refrain from modifying the signal handler in multiple threads.
                 */
                r = os_sigactionSet(sig, &_this->action, NULL);
                if (r != 0) {
                    OS_REPORT(OS_ERROR, "os_signalHandlerEnableQuitSignals", 0,
                            "os_sigactionSet(%d, 0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR") failed, result = %d",
                            sig, (os_address)&_this->action, (os_address)&old_signalHandler[sig], r);
                    goto err_exitSigSet;
                }
            }
        }
    }

    return os_resultSuccess;

err_exitSigSet:
    while(iExit) {
        const int sig = quits[--iExit];
        r = os_sigactionSet(sig, &old_signalHandler[sig], NULL);
        if (r < 0) {
            OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0,
                "Failed to restore original handler: os_sigactionSet(%d, 0x%"PA_PRIxADDR", NULL) failed, result = %d",
                sig, (os_address)&old_signalHandler[sig], r);
        }
    }

    return os_resultFail;
}
示例#6
0
static os_result
os_signalHandlerInit(
    os_signalHandler _this)
{
    os_result result = os_resultSuccess;
    os_sigset block_all_sigset, old_sigset;
    unsigned i;
    int r;
    os_threadAttr thrAttr;

    assert(_this);

    _this->handleExceptions = OS_FALSE;

    if(os__signalHandlerCallbackInit(&_this->callbackInfo) != os_resultSuccess) {
        goto err_callbackInfoInit;
    }

    if(!isSignallingSafe(1)){
        return os_resultSuccess;
    }

    /* Initialise the exceptionsMask */
    sigemptyset(&exceptionsMask);
    for(i = 0; i < lengthof(exceptions); i++){
        sigaddset(&exceptionsMask, exceptions[i]);
    }

    /* Initialise the quitsMask */
    sigemptyset(&quitsMask);
    for(i = 0; i < quits_len; i++){
        sigaddset(&quitsMask, quits[i]);
    }

    /* create signal handling pipes */
    r = pipe(_this->pipeIn);
    if (r < 0) {
        OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "pipe(_this->pipeIn) failed, result = %d", r);
        goto err_pipeIn;
    }

    r = fcntl(_this->pipeIn[0], F_SETFD, 1);
    if (r < 0) {
        OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeIn[0]) failed, result = %d", r);
        goto err_pipeInFcntl;
    }

    r = fcntl(_this->pipeIn[1], F_SETFD, 1);
    if (r < 0) {
        OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeIn[1]) failed, result = %d", r);
        goto err_pipeInFcntl;
    }

    r = pipe(_this->pipeOut);
    if (r < 0) {
        OS_REPORT(OS_ERROR, "os_signalHandlerInit", 1, "pipe(_this->pipeOut) failed, result = %d", r);
        goto err_pipeOut;
    }

    r = fcntl(_this->pipeOut[0], F_SETFD, 1);
    if (r < 0) {
        OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeOut[0]) failed, result = %d", r);
        goto err_pipeOutFcntl;
    }

    r = fcntl(_this->pipeOut[1], F_SETFD, 1);
    if (r < 0) {
        OS_REPORT(OS_WARNING, "os_signalHandlerInit", 0, "fcntl(_this->pipeOut[1]) failed, result = %d", r);
        goto err_pipeOutFcntl;
    }

    /* Block all signals in order to start the signalHandlerThread with all
     * signals blocked. */
    result = os_sigsetFill(&block_all_sigset);
    if (result != os_resultSuccess) {
        OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0,
                "os_sigsetFill(&block_all_sigset) failed: %s", os_resultImage(result));
        goto err_sigsetMask;
    }

    /* Remove signals that cannot be blocked. */
    for (i = 0; i < lengthof(excludes); i++) {
        const int sig = excludes[i];
        if (os_sigsetDel(&block_all_sigset, sig) != 0) {
            OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "os_sigsetDel(0x%"PA_PRIxADDR", %d) failed, result = %d",
                    (os_address)&_this->action, sig, r);
            goto err_sigsetMask;
        }
    }

    result = os_sigThreadSetMask(&block_all_sigset, &old_sigset);
    if (result != os_resultSuccess) {
        OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0, "os_sigThreadSetMask(0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR") failed: %s",
                    (os_address)&block_all_sigset, (os_address)&old_sigset, os_resultImage(result));
        goto err_sigsetMask;
    }

    /* Setup signal handler thread. */
    os_threadAttrInit(&thrAttr);
    thrAttr.stackSize = 4*1024*1024; /* 4 MB */
    result = os_threadCreate(&_this->threadId,
                             "signalHandler",
                             &thrAttr,
                             signalHandlerThread,
                             (void*)_this);

    if (result != os_resultSuccess) {
        OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0,
                    "os_threadCreate(0x%"PA_PRIxADDR", 0x%"PA_PRIxADDR",0x%"PA_PRIxADDR",0) failed: %s",
                    (os_address)&_this->threadId,
                    (os_address)&thrAttr,
                    (os_address)signalHandlerThread,
                    os_resultImage(result));
        goto err_threadCreate;
    }

    /* Reset signal mask to original value. */
    result = os_sigThreadSetMask(&old_sigset, NULL);
    if (result != os_resultSuccess) {
        OS_REPORT(OS_ERROR, "os_signalHandlerInit", 0,
                    "os_sigThreadSetMask(0x%"PA_PRIxADDR", NULL) failed: %s",
                    (os_address)&old_sigset, os_resultImage(result));
        goto err_sigResetMask;
    }

    /* install signal handlers */
    _this->action = os_sigactionNew(signalHandler, &block_all_sigset, SA_SIGINFO);

    if (os_signalHandlerEnableExitSignals() != os_resultSuccess) {
        goto err_enableExitHandling;
    }

    return os_resultSuccess;

/* Error handling */
err_enableExitHandling:
err_sigResetMask:
    os__signalHandlerThreadStop(_this);
err_threadCreate:
    (void) os_sigThreadSetMask(&old_sigset, NULL);
err_sigsetMask:
    /* No undo needed for fcntl's/sigsetFill */
err_pipeOutFcntl:
    (void) close(_this->pipeOut[0]);
    (void) close(_this->pipeOut[1]);
err_pipeOut:
    /* No undo needed for fcntl's */
err_pipeInFcntl:
    (void) close(_this->pipeIn[0]);
    (void) close(_this->pipeIn[1]);
err_pipeIn:
    os__signalHandlerCallbackDeinit(&_this->callbackInfo);
err_callbackInfoInit:
    return os_resultFail;
}
示例#7
0
/* protected functions */
void
os_processModuleInit(void)
{
#if !defined INTEGRITY && !defined VXWORKS_RTP
    struct sigaction action;
    pthread_attr_t      thrAttr;
    int result;

     result = pipe(_ospl_signalpipe);

    pthread_attr_init(&thrAttr);
    pthread_attr_setstacksize(&thrAttr, 4*1024*1024); /* 4MB */
    pthread_create(&_ospl_signalHandlerThreadId, &thrAttr, signalHandlerThread, (void*)0);


    /* install signal handlers */
    action.sa_handler = 0;
    action.sa_sigaction = signalHandler;
    sigfillset(&action.sa_mask); /* block all signals during handling of a signal */
    action.sa_flags = SA_SIGINFO;


    _SIGCURRENTACTION_(SIGINT);

    /* If the user has set a signal handler or explicitly told the system to
     * ignore the signal, we don't set a handler ourselves. It's the
     * responsibility of the user to make sure exit() is called to
     * terminate the application to make sure all shared memory resources
     * are properly cleaned up. This is on a per signal basis.
     */
    if ((_SIGNALVECTOR_(SIGINT).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGINT).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGINT);
    }
    _SIGCURRENTACTION_(SIGQUIT);

    if ((_SIGNALVECTOR_(SIGQUIT).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGQUIT).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGQUIT);
    }
    _SIGCURRENTACTION_(SIGHUP);

    if ((_SIGNALVECTOR_(SIGHUP).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGHUP).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGHUP);
    }
    _SIGCURRENTACTION_(SIGTERM);

    if ((_SIGNALVECTOR_(SIGTERM).sa_handler == SIG_DFL) ||
        (_SIGNALVECTOR_(SIGTERM).sa_handler == SIG_IGN)) {
        _SIGACTION_(SIGTERM);
    }

    if(isSignallingSafe(1)){
        _SIGCURRENTACTION_(SIGILL);

        if ((_SIGNALVECTOR_(SIGILL).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGILL).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGILL);
        }
        _SIGCURRENTACTION_(SIGABRT);

        if ((_SIGNALVECTOR_(SIGABRT).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGABRT).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGABRT);
        }
        _SIGCURRENTACTION_(SIGFPE);

        if ((_SIGNALVECTOR_(SIGFPE).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGFPE).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGFPE);
        }
        _SIGCURRENTACTION_(SIGSEGV);

        if ((_SIGNALVECTOR_(SIGSEGV).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGSEGV).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGSEGV);
        }
        _SIGCURRENTACTION_(SIGPIPE);

        if ((_SIGNALVECTOR_(SIGPIPE).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGPIPE).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGPIPE);
        }
        _SIGCURRENTACTION_(SIGALRM);

        if ((_SIGNALVECTOR_(SIGALRM).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGALRM).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGALRM);
        }
        _SIGCURRENTACTION_(SIGUSR1);

        if ((_SIGNALVECTOR_(SIGUSR1).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGUSR1).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGUSR1);
        }
        _SIGCURRENTACTION_(SIGUSR2);

        if ((_SIGNALVECTOR_(SIGUSR2).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGUSR2).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGUSR2);
        }
        /* Only in newer POSIX versions, ignoring for now
        _SIGCURRENTACTION_(SIGTSTOP);
        _SIGACTION_(SIGTSTOP);
        */
        _SIGCURRENTACTION_(SIGTTIN);

        if ((_SIGNALVECTOR_(SIGTTIN).sa_handler == SIG_DFL) ||
            (_SIGNALVECTOR_(SIGTTIN).sa_handler == SIG_IGN)) {
            _SIGACTION_(SIGTTIN);
        }
        /* Only in newer POSIX versions, ignoring for now
        _SIGCURRENTACTION_(SIGTTOUT);
        _SIGACTION_(SIGTTOUT);
        */
    }
#endif
}
示例#8
0
static os_result
os_signalHandlerInit(
    os_signalHandler _this)
{
    os_result result = os_resultSuccess;
    os_sigaction action;
    os_sigset block_all_sigset, old_sigset;
    int i, r;

    if (_this == NULL) {
        result = os_resultFail;
    }
    _this->exitRequestCallback = (os_signalHandlerExitRequestCallback)0;
    _this->exceptionCallback = (os_signalHandlerExceptionCallback)0;


    if(isSignallingSafe(1)) {
        /* Initialise the exceptionsMask */
        sigemptyset(&exceptionsMask);
        for(i = 0; i < lengthof(exceptions); i++) {
            sigaddset(&exceptionsMask, exceptions[i]);
        }

        /* Initialise the quitsMask */
        sigemptyset(&quitsMask);
        for(i = 0; i < lengthof(quits); i++) {
            sigaddset(&quitsMask, quits[i]);
        }

        /* create signal handling pipes */
        if (result == os_resultSuccess) {
            r = pipe(_this->pipeIn);
            if (r<0) {
                OS_REPORT_1(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "pipe(_this->pipeIn) failed, result = %d",
                            r);
                result = os_resultFail;
            } else {
                r = fcntl(_this->pipeIn[0], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeIn[0]) failed, result = %d", r);
                    assert(OS_FALSE);
                }
                r = fcntl(_this->pipeIn[1], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeIn[1]) failed, result = %d", r);
                    assert(OS_FALSE);
                }
            }
        }
        if (result == os_resultSuccess) {
            r = pipe(_this->pipeOut);
            if (r<0) {
                OS_REPORT_1(OS_ERROR,
                            "os_signalHandlerInit", 1,
                            "pipe(_this->pipeOut) failed, result = %d",
                            r);
                result = os_resultFail;
            } else {
                r = fcntl(_this->pipeOut[0], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeOut[0]) failed, result = %d",
                                r);
                    assert(OS_FALSE);
                }
                r = fcntl(_this->pipeOut[1], F_SETFD, 1);
                if (r<0) {
                    OS_REPORT_1(OS_WARNING,
                                "os_signalHandlerInit", 0,
                                "fcntl(_this->pipeOut[1]) failed, result = %d",
                                r);
                    assert(OS_FALSE);
                }
            }
        }
        /* Block all signals */
        if (result == os_resultSuccess) {
            result = os_sigsetFill(&block_all_sigset);
            if (result != os_resultSuccess) {
                OS_REPORT_1(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "os_sigsetFill(&block_all_sigset) failed, result = %d",
                            r);
                assert(OS_FALSE);
            } else {
                result = os_sigThreadSetMask(&block_all_sigset, &old_sigset);
                if (result != os_resultSuccess) {
                    OS_REPORT_3(OS_ERROR,
                                "os_signalHandlerInit", 0,
                                "os_sigThreadSetMask(0x%x, 0x%x) failed, result = %d",
                                &block_all_sigset, &old_sigset, r);
                    assert(OS_FALSE);
                }
            }
        }
        /* Setup signal handler thread. */
        if (result == os_resultSuccess) {
            os_threadAttr thrAttr;

            result = os_threadAttrInit(&thrAttr);
            if (result != os_resultSuccess) {
                OS_REPORT_2(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "pthread_attr_init(0x%x) failed, result = %d",
                            &thrAttr, r);
                assert(OS_FALSE);
            } else {
                thrAttr.stackSize = 4*1024*1024; /* 4 MB */
                result = os_threadCreate(&_this->threadId,
                                         "signalHandler",
                                         &thrAttr,
                                         signalHandlerThread,
                                         (void*)_this);

                if (result != os_resultSuccess) {
                    OS_REPORT_4(OS_ERROR,
                                "os_signalHandlerInit", 0,
                                "os_threadCreate(0x%x, 0x%x,0x%x,0) failed, result = %d",
                                &_this->threadId,
                                &thrAttr,
                                signalHandlerThread,
                                result);
                    assert(OS_FALSE);
                }
            }
        }
        /* Reset signal mask to original value. */
        if (result == os_resultSuccess) {
            result = os_sigThreadSetMask(&old_sigset, NULL);
            if (result != os_resultSuccess) {
                OS_REPORT_2(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "os_sigThreadSetMask(0x%x, NULL) failed, result = %d",
                            &old_sigset, r);
                result = os_resultFail;
                assert(OS_FALSE);
            }
        }
        /* install signal handlers */
        if (result == os_resultSuccess) {
            os_sigset mask;
            /* block all signals during handling of a signal */
            result = os_sigsetFill(&mask);
            if (result != os_resultSuccess) {
                OS_REPORT_2(OS_ERROR,
                            "os_signalHandlerInit", 0,
                            "os_sigsetFill(0x%x) failed, result = %d",
                            &action.sa_mask, result);
            } else {
                action = os_sigactionNew(signalHandler, &mask, SA_SIGINFO);
            }
            if (result == os_resultSuccess) {
                for (i=0; i<lengthof(exceptions); i++) {
                    const int sig = exceptions[i];
                    r = os_sigsetDel(&action.sa_mask, sig);
                    if (r<0) {
                        OS_REPORT_3(OS_ERROR,
                                    "os_signalHandlerInit", 0,
                                    "os_sigsetDel(0x%x, %d) failed, result = %d",
                                    &action, sig, r);
                        result = os_resultFail;
                        assert(OS_FALSE);
                    }
                }
            }
            if (result == os_resultSuccess) {
                for (i=0; i<lengthof(exceptions); i++) {
                    const int sig = exceptions[i];
                    /* For exceptions we always set our own signal handler, since
                     * applications that cause an exception are not in a position
                     * to ignore it. However, we will chain the old handler to our
                     * own.
                     */
                    r = os_sigactionSet(sig, &action, &old_signalHandler[sig]);
                    if (r < 0) {
                        OS_REPORT_4(OS_ERROR,
                                    "os_signalHandlerInit", 0,
                                    "os_sigactionSet(%d, 0x%x, 0x%x) failed, result = %d",
                                    sig, &action, &old_signalHandler[sig], r);
                        result = os_resultFail;
                        assert(OS_FALSE);
                    }
                }
            }
            if (result == os_resultSuccess) {
                for (i=0; i<lengthof(quits); i++) {
                    const int sig = quits[i];
                    /* By passing NULL we only retrieve the currently set handler. If
                     * the signal should be ignored, we don't do anything. Otherwise we
                     * chain the old handler to our own.
                     * man-page of sigaction only states behaviour when new
                     * action is non-NULL, but all known implementations act as
                     * expected. That is: return the currently set signal-hand-
                     * ler (and not the previous, as the man-pages state).
                     * NOTE: Not MT-safe */
                    r = os_sigactionSet(sig, NULL, &old_signalHandler[sig]);
                    if (r == 0) {
                        if(old_signalHandler[sig].sa_handler != SIG_IGN) {
                            /* We don't know if the oldHandler has been modified in the mean
                             * time, since there is no way to make the signal handler reentrant.
                             * It doesn't make sense to look for modifications now, since a
                             * new modification could be on its way while we are processing
                             * the current modification.
                             * For that reason we will ignore any intermediate modifications
                             * and continue setting our own handler. Processes should therefore
                             * refrain from modifying the signal handler in multiple threads.
                             */
                            r = os_sigactionSet(sig, &action, NULL);
                            if (r != 0) {
                                OS_REPORT_4(OS_ERROR,
                                            "os_signalHandlerInit", 0,
                                            "os_sigactionSet(%d, 0x%x, 0x%x) failed, result = %d",
                                            sig, &action, &old_signalHandler[sig], r);
                                result = os_resultFail;
                                assert(OS_FALSE);
                            }
                        } else {
                            OS_REPORT_1(OS_INFO,
                                        "os_signalHandlerThread", 0,
                                        "Not installing a signal handler for the already ignored signal %d.",
                                        sig);
                        }
                    } else {
                        OS_REPORT_1(OS_ERROR, "os_signalHandlerInit", 0, "Could not retrieve currently set signal-handler for signal %d", sig);
                        result = os_resultFail;
                        assert(OS_FALSE);
                    }
                }
            }
        }
    } else {
        result = os_resultSuccess;
    }
    return result;
}