Skip to content

Instantly share code, notes, and snippets.

@tonyg
Created January 1, 2010 18:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tonyg/267180 to your computer and use it in GitHub Desktop.
Save tonyg/267180 to your computer and use it in GitHub Desktop.
Q: Why does the whole program crash when the remote client closes its socket before the server is done? A: Because SIGPIPE is not blocked. Use UnixSignals.setHandler.
Group is
$cml/basis.cm
$cml/cml.cm
$cml-lib/smlnj-lib.cm
maybebug.sml
(* ml-build maybebug.cm && sml @SMLload=maybebug *)
(* then in another terminal, nc localhost 8989 and interrupt it before it gets to zero *)
structure Test = struct
open TextIO
structure SU = SockUtil
exception Foo of string
fun connMain s =
let fun ds str = (print "in\n";
SU.sendStr (s, str);
print "out\n")
fun count 0 = ds ("Bye!\r\n")
| count n = (ds ("Hello " ^ (Int.toString n) ^ "\r\n");
CML.sync (CML.timeOutEvt (Time.fromReal 0.5));
count (n - 1))
in
count 5;
raise Foo "Eek";
print "Closing the connection.\n";
Socket.close s
end
fun catchWrap f arg =
fn () =>
f arg
handle v => print ("Oh no: " ^ (General.exnMessage v) ^ "\n")
fun acceptLoop server_sock =
let val (s, _) = Socket.accept server_sock
in
print "Accepted a connection.\n";
CML.spawn (catchWrap connMain s);
acceptLoop server_sock
end
fun cml_main (program_name, arglist) =
let val s = INetSock.TCP.socket()
in
Socket.Ctl.setREUSEADDR (s, true);
Socket.bind(s, INetSock.any 8989);
Socket.listen(s, 5);
print "Entering accept loop...\n";
acceptLoop s
end
fun main (program_name, arglist) =
(RunCML.doit (fn () => cml_main(program_name, arglist), NONE);
OS.Process.success)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment