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; }
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; }