# # # patch "usher.cc" # from [26b4efedf05795ec674114086ff65e94248eb8ae] # to [ebc7204d4bc9b3c95203f0f23149d45b8d6b9796] # ============================================================ --- usher.cc 26b4efedf05795ec674114086ff65e94248eb8ae +++ usher.cc ebc7204d4bc9b3c95203f0f23149d45b8d6b9796 @@ -63,6 +63,8 @@ #include #include #include +#include +#include #include #include #include @@ -75,6 +77,7 @@ #include #include +#include #include #include #include @@ -108,6 +111,7 @@ int listenport = 4691; string listenaddr = "0.0.0.0"; string monotone = "monotone"; +string logdir = "."; // keep local servers around for this many seconds after the last // client disconnects from them (only accurate to ~10 seconds) @@ -464,11 +468,23 @@ return s; } -int fork_server(vector const & args) +int fork_server(const string & name, vector const & args) { +#ifdef RL_DEBUG + cerr << "Forking this command: "; + copy(args.begin(), args.end(), std::ostream_iterator(cerr, " ")); + cerr << std::endl; +#endif + + string logfile = logdir + "/" + name + ".log"; int err[2]; - if (pipe(err) < 0) + if ((err[1]=open(logfile.c_str(),O_CREAT|O_APPEND,0644)) < 0) return false; + if ((err[0]=open(logfile.c_str(),O_RDONLY)) < 0) + { + close(err[1]); + return false; + } int pid = fork(); if (pid == -1) { close(err[0]); @@ -481,9 +497,13 @@ close(1); close(2); sock::close_all_socks(); - if (dup2(err[1], 2) < 0) { + if (dup2(err[1], 1) < 0) { exit(1); } + close(err[1]); + if (dup2(1, 2) < 0) { + exit(1); + } char ** a = new char*[args.size()+1]; for (unsigned int i = 0; i < args.size(); ++i) { @@ -514,7 +534,8 @@ line = true; got += r; } - } while(r > 0 && !line && got < 256); + } while(r >= 0 && !line && got < 256); + close(err[0]); head[got] = 0; if (string(head).find("beginning service") != string::npos) return pid; @@ -666,17 +687,25 @@ for (vector::const_iterator i = h.begin(); i != h.end(); ++i) { c = servers_by_host.find(*i); if (c != servers_by_host.end()) { + cerr << "Removing duplicate for hostname " << *i << " in:" << std::endl + << " "; list >::iterator>::iterator j; + bool first = true; for (j = c->second->by_host.begin(); j != c->second->by_host.end(); ++j) { list >::iterator>::iterator j_saved = j; ++j; - if ((*j_saved)->first == *i) { - servers_by_host.erase(*j_saved); - c->second->by_host.erase(j_saved); - } + cerr << (first ? "" : ", ") << (*j_saved)->second->by_name->first; + first = false; + if ((*j_saved)->first == *i) + { + servers_by_host.erase(*j_saved); + c->second->by_host.erase(j_saved); + } } + cerr << std::endl + << " ... because it appeared in " << by_name->first << std::endl; } c = servers_by_host.insert(make_pair(*i, me)).first; by_host.push_back(c); @@ -693,12 +722,25 @@ for (vector::const_iterator i = p.begin(); i != p.end(); ++i) { c = servers_by_pattern.find(*i); if (c != servers_by_pattern.end()) { + cerr << "Removing duplicate for pattern " << *i << " in: " << std::endl + << " "; list >::iterator>::iterator j; + bool first = true; for (j = c->second->by_pat.begin(); j != c->second->by_pat.end(); ++j) - if ((*j)->first == *i) { - servers_by_pattern.erase(*j); - c->second->by_pat.erase(j); + { + list >::iterator>::iterator j_saved + = j; + ++j; + cerr << (first ? "" : ", ") << (*j_saved)->second->by_name->first; + first = false; + if ((*j_saved)->first == *i) + { + servers_by_pattern.erase(*j_saved); + c->second->by_pat.erase(j_saved); + } } + cerr << std::endl + << " ... because it appeared in " << by_name->first << std::endl; } c = servers_by_pattern.insert(make_pair(*i, me)).first; by_pat.push_back(c); @@ -720,6 +762,7 @@ vector args; args.push_back(monotone); args.push_back("serve"); + args.push_back("--ticker=dot"); args.push_back("--bind=" + addr + ":" + lexical_cast(port)); unsigned int n = 0, m = 0; n = arguments.find_first_not_of(" \t"); @@ -728,7 +771,7 @@ args.push_back(arguments.substr(n, m-n)); n = arguments.find_first_not_of(" ", m); } - pid = fork_server(args); + pid = fork_server(by_name->first,args); } } sock s = make_outgoing(port, addr); @@ -1372,6 +1415,8 @@ string user = readtok(cf).s; string pass = readtok(cf).s; admins.insert(make_pair(user, pass)); + } else if(tok.s == "logdir") { + logdir = readtok(cf).s; } else if(tok.s == "hostname") { hostname = readtok(cf).s; } else if(tok.s == "project_dir") {