Beispiel #1
0
static
VOID
MainTask(
    PLW_TASK pTask,
    PVOID pContext,
    LW_TASK_EVENT_MASK WakeMask,
    PLW_TASK_EVENT_MASK pWaitMask,
    PLONG64 pllTime
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    siginfo_t info;

    if (WakeMask & LW_TASK_EVENT_CANCEL)
    {
        *pWaitMask = LW_TASK_EVENT_COMPLETE;
        goto cleanup;
    }
    else if (WakeMask & LW_TASK_EVENT_INIT)
    {
        status = LwRtlSetTaskUnixSignal(pTask, SIGTERM, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskUnixSignal(pTask, SIGINT, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskUnixSignal(pTask, SIGHUP, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlQueueWorkItem(gpPool, Startup, NULL, 0);
        BAIL_ON_ERROR(status);

        *pWaitMask = LW_TASK_EVENT_UNIX_SIGNAL;
    }
    else if (WakeMask & LW_TASK_EVENT_UNIX_SIGNAL)
    {
        while (LwRtlNextTaskUnixSignal(pTask, &info))
        {
            switch(info.si_signo)
            {
            case SIGTERM:
            case SIGINT:
                SM_LOG_VERBOSE(info.si_signo == SIGINT ?
                    "Shutting down on SIGINT" :
                    "Shutting down on SIGTERM");
                /* Shutting down stops all running services, which is a blocking operation */
                status = LwRtlQueueWorkItem(gpPool, Shutdown, NULL, 0);
                BAIL_ON_ERROR(status);
                *pWaitMask = LW_TASK_EVENT_COMPLETE;
                goto cleanup;
            case SIGHUP:
                SM_LOG_VERBOSE("Refreshing configuration on SIGHUP");
                /* Refreshing config reads from the registry, which is a blocking operation */
                status = LwRtlQueueWorkItem(gpPool, RefreshConfig, NULL, 0);
                BAIL_ON_ERROR(status);
                break;
            default:
                break;
            }
        }

        *pWaitMask = LW_TASK_EVENT_UNIX_SIGNAL;
    }

cleanup:

    return;

error:

    if (status)
    {
        LwRtlExitMain(status);
        *pWaitMask = LW_TASK_EVENT_COMPLETE;
    }

    goto cleanup;
}
Beispiel #2
0
static
VOID
LogTapper(
    PLW_TASK pTask,
    PVOID pContext,
    LW_TASK_EVENT_MASK WakeMask,
    LW_TASK_EVENT_MASK* pWaitMask,
    LONG64* pllTime
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    int FifoFd = *(int*) pContext;
    siginfo_t info = {0};
    char buffer[2048] = {0};
    ssize_t count = 0;

    if (WakeMask & LW_TASK_EVENT_CANCEL)
    {
        status = STATUS_CANCELLED;
        BAIL_ON_ERROR(status);
    }
    else if (WakeMask & LW_TASK_EVENT_INIT)
    {
        status = LwRtlSetTaskUnixSignal(pTask, SIGINT, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskUnixSignal(pTask, SIGTERM, TRUE);
        BAIL_ON_ERROR(status);

        status = LwRtlSetTaskFd(pTask, FifoFd, LW_TASK_EVENT_FD_READABLE);
        BAIL_ON_ERROR(status);
    }
    else if (WakeMask & LW_TASK_EVENT_UNIX_SIGNAL)
    {
        while (LwRtlNextTaskUnixSignal(pTask, &info))
        {
            if (info.si_signo == SIGINT || info.si_signo == SIGTERM)
            {
                status = STATUS_CANCELLED;
                BAIL_ON_ERROR(status);
            }
        }
    }
    else if (WakeMask & LW_TASK_EVENT_FD_READABLE)
    {
        do
        {
            do
            {
                count = read(FifoFd, buffer, sizeof(buffer));
            } while (count < 0 && errno == EINTR);

            if (count == 0)
            {
                status = STATUS_END_OF_FILE;
                BAIL_ON_ERROR(status);
            }
            else if (count > 0)
            {
                count = write(1, buffer, count);
                if (count < 0)
                {
                    status = LwErrnoToNtStatus(errno);
                    BAIL_ON_ERROR(status);
                }
            }
            else if (errno != EAGAIN)
            {
                status = LwErrnoToNtStatus(errno);
                BAIL_ON_ERROR(status);
            }
        } while (count > 0);
    }

    *pWaitMask = LW_TASK_EVENT_FD_READABLE | LW_TASK_EVENT_UNIX_SIGNAL;

cleanup:

    return;

error:

    *pWaitMask = LW_TASK_EVENT_COMPLETE;
    LwRtlSetTaskFd(pTask, FifoFd, 0);
    LwRtlExitMain(status);

    goto cleanup;
}