Skip to content

Commit

Permalink
fix(Server): Handle "socket already exists" more gracefully
Browse files Browse the repository at this point in the history
  • Loading branch information
whisperity committed May 7, 2022
1 parent 5705478 commit 8ff2c80
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 63 deletions.
54 changes: 27 additions & 27 deletions src/client/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,33 +226,33 @@ int main(Options& Opts)
{
ScopeGuard TerminalSetup{[&Term, &Client] { Term.setupClient(Client); },
[&Term] { Term.releaseClient(); }};
ScopeGuard Signal{
[&Term] {
SignalHandling& Sig = SignalHandling::get();
Sig.registerObject(SignalHandling::ModuleObjName, "Client");
Sig.registerObject(TerminalObjName, &Term);
Sig.registerCallback(SIGWINCH, &windowSizeChange);
Sig.enable();

// Override the SIGABRT handler with a custom one that
// resets the terminal during a crash.
Sig.registerCallback(SIGILL, &coreDumped);
Sig.registerCallback(SIGABRT, &coreDumped);
Sig.registerCallback(SIGSEGV, &coreDumped);
Sig.registerCallback(SIGSYS, &coreDumped);
Sig.registerCallback(SIGSTKFLT, &coreDumped);
},
[] {
SignalHandling& Sig = SignalHandling::get();
Sig.defaultCallback(SIGWINCH);
Sig.deleteObject(TerminalObjName);

Sig.clearOneCallback(SIGILL);
Sig.clearOneCallback(SIGABRT);
Sig.clearOneCallback(SIGSEGV);
Sig.clearOneCallback(SIGSYS);
Sig.clearOneCallback(SIGSTKFLT);
}};
ScopeGuard Signal{[&Term] {
SignalHandling& Sig = SignalHandling::get();
Sig.registerObject(SignalHandling::ModuleObjName,
"Client");
Sig.registerObject(TerminalObjName, &Term);
Sig.registerCallback(SIGWINCH, &windowSizeChange);
Sig.enable();

// Override the SIGABRT handler with a custom one that
// resets the terminal during a crash.
Sig.registerCallback(SIGILL, &coreDumped);
Sig.registerCallback(SIGABRT, &coreDumped);
Sig.registerCallback(SIGSEGV, &coreDumped);
Sig.registerCallback(SIGSYS, &coreDumped);
Sig.registerCallback(SIGSTKFLT, &coreDumped);
},
[] {
SignalHandling& Sig = SignalHandling::get();
Sig.defaultCallback(SIGWINCH);
Sig.deleteObject(TerminalObjName);

Sig.clearOneCallback(SIGILL);
Sig.clearOneCallback(SIGABRT);
Sig.clearOneCallback(SIGSEGV);
Sig.clearOneCallback(SIGSYS);
Sig.clearOneCallback(SIGSTKFLT);
}};

LOG(trace) << "Starting client...";

Expand Down
87 changes: 51 additions & 36 deletions src/server/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,9 @@ constexpr char ServerObjName[] = "Server";
void serverShutdown(SignalHandling::Signal SigNum,
::siginfo_t* Info,
const SignalHandling* Handling);

void childExited(SignalHandling::Signal SigNum,
::siginfo_t* Info,
const SignalHandling* Handling);

void coreDumped(SignalHandling::Signal SigNum,
::siginfo_t* Info,
const SignalHandling* Handling);
Expand All @@ -90,41 +88,58 @@ void coreDumped(SignalHandling::Signal SigNum,

int main(Options& Opts)
{
Socket ServerSock = Socket::create(*Opts.SocketPath);
Server S = Server(std::move(ServerSock));
std::optional<Socket> ServerSock;
try
{
ServerSock.emplace(Socket::create(*Opts.SocketPath));
}
catch (const std::system_error& SE)
{
LOG(fatal) << "Creating the socket '" << *Opts.SocketPath << "' failed:\n\t"
<< SE.what();
if (SE.code() == std::errc::address_in_use)
LOG(info) << "If you are sure another server is not running, delete the "
"file and restart the server.";
return EXIT_SystemError;
}

Server S = Server(std::move(*ServerSock));
S.setExitIfNoMoreSessions(Opts.ExitOnLastSessionTerminate);
ScopeGuard Signal{
[&S] {
SignalHandling& Sig = SignalHandling::get();
Sig.registerObject(SignalHandling::ModuleObjName, "Server");
Sig.registerObject(ServerObjName, &S);
Sig.registerCallback(SIGINT, &serverShutdown);
Sig.registerCallback(SIGTERM, &serverShutdown);
Sig.registerCallback(SIGCHLD, &childExited);
Sig.ignore(SIGPIPE);
Sig.enable();

// Override the SIGABRT handler with a custom one that kills the server.
Sig.registerCallback(SIGILL, &coreDumped);
Sig.registerCallback(SIGABRT, &coreDumped);
Sig.registerCallback(SIGSEGV, &coreDumped);
Sig.registerCallback(SIGSYS, &coreDumped);
Sig.registerCallback(SIGSTKFLT, &coreDumped);
},
[] {
SignalHandling& Sig = SignalHandling::get();
Sig.unignore(SIGPIPE);
Sig.defaultCallback(SIGCHLD);
Sig.defaultCallback(SIGTERM);
Sig.defaultCallback(SIGINT);
Sig.deleteObject(ServerObjName);

Sig.clearOneCallback(SIGILL);
Sig.clearOneCallback(SIGABRT);
Sig.clearOneCallback(SIGSEGV);
Sig.clearOneCallback(SIGSYS);
Sig.clearOneCallback(SIGSTKFLT);
}};
ScopeGuard Signal{[&S] {
SignalHandling& Sig = SignalHandling::get();
Sig.registerObject(SignalHandling::ModuleObjName,
"Server");
Sig.registerObject(ServerObjName, &S);
Sig.registerCallback(SIGHUP, &serverShutdown);
Sig.registerCallback(SIGINT, &serverShutdown);
Sig.registerCallback(SIGTERM, &serverShutdown);
Sig.registerCallback(SIGCHLD, &childExited);
Sig.ignore(SIGPIPE);
Sig.enable();

// Override the SIGABRT handler with a custom one that
// kills the server.
Sig.registerCallback(SIGILL, &coreDumped);
Sig.registerCallback(SIGABRT, &coreDumped);
Sig.registerCallback(SIGSEGV, &coreDumped);
Sig.registerCallback(SIGSYS, &coreDumped);
Sig.registerCallback(SIGSTKFLT, &coreDumped);
},
[] {
SignalHandling& Sig = SignalHandling::get();
Sig.unignore(SIGPIPE);
Sig.defaultCallback(SIGCHLD);
Sig.defaultCallback(SIGTERM);
Sig.defaultCallback(SIGINT);
Sig.defaultCallback(SIGHUP);
Sig.deleteObject(ServerObjName);

Sig.clearOneCallback(SIGILL);
Sig.clearOneCallback(SIGABRT);
Sig.clearOneCallback(SIGSEGV);
Sig.clearOneCallback(SIGSYS);
Sig.clearOneCallback(SIGSTKFLT);
}};

LOG(info) << "Starting Monomux Server";
if (Opts.Background)
Expand Down

0 comments on commit 8ff2c80

Please sign in to comment.