Children mainParse(I& be, I& en, Pos& pos) { Children ret; while(be != en) { eatWhitespaceComment(be, en, pos); if(test(be, en, "<{{")) { ret.push_back(std::move(parseC(be, en, pos))); } else if(test(be, en, '<')) { ret.push_back(std::move(parseNode(be, en, pos))); } else if(test(be, en, '>')) { eat(be, '>', pos); break; } else { I iter; TNodeType type; if(!test(be, en, "&{{") && *be == '&') { iter = eatUntil(be, en, "\n", pos); /*for(iter = be; !test(iter, en, '\n') && !test(iter, en, "//"); increment(iter, pos)) { } if(test(be, en, "//")) { eatWhitespaceComment(be, en, pos); }*/ type = TNodeType::SingleCppLine; } else { iter = eatUntil(be, en, "\n>", pos); for(iter = be; !test(iter, en, '\n') && !test(iter, en, "//") && !test(iter, en, '>'); increment(iter, pos)) { } if(test(be, en, "//")) { eatWhitespaceComment(be, en, pos); } type = TNodeType::Text; } auto posCopy = pos; //std::cout<<"||| "<<std::string(be, iter)<<std::endl; ret.push_back( std::make_unique<TNode>(std::string(be, iter), posCopy, type ) ); be = iter; char iterC = *iter; eat(be, iterC, pos); if(iterC == '>') { break; } } eatWhitespaceComment(be, en, pos); } return ret; }
void cHandler::GetChildren( Children& children ) const { cObject::GetChildren( children ); Resources::const_iterator iter = m_resources.begin(); Resources::const_iterator end = m_resources.end(); for ( ; iter != end; ++iter ) { cResource * r = iter->second; children.push_back( r ); } }
inline void add_child (int c) { child.push_back (c); }
void start() { std::ofstream pidfile(SC_PID); if (!pidfile.good()) { std::cerr << "cannot open PID file " << SC_PID << ": " << strerror(errno) << std::endl; exit(errno); } pidfile << getpid() << std::endl; pidfile.close(); std::ofstream log; log.open(SC_LOG, std::ofstream::app); log << "\n" << logPrefix() << "starting shoutcast daemon" << std::endl; log << logPrefix() << "reading shoutcast configuration files from " << SC_CONFIG << std::endl; log.close(); // Enumerate config files in shoutcast config dir. DIR *dir; struct dirent *ent; dir = opendir (SC_CONFIG); if (dir == NULL) { log.open(SC_LOG, std::ofstream::app); log << logPrefix() << "cannot read scd configuration direcoty " << SC_CONFIG << ": " << strerror(errno) << std::endl; log.close(); exit(errno); } for (; ent = readdir(dir); ent != NULL) { std::string cfgfile = ent->d_name; if (cfgfile == "." || cfgfile == "..") { continue; } std::string cfgpath = SC_CONFIG; cfgpath += "/"; cfgpath += cfgfile; Child c; c.pid = 0; c.config = cfgpath; size_t idx = cfgfile.find("."); c.log = SC_LOGDIR"sc_stream_"; c.log += cfgfile.substr(0, idx); c.log += ".log"; g_children.push_back(c); log.open(SC_LOG, std::ofstream::app); log << logPrefix() << "found shoutcast configuration: " << cfgpath << std::endl; log.close(); } closedir(dir); // Start respawn loop. while (g_running) { // Respawn all children with zero pid. for (Children::iterator i = g_children.begin(); i != g_children.end(); ++i) { if (i->pid == 0) { i->pid = fork(); if (i->pid == 0) { // Open log file and redirect stdout, stderr. FILE *f = fopen(i->log.c_str(), "a"); int r1 = dup2(fileno(f), 1); int r2 = dup2(fileno(f), 2); fclose(f); // Start child process. std::cout << timeStr() << "[" << getpid() << "] started" << std::endl; if (execl(SC_EXEC, SC_EXEC, i->config.c_str(), (char*)0) < 0) { exit(1); } } else { log.open(SC_LOG, std::ofstream::app); log << logPrefix() << "spawned server for config " << i->config << ", server pid is [" << i->pid << "]" << std::endl; log.close(); } } } // Wait for any failed children. int status; pid_t pid = wait(&status); if (!g_running) break; // Mark a failed child to restart. for (Children::iterator i = g_children.begin(); i != g_children.end(); ++i) { if (i->pid == pid) { log.open(SC_LOG, std::ofstream::app); log << logPrefix() << "server with pid [" << pid << "] (" << i->config << ") failed with status " << status << std::endl; log.close(); i->pid = 0; break; } } } log.open(SC_LOG, std::ofstream::app); log << logPrefix() << "terminated" << "\n" << std::endl; log.close(); }