Beispiel #1
1
/***********************************************************************************************************************************
Execute main function in Perl
***********************************************************************************************************************************/
int
perlExec(void)
{
    FUNCTION_LOG_VOID(logLevelDebug);

    // Initialize Perl
    perlInit();

    // Run perl main function
    perlEval(perlMain());

    // Return result code
    int code = (int)SvIV(get_sv("iResult", 0));
    bool errorC = (int)SvIV(get_sv("bErrorC", 0));
    char *message = SvPV_nolen(get_sv("strMessage", 0));                            // {uncovered - internal Perl macro branch}

    if (code >= errorTypeCode(&AssertError))                                        // {uncovered - success tested in integration}
    {
        if (errorC)                                                                 // {+uncovered}
            RETHROW();                                                              // {+uncovered}
        else
            THROW_CODE(code, strlen(message) == 0 ? PERL_EMBED_ERROR : message);    // {+uncovered}
    }

    FUNCTION_LOG_RETURN(INT, code);                                               // {+uncovered}
}
Beispiel #2
0
/***********************************************************************************************************************************
Catch signals
***********************************************************************************************************************************/
static void
exitOnSignal(int signalType)
{
    FUNCTION_LOG_BEGIN(logLevelTrace);
        FUNCTION_LOG_PARAM(INT, signalType);
    FUNCTION_LOG_END();

    exit(exitSafe(errorTypeCode(&TermError), false, (SignalType)signalType));

    FUNCTION_LOG_RETURN_VOID();
}
Beispiel #3
0
/***********************************************************************************************************************************
Execute main function in Perl
***********************************************************************************************************************************/
static int perlExecResult(int code, bool errorC, const char *message)
{
    FUNCTION_TEST_BEGIN();
        FUNCTION_TEST_PARAM(INT, code);
        FUNCTION_TEST_PARAM(BOOL, errorC);
        FUNCTION_TEST_PARAM(STRINGZ, message);
    FUNCTION_TEST_END();

    int result = code;

    if (code >= errorTypeCode(&AssertError))
    {
        if (errorC)
            RETHROW();
        else
            THROW_CODE(code, strlen(message) == 0 ? PERL_EMBED_ERROR : message);
    }

    FUNCTION_TEST_RETURN(result);
}
Beispiel #4
0
/***********************************************************************************************************************************
Do cleanup and return result code
***********************************************************************************************************************************/
int
exitSafe(int result, bool error, SignalType signalType)
{
    FUNCTION_LOG_BEGIN(logLevelDebug);
        FUNCTION_LOG_PARAM(INT, result);
        FUNCTION_LOG_PARAM(BOOL, error);
        FUNCTION_LOG_PARAM(ENUM, signalType);
    FUNCTION_LOG_END();

    // Report error if one was thrown
    if (error)
    {
        // Don't log the error if it has already been logged by Perl
#ifdef HAVE_LIBPERL
        if (strcmp(errorMessage(), PERL_EMBED_ERROR) != 0)
        {
#endif
            LogLevel logLevel = errorCode() == errorTypeCode(&AssertError) ? logLevelAssert : logLevelError;

            // Assert errors always output a stack trace
            if (logLevel == logLevelAssert)
                LOG(logLevel, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(), errorStackTrace());
            else
            {
                // Log just the error to non-debug levels
                LOG_INTERNAL(logLevel, LOG_LEVEL_MIN, logLevelDetail, 0, errorCode(), errorMessage());

                // Log the stack trace debug levels
                if (logAny(logLevelDebug))
                {
                    LOG_INTERNAL(
                        logLevel, logLevelDebug, LOG_LEVEL_MAX, 0, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(),
                        errorStackTrace());
                }
            }
#ifdef HAVE_LIBPERL
        }
#endif

        result = errorCode();
    }

    // Free protocol objects but ignore errors
    TRY_BEGIN()
    {
        protocolFree();
    }
    TRY_END();

    // Free Perl but ignore errors
#ifdef HAVE_LIBPERL
    TRY_BEGIN()
    {
        perlFree(result);
    }
    TRY_END();
#endif

    // Log command end if a command is set
    if (cfgCommand() != cfgCmdNone)
    {
        String *errorMessage = NULL;

        // On error generate an error message
        if (result != 0)
        {
            // On process terminate
            if (result == errorTypeCode(&TermError))
            {
                errorMessage = strNew("terminated on signal ");

                // Terminate from a child
                if (signalType == signalTypeNone)
                    strCat(errorMessage, "from child process");
                // Else terminated directly
                else
                    strCatFmt(errorMessage, "[SIG%s]", exitSignalName(signalType));
            }
            // Standard error exit message
            else if (error)
                errorMessage = strNewFmt("aborted with exception [%03d]", result);
        }

        cmdEnd(result, errorMessage);
    }

    // Release any locks but ignore errors
    TRY_BEGIN()
    {
        lockRelease(false);
    }
    TRY_END();

    // Return result - caller should immediate pass this result to exit()
    FUNCTION_LOG_RETURN(INT, result);
}