Commit Diff


commit - ae2955a0d5099c7bfb7ae69346c89874aafc0f88
commit + d2f8aa1ddcef54f8da65783f935f4b0b363affc5
blob - fb3c5d6e363800166e51cb07d2ba2f44c39ee861
blob + 1f0ee772f825b965a62afaa96979fa29e9704a3a
--- shinsha.ha
+++ shinsha.ha
@@ -1,3 +1,4 @@
+use errors;
 use fmt;
 use getopt;
 use io;
@@ -6,6 +7,7 @@ use net::ip;
 use net::tcp;
 use net;
 use os;
+use unix::signal;
 
 use ev;
 
@@ -33,6 +35,19 @@ fn accept(fp: io::file, event: ev::event, data: nullab
 	ev::add(sock, ev::READ, &handleio, null);
 };
 
+fn sighandler(sig: signal::sig, data: nullable *opaque) void = {
+	// Normal signal handler rules don't apply because ev
+	// decouples for us.
+
+	if (sig == signal::sig::TERM || sig == signal::sig::INT) {
+		log::printfln("got {}; quitting...", signal::signame(sig));
+		ev::loopbreak();
+		return;
+	};
+
+	log::fatalf("unexpected {}", signal::signame(sig));
+};
+
 export fn main() void = {
 	const cmd = getopt::parse(os::args,
 		"web manga reader",
@@ -70,8 +85,15 @@ export fn main() void = {
 
 	ev::add(sock, ev::READ, &accept, null);
 
+	ev::signal(signal::sig::INT, &sighandler, null)!;
+	ev::signal(signal::sig::TERM, &sighandler, null)!;
+
 	log::printfln("listening on port {}", port);
-	ev::mainloop()!;
+	match (ev::mainloop()) {
+	case void => yield;
+	case let err: errors::error =>
+		log::fatalf("mainloop failure: {}", errors::strerror(err));
+	};
 
 	log::printfln("exiting...");
 };