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