]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Add exit functions functionality
authorJoel Rosdahl <joel@rosdahl.net>
Wed, 14 Jul 2010 16:13:23 +0000 (18:13 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Wed, 14 Jul 2010 16:59:06 +0000 (18:59 +0200)
Makefile.in
ccache.c
ccache.h
exitfn.c [new file with mode: 0644]

index c9e3676f7e5b11856332bce5cd0bd5ea5721d0b1..42f902c9140443c6807ca6bf89056750c9af9589 100644 (file)
@@ -19,7 +19,7 @@ libs = @LIBS@ -lm
 sources = \
     ccache.c mdfour.c hash.c execute.c util.c args.c stats.c version.c \
     cleanup.c snprintf.c unify.c manifest.c hashtable.c hashtable_itr.c \
-    murmurhashneutral2.c hashutil.c getopt_long.c
+    murmurhashneutral2.c hashutil.c getopt_long.c exitfn.c
 all_sources = $(sources) @extra_sources@
 
 headers = \
index 1017ad237b9c6587687a957f763cfcadede32b98..a1332bfd2dca2c6e515733ae4338ddd6fb480ccd 100644 (file)
--- a/ccache.c
+++ b/ccache.c
@@ -284,6 +284,7 @@ static void failed(void)
 
        cc_log("Failed; falling back to running the real compiler");
        cc_log_executed_command(orig_args->argv);
+       exitfn_call();
        execv(orig_args->argv[0], orig_args->argv);
        fatal("%s: execv returned (%s)", orig_args->argv[0], strerror(errno));
 }
@@ -2138,6 +2139,8 @@ int main(int argc, char *argv[])
        char *p;
        char *program_name;
 
+       exitfn_init();
+
        /* check for logging early so cc_log messages start working ASAP */
        cache_logfile = getenv("CCACHE_LOGFILE");
        cc_log("=== CCACHE STARTED =========================================");
index 68be2ae1cd791aec7a34a86d4c73d27176f4b5ab..5c155f06aa9a68082eba774330c11fd80fa28f7b 100644 (file)
--- a/ccache.h
+++ b/ccache.h
@@ -122,6 +122,11 @@ void stats_set_sizes(const char *dir, size_t num_files, size_t total_size);
 
 int unify_hash(struct mdfour *hash, const char *fname);
 
+void exitfn_init(void);
+void exitfn_add_nullary(void (*function)(void));
+void exitfn_add(void (*function)(void *), void *context);
+void exitfn_call(void);
+
 #ifndef HAVE_VASPRINTF
 int vasprintf(char **, const char *, va_list) ATTR_FORMAT(printf, 2, 0);
 #endif
diff --git a/exitfn.c b/exitfn.c
new file mode 100644 (file)
index 0000000..0a81793
--- /dev/null
+++ b/exitfn.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 Joel Rosdahl
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "ccache.h"
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+struct exit_function {
+       void (*function)(void *);
+       void *context;
+       struct exit_function *next;
+};
+
+struct nullary_exit_function {
+       void (*function)(void);
+};
+
+static struct exit_function *exit_functions;
+
+static void
+call_nullary_exit_function(void *context)
+{
+       struct nullary_exit_function *p = (struct nullary_exit_function*)context;
+       p->function();
+       free(p);
+}
+
+/*
+ * Initialize exit functions. Must be called once before exitfn_add* are used.
+ */
+void
+exitfn_init(void)
+{
+       if (atexit(exitfn_call) != 0) {
+               fatal("atexit failed: %s", strerror(errno));
+       }
+}
+
+/*
+ * Add a nullary function to be called context when ccache exits. Functions are
+ * called in reverse order.
+ */
+void
+exitfn_add_nullary(void (*function)(void))
+{
+       struct nullary_exit_function *p = x_malloc(sizeof(*p));
+       p->function = function;
+       exitfn_add(call_nullary_exit_function, p);
+}
+
+/*
+ * Add a function to be called with a context parameter when ccache exits.
+ * Functions are called in reverse order.
+ */
+void
+exitfn_add(void (*function)(void *), void *context)
+{
+       struct exit_function *p;
+
+       p = x_malloc(sizeof(*p));
+       p->function = function;
+       p->context = context;
+       p->next = exit_functions;
+       exit_functions = p;
+}
+
+/*
+ * Call added functions.
+ */
+void
+exitfn_call(void)
+{
+       struct exit_function *p = exit_functions, *q;
+       while (p) {
+               p->function(p->context);
+               q = p;
+               p = p->next;
+               free(q);
+       }
+}