#include "Server.hpp"
-#include "Connection.hpp"
+#include "Retry.hpp"
#include "ForkAndExec.hpp"
#include <sys/wait.h>
optional<string> Server::handleArg(vector<char *> &arr, const string &arg, const arg_func_t &next_arg) {
pushArg(arr, arg);
- if (arg == "-p" || arg == "--port") {
+ if (arg == "-U" || arg == "--udp-port") {
+ auto port = next_arg(arg);
+ pushArg(arr, port);
+ pushArg(arr, "-p");
+ pushArg(arr, port);
+ socket_or_port = stoi(port);
+ return port;
+ } else if (arg == "-p" || arg == "--port") {
auto port = next_arg(arg);
pushArg(arr, port);
-// pushArg(arr, "-U");
-// pushArg(arr, port);
socket_or_port = stoi(port);
return port;
} else if (arg == "-s" || arg == "--unix-socket") {
vector<char *> arr;
pushArg(arr, binary);
- //pushArg(arr, "-v");
+ pushArg(arr, "-u");
+ pushArg(arr, "nobody");
for (auto it = args.cbegin(); it != args.cend(); ++it) {
if (holds_alternative<arg_t>(*it)) {
return ChildProc{pid, pipe};
}
-bool Server::isListening() {
+bool Server::isListening() const {
MemcachedPtr memc;
if (holds_alternative<string>(socket_or_port)) {
}
Malloced stat(memcached_stat(*memc, nullptr, nullptr));
- if (!*stat || !stat->pid || stat->pid != pid) {
+ if (!*stat || !stat->pid || stat->pid == -1) {
+ return false;
+ }
+ if (stat->pid != pid) {
+ cerr << "Another server is listening on " << socket_or_port
+ << " (expected pid " << pid << " found pid " << stat->pid << ")\n";
return false;
}
return true;
}
+bool Server::ensureListening() {
+ if (!start()) {
+ return false;
+ }
+ return Retry{[this] {
+ again:
+ start();
+ if (!isListening()) {
+ auto old = pid;
+ if (tryWait()) {
+ cerr << "Collected zombie " << *this << "(old pid=" << old << ")\n";
+ goto again;
+ }
+ }
+ return isListening();
+ }}();
+}
+
bool Server::stop() {
if (!pid) {
return true;
bool Server::wait(int flags) {
if (pid && pid == waitpid(pid, &status, flags)) {
- if (drain().length()) {
- cerr << "Ouput of " << *this << ":\n" << output << endl;
+ if (drain().length() &&
+ output.rfind("Signal handled: Terminated", 0) != 0) {
+ cerr << "Output of " << *this << ":\n";
+
+ istringstream iss{output};
+ string line;
+
+ while (getline(iss, line)) {
+ cerr << " " << line << "\n";
+ }
+
+ if (output.back() != '\n') {
+ cerr << endl;
+ }
output.clear();
}
pid = 0;