mirror of
https://github.com/reactos/ccache.git
synced 2024-12-12 13:45:48 +00:00
0bdaeb12a0
While execve() does not run the functions registered with atexit() and they must therefore be called explicitly prior to the call to execve(), the Windows replacement function will end up running the atexit() hooks twice, and clearing the pointer prevents the functions from actually running twice.
98 lines
2.2 KiB
C
98 lines
2.2 KiB
C
/*
|
|
* 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);
|
|
}
|
|
exit_functions = NULL;
|
|
}
|