void LoggerImpl::runLoggerProcess(const std::string& user, const std::string& group) { struct passwd * pw = 0; if (!user.empty()) { pw = getpwnam(user.c_str()); if (pw == 0) throw std::runtime_error("unknown user \"" + user + "\" in logging configuration"); } struct group * gr = 0; if (!group.empty()) { gr = getgrnam(group.c_str()); if (gr == 0) throw std::runtime_error("unknown group \"" + group + "\" in logging configuration"); } pipe = new posix::Pipestream(); pid_t pid = ::fork(); if(pid < 0) throw SystemError("fork"); if (pid == 0) { // 1st child pipe->closeWriteFd(); pid = ::fork(); if (pid < 0) exit(-1); if (pid) exit(0); // exit middle process // 2nd child std::streambuf* in = pipe->rdbuf(); // set global pipe pointer to 0, so that getAppender do not return // that pipe, but skips to the next appender pipe = 0; setUserAndGroup(pw, gr); log_debug("logger process initialized"); char ich; std::ostream& out = getAppender(); while ((ich = in->snextc()) != std::ios::traits_type::eof()) { char ch = std::ios::traits_type::to_char_type(ich); out.rdbuf()->sputc(ch); if (ch == '\n') getAppender().flush(); } exit(0); } else { // parent pipe->closeReadFd(); int status; ::waitpid(pid, &status, 0); if (WEXITSTATUS(status) != 0) throw std::runtime_error("error creating logging process"); } }
Appender* Appender::getAppender( const char * pName ) { return getAppender( pName, "appender.ps" ); }