]> git.ozlabs.org Git - ccan-lca-2011.git/blobdiff - ccan/oserver/oserver.c
lca2011: oserver_restore.
[ccan-lca-2011.git] / ccan / oserver / oserver.c
index 8a5fdceecf1a0c2c4f7ddf1ac278ad8c61f7e793..b65fe6b1f3069fd90dae4cda0895210bda37a649 100644 (file)
@@ -5,6 +5,7 @@
 #include <ccan/opt/opt.h>
 #include <ccan/tevent/tevent.h>
 #include <ccan/array_size/array_size.h>
+#include <ccan/grab_file/grab_file.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
@@ -306,6 +307,53 @@ static void dump(struct tevent_context *ev,
        talloc_free(str);
 }
 
+static bool load_file(struct oserver *oserver, const char *file)
+{
+       char *str;
+
+       if (!file)
+               return false;
+
+       str = grab_file(oserver, file, NULL);
+       if (!str)
+               return false;
+
+       if (!cdump_unbundle(oserver, cdump_struct_oserver, oserver, str)) {
+               talloc_free(str);
+               return false;
+       }
+       talloc_free(str);
+       return true;
+}
+
+static void complete_server(struct tevent_context *ev,
+                           struct oserver *oserver, const char *dumpfile)
+{
+       /* Re-set this even if restored from file, in case it changed. */
+       oserver->dumpfile = dumpfile;
+       if (oserver->dumpfile)
+               tevent_add_signal(ev, oserver, SIGHUP, SA_RESTART,
+                                 dump, oserver);
+
+       /* Don't kill us if client dies. */
+       signal(SIGPIPE, SIG_IGN);
+
+       /* Show talloc tree on SIGUSR1. */
+       tevent_add_signal(ev, oserver, SIGUSR1, SA_RESTART,
+                         talloc_dump, oserver);
+}
+
+struct oserver *oserver_restore(struct tevent_context *ev, const char *dumpfile)
+{
+       struct oserver *oserver = talloc(ev, struct oserver);
+       if (!load_file(oserver, dumpfile)) {
+               talloc_free(oserver);
+               return NULL;
+       }
+       complete_server(ev, oserver, dumpfile);
+       return oserver;
+}
+
 struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
                              const char *dumpfile)
 {
@@ -350,18 +398,6 @@ struct oserver *oserver_setup(struct tevent_context *ev, unsigned short port,
                return NULL;
        }
 
-       oserver->dumpfile = dumpfile;
-       if (oserver->dumpfile) {
-               tevent_add_signal(ev, oserver, SIGHUP, SA_RESTART,
-                                 dump, oserver);
-       }
-
-       /* Don't kill us if client dies. */
-       signal(SIGPIPE, SIG_IGN);
-
-       /* Show talloc tree on SIGUSR1. */
-       tevent_add_signal(ev, oserver, SIGUSR1, SA_RESTART,
-                         talloc_dump, oserver);
-
+       complete_server(ev, oserver, dumpfile);
        return oserver;
 }