fix(master): a server that fails to start doesn't leave a second master running

When execl failed in the forked child (seen when WorldServer was being
relinked as a property world was started), the child carried on as a copy of
the master: it logged "WorldServer PID is 0" and kept running, and the
player waiting for that world stayed stuck. The child now reports the error
and exits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Aaron Kimbrell
2026-09-28 11:35:51 -05:00
parent 379f09dd7c
commit 64e53bace3

View File

@@ -32,6 +32,7 @@ namespace {
};
}
#else
#include <cstdio>
#include <unistd.h>
#endif
@@ -65,6 +66,9 @@ uint32_t StartChatServer() {
} else if (chat_pid == 0) {
// We are the child process
execl(chat_path.string().c_str(), chat_path.string().c_str(), nullptr);
// exec failed (e.g. the binary is being rebuilt): the child must not carry on as a second master
perror("exec");
_exit(127);
}
#endif
LOG("ChatServer PID is %d", chat_pid);
@@ -101,6 +105,9 @@ uint32_t StartAuthServer() {
} else if (auth_pid == 0) {
// We are the child process
execl(auth_path.string().c_str(), auth_path.string().c_str(), nullptr);
// exec failed (e.g. the binary is being rebuilt): the child must not carry on as a second master
perror("exec");
_exit(127);
}
#endif
LOG("AuthServer PID is %d", auth_pid);
@@ -137,6 +144,9 @@ uint32_t StartDashboardServer() {
} else if (web_pid == 0) {
// We are the child process
execl(web_path.string().c_str(), web_path.string().c_str(), nullptr);
// exec failed (e.g. the binary is being rebuilt): the child must not carry on as a second master
perror("exec");
_exit(127);
}
#endif
LOG("DashboardServer PID is %d", web_pid);
@@ -173,6 +183,9 @@ uint32_t StartUgcServer() {
} else if (ugc_pid == 0) {
// We are the child process
execl(ugc_path.string().c_str(), ugc_path.string().c_str(), nullptr);
// exec failed (e.g. the binary is being rebuilt): the child must not carry on as a second master
perror("exec");
_exit(127);
}
#endif
LOG("UgcServer PID is %d", ugc_pid);
@@ -214,6 +227,9 @@ uint32_t StartWorldServer(LWOMAPID mapID, uint16_t port, LWOINSTANCEID lastInsta
"-instance", std::to_string(lastInstanceID).c_str(),
"-maxclients", std::to_string(maxPlayers).c_str(),
"-clone", std::to_string(cloneID).c_str(), nullptr);
// exec failed (e.g. the binary is being rebuilt): the child must not carry on as a second master
perror("exec");
_exit(127);
}
#endif
LOG("WorldServer PID is %d", world_pid);