Ejemplo n.º 1
0
LW_NTSTATUS
LwRtlMain(
    VOID
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    sigset_t waitSet;
    sigset_t intSet;
    siginfo_t info = {0};
    struct sigaction action;
    int ret = 0;
    int i = 0;

    memset(&action, 0, sizeof(action));

    LOCK_SIGNAL();

    sigfillset(&waitSet);
    sigfillset(&intSet);
    sigdelset(&intSet, SIGINT);

    for (i = 0; SignalBlacklist[i]; i++)
    {
        sigdelset(&waitSet, SignalBlacklist[i]);
        sigdelset(&intSet, SignalBlacklist[i]);
    }    

    /* Set a special handler for SIGINT */
    action.sa_handler = InterruptHandler;
    action.sa_flags = 0;
        
    if (sigaction(SIGINT, &action, NULL) < 0)
    {
        status = LwErrnoToNtStatus(errno);
        GOTO_ERROR_ON_STATUS(status);
    }

    status = LwRtlBlockSignals();
    GOTO_ERROR_ON_STATUS(status);

    for (;;)
    {
        UNLOCK_SIGNAL();
        // sigwaitinfo on HPUX 11.11 does not fill-in info.si_signo.
#if defined(HAVE_SIGWAITINFO) && !defined(__LWI_HP_UX__)
        ret = sigwaitinfo(&waitSet, &info);
#else
        ret = sigwait(&waitSet, &info.si_signo);
#endif
        LOCK_SIGNAL();

        if (ret < 0 && errno == EINTR)
        {
            continue;
        }

        if (ret < 0)
        {
            status = LwErrnoToNtStatus(errno);
            GOTO_ERROR_ON_STATUS(status);
        }

        if (gSignal.bExit)
        {
            status = gSignal.Status;
            gSignal.bExit = FALSE;
            gSignal.Status = STATUS_SUCCESS;
            break;
        }

        if (info.si_signo == SIGINT)
        {
            /* Make hitting ^C to break into a process in gdb work.
             *  
             * gdb can't trap SIGINT when we receive it with sigwaitinfo(),
             * so we reraise it against the process and then unblock it to
             * give the debugger a chance to intercept it.  If it is not
             * intercepted, InterruptHandler() will run and set gRealSigInt,
             * and we will forward the original SIGINT to all subscribed
             * tasks.  If the signal is intercepted, we pretend the original
             * SIGINT never happened, and the desired debugging behavior 
             * is preserved.
             */
            gRealSigInt = FALSE;
            kill(getpid(), SIGINT);
            status = LwErrnoToNtStatus(pthread_sigmask(SIG_SETMASK, &intSet, NULL));
            GOTO_ERROR_ON_STATUS(status);
            status = LwRtlBlockSignals();
            GOTO_ERROR_ON_STATUS(status);

            if (!gRealSigInt)
            {
                continue;
            }
        }

        DispatchSignal(&info);
    }

error:

    UNLOCK_SIGNAL();

    return status;
}
Ejemplo n.º 2
0
int
main(
    int argc,
    char** ppszArgv
    )
{
    DWORD dwError = 0;

    /* Parse command line */
    dwError = LwSmParseArguments(argc, ppszArgv);
    BAIL_ON_ERROR(dwError);

    /* Block all signals */
    dwError = LwNtStatusToWin32Error(LwRtlBlockSignals());
    BAIL_ON_ERROR(dwError);

    /* Fork into background if running as a daemon */
    if (gState.bStartAsDaemon)
    {
        dwError = LwSmDaemonize();
        BAIL_ON_ERROR(dwError);
    }

    /* If we're starting as the control server, acquire lock */
    if (!gState.bContainer)
    {
        dwError = LwSmControlLock();
        BAIL_ON_ERROR(dwError);
    }

    /* Create thread pool */
    dwError = LwNtStatusToWin32Error(LwRtlCreateThreadPool(&gpPool, NULL));
    BAIL_ON_ERROR(dwError);

    dwError = LWNetExtendEnvironmentForKrb5Affinity(FALSE);
    BAIL_ON_ERROR(dwError);

    /* Mac OS X - avoid potential circular calls into directory services */
    dwError = LwDsCacheAddPidException(getpid());
    BAIL_ON_ERROR(dwError);

    /* Initialize i18n */
    setlocale(LC_ALL, "");

    /* Initialize logging subsystem */
    LwSmLogInit();

    /* Set up logging */
    dwError = LwSmConfigureLogging(gState.pName);
    BAIL_ON_ERROR(dwError);

    /* Initialize the container subsystem */
    dwError = LwSmContainerInit();
    BAIL_ON_ERROR(dwError);

    /* Initialize the service table subsystem */
    dwError = LwSmTableInit();
    BAIL_ON_ERROR(dwError);

    /* Enter main loop */
    dwError = LwSmMain();
    BAIL_ON_ERROR(dwError);

error:

    /* If we are starting as a daemon and have not
       notified the parent process yet, notify it
       of an error now */
    if (gState.bStartAsDaemon && !gState.bNotified)
    {
        LwSmNotify(dwError);
    }

    /* Shut down service table */
    LwSmTableShutdown();

    /* Shut down containers */
    LwSmContainerShutdown();

    /* Shut down logging */
    LwSmLoggingShutdown();

    /* Remove DS cache exception */
    LwDsCacheRemovePidException(getpid());

    /* Free thread pool */
    LwRtlFreeThreadPool(&gpPool);

    /* Close control file if it is open */
    if (gState.ControlLock >= 0)
    {
        close(gState.ControlLock);
    }

    if (dwError)
    {
        fprintf(stderr, "Error: %s (%d)\n", LwWin32ExtErrorToName(dwError), (int) dwError);
    }

    return dwError ? 1 : 0;
}
Ejemplo n.º 3
0
static
DWORD
LwSmCmdTapLog(
    int argc,
    char** pArgv
    )
{
    DWORD error = ERROR_SUCCESS;
    PLW_THREAD_POOL pPool = NULL;
    PLW_TASK pTask = NULL;
    BOOLEAN bResetLogger = FALSE;
    BOOLEAN bRmPipe = FALSE;
    LW_SM_LOGGER_TYPE oldLogger = 0;
    PSTR pOldTarget = NULL;
    LW_SM_LOG_LEVEL oldLevel = 0;
    LW_SM_LOG_LEVEL newLevel = 0;
    PSTR pFacility = NULL;
    LW_SERVICE_HANDLE hHandle = NULL;
    PWSTR pServiceName = NULL;
    PSTR pFifo = NULL;
    int FifoFd = -1;

    if (argc < 4)
    {
        error = LW_ERROR_INVALID_PARAMETER;
        BAIL_ON_ERROR(error);
    }

    if (strcmp(pArgv[1], "-"))
    {
        error = LwMbsToWc16s(pArgv[1], &pServiceName);
        BAIL_ON_ERROR(error);

        error = LwSmAcquireServiceHandle(pServiceName, &hHandle);
        BAIL_ON_ERROR(error);
    }

    if (strcmp(pArgv[2], "-"))
    {
        pFacility = pArgv[2];
    }

    error = LwSmLogLevelNameToLogLevel(pArgv[3], &newLevel);
    BAIL_ON_ERROR(error);

    error = LwSmGetServiceLogState(hHandle, pFacility, &oldLogger, &pOldTarget, &oldLevel);
    BAIL_ON_ERROR(error);

    error = LwAllocateStringPrintf(&pFifo, "/tmp/.lwsm-log-tap-%lu", (unsigned long) getpid());
    BAIL_ON_ERROR(error);

    LwRtlBlockSignals();
    if (mknod(pFifo, S_IRUSR | S_IWUSR | S_IFIFO, 0) < 0)
    {
        error = LwErrnoToWin32Error(errno);
        BAIL_ON_ERROR(error);
    }
    bRmPipe = TRUE;

    if ((FifoFd = open(pFifo, O_RDONLY | O_NONBLOCK)) < 0)
    {
        error = LwErrnoToWin32Error(errno);
        BAIL_ON_ERROR(error);
    }

    if (fcntl(FifoFd, F_SETFL, O_NONBLOCK) < 0)
    {
        error = LwErrnoToWin32Error(errno);
        BAIL_ON_ERROR(error);
    }

    error = LwSmSetServiceLogTarget(hHandle, pFacility, LW_SM_LOGGER_FILE, pFifo);
    BAIL_ON_ERROR(error);
    bResetLogger = TRUE;

    error = LwSmSetServiceLogLevel(hHandle, pFacility, newLevel);
    BAIL_ON_ERROR(error);

    error = LwNtStatusToWin32Error(LwRtlCreateThreadPool(&pPool, NULL));
    BAIL_ON_ERROR(error);

    error = LwNtStatusToWin32Error(LwRtlCreateTask(pPool, &pTask, NULL, LogTapper, &FifoFd));
    BAIL_ON_ERROR(error);

    LwRtlWakeTask(pTask);

    error = LwNtStatusToWin32Error(LwRtlMain());
    BAIL_ON_ERROR(error);

error:

    if (pTask)
    {
        LwRtlCancelTask(pTask);
        LwRtlWaitTask(pTask);
        LwRtlReleaseTask(&pTask);
    }

    LwRtlFreeThreadPool(&pPool);

    if (bResetLogger)
    {
        error = LwSmSetServiceLogLevel(hHandle, pFacility, oldLevel);
        BAIL_ON_ERROR(error);

        error = LwSmSetServiceLogTarget(hHandle, pFacility, oldLogger, pOldTarget);
        BAIL_ON_ERROR(error);
    }

    if (pOldTarget)
    {
        LwSmFreeLogTarget(pOldTarget);
    }

    if (FifoFd >= 0)
    {
        close(FifoFd);
    }

    if (bRmPipe)
    {
        unlink(pFifo);
    }

    LW_SAFE_FREE_MEMORY(pFifo);

    return error;
}