+
+#----------------------------------------------------------------------
+
+# Toplevel wrote something.
+
+sub got_stdout
+{
+ my ($kernel,$heap, $input, $wheel_id) = @_[KERNEL,HEAP,ARG0,ARG1];
+ print "Child said: $input\n";
+ $kernel->post ($heap->{irc} => privmsg => $channel => "$input");
+}
+
+# Got a SIGCHLD, so start the bot up again.
+
+sub got_sigchld
+{
+ my ($kernel, $heap) = @_[KERNEL,HEAP];
+ my $ocaml = start_toplevel ();
+ $heap->{ocaml} = $ocaml;
+}
+
+# Start up the toplevel (assumes it's not running).
+
+sub start_toplevel
+{
+ return POE::Wheel::Run->new
+ (
+ Program => "./ocamlbotwrapper",
+ StdoutEvent => "got_stdout",
+ StderrEvent => "got_stdout",
+ ) or die "POE::Wheel::Run->new ./ocamlbotwrapper failed: $!";
+}
+
+# Restart the toplevel - kill the old one, and a new one
+# will be spawned after we get the SIGCHLD signal.
+#
+# XXX Can't send signal to setuid child, so instead just close
+# stdin.
+
+sub restart_toplevel
+{
+ my $ocaml = shift;
+
+ $ocaml->kill (9);
+ $ocaml->shutdown_stdin;
+}