Add program destructor support

Update #4649.
This commit is contained in:
Sebastian Huber 2022-05-10 16:11:01 +02:00
parent 6364f4534e
commit 5c88a52bcc
3 changed files with 64 additions and 0 deletions

View File

@ -60,6 +60,12 @@ rtems_bsd_program_call_main_with_data_restore(const char *name,
int (*main)(int, char **), int argc, char **argv,
void *data_buf, const size_t data_size);
void *
rtems_bsd_program_add_destructor(void (*destructor)(void *), void *arg);
void
rtems_bsd_program_remove_destructor(void *cookie, bool call);
void
rtems_bsd_program_exit(int exit_code) __dead2;

View File

@ -60,6 +60,12 @@ struct program_allocmem_item {
LIST_ENTRY(program_allocmem_item) entries;
};
struct program_destructor {
void (*destructor)(void *);
void *arg;
LIST_ENTRY(program_destructor) link;
};
struct rtems_bsd_program_control {
void *context;
int exit_code;
@ -68,6 +74,7 @@ struct rtems_bsd_program_control {
LIST_HEAD(, program_fd_item) open_fd;
LIST_HEAD(, program_file_item) open_file;
LIST_HEAD(, program_allocmem_item) allocated_mem;
LIST_HEAD(, program_destructor) destructors;
};
struct rtems_bsd_program_control *rtems_bsd_program_get_control_or_null(void);

View File

@ -224,6 +224,18 @@ allocmem_free_all(struct rtems_bsd_program_control *prog_ctrl)
}
}
static void
call_destructors(struct rtems_bsd_program_control *prog_ctrl)
{
struct program_destructor *node;
struct program_destructor *tmp;
LIST_FOREACH_SAFE(node, &prog_ctrl->destructors, link, tmp) {
(*node->destructor)(node->arg);
free(node);
}
}
int
rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context)
{
@ -251,6 +263,7 @@ rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context)
LIST_INIT(&prog_ctrl->open_fd);
LIST_INIT(&prog_ctrl->open_file);
LIST_INIT(&prog_ctrl->allocated_mem);
LIST_INIT(&prog_ctrl->destructors);
if (setjmp(prog_ctrl->return_context) == 0) {
exit_code = (*prog)(context);
@ -262,10 +275,48 @@ rtems_bsd_program_call(const char *name, int (*prog)(void *), void *context)
fd_close_all(prog_ctrl);
file_close_all(prog_ctrl);
allocmem_free_all(prog_ctrl);
call_destructors(prog_ctrl);
free(prog_ctrl);
return (exit_code);
}
void *
rtems_bsd_program_add_destructor(void (*destructor)(void *), void *arg)
{
struct rtems_bsd_program_control *prog_ctrl;
struct program_destructor *node;
prog_ctrl = rtems_bsd_program_get_control_or_null();
if (prog_ctrl == NULL) {
return (NULL);
}
node = malloc(sizeof(*node));
if (node == NULL) {
return (NULL);
}
node->destructor = destructor;
node->arg = arg;
LIST_INSERT_HEAD(&prog_ctrl->destructors, node, link);
return (node);
}
void
rtems_bsd_program_remove_destructor(void *cookie, bool call)
{
struct program_destructor *node;
node = cookie;
LIST_REMOVE(node, link);
if (call) {
(*node->destructor)(node->arg);
}
free(node);
}
void
rtems_bsd_program_exit(int exit_code)
{