From: Alan Cox Date: Wed, 21 Jan 2015 20:24:27 +0000 (+0000) Subject: atexit: clean up all the atexit code and fix the improper casts X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=875b6aeaa1d26ca8f3bf28ecec3e1fed43c0b756;p=FUZIX.git atexit: clean up all the atexit code and fix the improper casts Turns out atexit isn't a cc65 bug rather an interesting property of the compiler. cc65 requires the called function to unstack the arguments so that it can fold together the argument popping and local recovery. This means that calling a function declared as foo(void) cast as foo(int) doesn't work and trashes your local variables. A new to me and excitingly novel way of shooting yourself in the boot, but perfectly valid compiler behaviour. --- diff --git a/Library/include/stdlib.h b/Library/include/stdlib.h index 75ab85f1..1475175b 100644 --- a/Library/include/stdlib.h +++ b/Library/include/stdlib.h @@ -62,11 +62,8 @@ extern int putenv __P((char *)); extern int setenv __P((char *, char *, int)); extern void unsetenv __P((char *)); -typedef void (*atexit_t) __P((int)); -typedef void (*onexit_t) __P((int, void *)); +typedef void (*atexit_t) __P((void)); extern int atexit __P((atexit_t)); -extern int on_exit __P((onexit_t, void *arg)); -extern onexit_t __cleanup; extern char *crypt __P((char *__key, char *__salt)); diff --git a/Library/libs/atexit.c b/Library/libs/atexit.c index 12914d11..8bd374e8 100644 --- a/Library/libs/atexit.c +++ b/Library/libs/atexit.c @@ -12,54 +12,43 @@ #include #include -/* ATEXIT.H */ -#define MAXONEXIT 10 /* AIUI Posix requires 10 */ +#define MAXATEXIT 10 /* AIUI Posix requires 10 */ -typedef void (*vfuncp) (int, void *); +typedef void (*vfuncp) (void); -extern struct exit_table { - onexit_t called; - void *argument; -} __on_exit_table[MAXONEXIT]; +struct exit_table { + atexit_t called; +} __atexit_table[MAXATEXIT]; -extern int __on_exit_count; +extern int __atexit_count; -/* End ATEXIT.H */ -int __on_exit_count = 0; -struct exit_table __on_exit_table[MAXONEXIT]; +int __atexit_count = 0; void __do_exit(int rv) { - /* Static to work around a bug in cc65 */ - static int count; + int count; vfuncp ptr; - count = __on_exit_count - 1; - __on_exit_count = -1; /* ensure no more will be added */ + count = __atexit_count - 1; + __atexit_count = -1; /* ensure no more will be added */ /* In reverse order */ while (count >= 0) { - ptr = (vfuncp) __on_exit_table[count].called; - (*ptr) (rv, __on_exit_table[count].argument); + ptr = (vfuncp) __atexit_table[count].called; + (*ptr) (); --count; } } -int on_exit(onexit_t ptr, void *arg) +int atexit(atexit_t ptr) { - if (__on_exit_count < 0 || __on_exit_count >= MAXONEXIT) { + if (__atexit_count < 0 || __atexit_count >= MAXATEXIT) { errno = ENOMEM; return -1; } if (ptr) { - __on_exit_table[__on_exit_count].called = ptr; - __on_exit_table[__on_exit_count].argument = arg; - __on_exit_count++; + __atexit_table[__atexit_count].called = ptr; + __atexit_count++; } return 0; } - -int atexit(atexit_t ptr) -{ - return on_exit((onexit_t) ptr, 0); -} diff --git a/Library/libs/stdio0.c b/Library/libs/stdio0.c index cf4222c5..5e025f05 100644 --- a/Library/libs/stdio0.c +++ b/Library/libs/stdio0.c @@ -26,7 +26,7 @@ FILE stderr[1] = { /* Call the stdio initialiser; it's main job it to call atexit */ -STATIC void __stdio_close_all(VOID) +STATIC void __stdio_close_all(void) { FILE *fp = __IO_list;