From 6c3ea4f47ea280811a7fe53a22f7832e4533c9ec Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 26 Jun 2024 18:18:36 +0200 Subject: Adding upstream version 1:4.15.2. Signed-off-by: Daniel Baumann --- lib/cleanup.c | 121 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 lib/cleanup.c (limited to 'lib/cleanup.c') diff --git a/lib/cleanup.c b/lib/cleanup.c new file mode 100644 index 0000000..c16f1bc --- /dev/null +++ b/lib/cleanup.c @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: 2008 - 2011, Nicolas François + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include + +#include +#include + +#include "prototypes.h" + +/* + * The cleanup_functions stack. + */ +#define CLEANUP_FUNCTIONS 10 + +typedef /*@null@*/void * parg_t; + +static cleanup_function cleanup_functions[CLEANUP_FUNCTIONS]; +static parg_t cleanup_function_args[CLEANUP_FUNCTIONS]; +static pid_t cleanup_pid = 0; + +/* + * - Cleanup functions shall not fail. + * - You should register do_cleanups with atexit. + * - You should add cleanup functions to the stack with add_cleanup when + * an operation is expected to be executed later, and remove it from the + * stack with del_cleanup when it has been executed. + * + **/ + +/* + * do_cleanups - perform the actions stored in the cleanup_functions stack. + * + * Cleanup action are not executed on exit of the processes started by the + * parent (first caller of add_cleanup). + * + * It is intended to be used as: + * atexit (do_cleanups); + */ +void do_cleanups (void) +{ + unsigned int i; + + /* Make sure there were no overflow */ + assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-1]); + + if (getpid () != cleanup_pid) { + return; + } + + i = CLEANUP_FUNCTIONS; + do { + i--; + if (cleanup_functions[i] != NULL) { + cleanup_functions[i] (cleanup_function_args[i]); + } + } while (i>0); +} + +/* + * add_cleanup - Add a cleanup_function to the cleanup_functions stack. + */ +void add_cleanup (/*@notnull@*/cleanup_function pcf, /*@null@*/void *arg) +{ + unsigned int i; + assert (NULL != pcf); + + assert (NULL == cleanup_functions[CLEANUP_FUNCTIONS-2]); + + if (0 == cleanup_pid) { + cleanup_pid = getpid (); + } + + /* Add the cleanup_function at the end of the stack */ + for (i=0; NULL != cleanup_functions[i]; i++); + cleanup_functions[i] = pcf; + cleanup_function_args[i] = arg; +} + +/* + * del_cleanup - Remove a cleanup_function from the cleanup_functions stack. + */ +void del_cleanup (/*@notnull@*/cleanup_function pcf) +{ + unsigned int i; + assert (NULL != pcf); + + /* Find the pcf cleanup function */ + for (i=0; i