From 911841be30d002804e59d3ebe49b79220873a5d4 Mon Sep 17 00:00:00 2001 From: NeGate Date: Tue, 7 Jun 2022 22:17:57 -0400 Subject: [PATCH] Added atexit --- code/os/win/win_entry.c | 4 +++- code/os/win/win_io.c | 2 -- code/stdlib/env.c | 22 +++++++++++++++++++++- inc/stdlib.h | 15 ++++++++++----- test/test.c | 10 ++++++++-- test/test2.c | 25 +++++++++++++++++++++++++ test/test3.c | 9 +++++++++ 7 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 test/test2.c create mode 100644 test/test3.c diff --git a/code/os/win/win_entry.c b/code/os/win/win_entry.c index 314fe29..5fa2b44 100644 --- a/code/os/win/win_entry.c +++ b/code/os/win/win_entry.c @@ -74,9 +74,11 @@ void mainCRTStartup() { srand(0); setlocale(LC_ALL, "C"); _os_init_eh(); + int exit_code = main(arg_count, args); - ExitProcess(exit_code); + // we call exit because we want atexit routines run + exit(exit_code); } // This symbol is required to be present if we're using floating-point diff --git a/code/os/win/win_io.c b/code/os/win/win_io.c index 4059204..f7bb2af 100644 --- a/code/os/win/win_io.c +++ b/code/os/win/win_io.c @@ -10,5 +10,3 @@ void _os_file_write(void* ctx, size_t n, const char str[]) { DWORD written = 0; WriteFile((HANDLE) ctx, str, n, &written, NULL); } - - diff --git a/code/stdlib/env.c b/code/stdlib/env.c index 9e8b349..fb35a06 100644 --- a/code/stdlib/env.c +++ b/code/stdlib/env.c @@ -4,18 +4,38 @@ #include <_os.h> +typedef void (*ExitRoutine)(void); + +// The implementation shall support the registration +// of at least 32 functions. +static ExitRoutine _exit_routines[64]; +static int _exit_routine_count; + _Noreturn void abort(void) { raise(SIGABRT); _os_exit(-69); } -// TODO: at_exit handling +int atexit(void (*func)(void)) { + if (_exit_routine_count >= COUNTOF(_exit_routines)) { + return 0; + } + + _exit_routines[_exit_routine_count++] = func; + return 1; +} _Noreturn void exit(int status) { + // doing them in reverse seems nicer + for (int i = _exit_routine_count; i--;) { + _exit_routines[i](); + } + _os_exit(status); } _Noreturn void _Exit(int status) { + // doesn't run atexit routines _os_exit(status); } diff --git a/inc/stdlib.h b/inc/stdlib.h index 048665d..12f9761 100644 --- a/inc/stdlib.h +++ b/inc/stdlib.h @@ -3,13 +3,13 @@ #include #if !defined(__STDC_LIB_EXT1__) - #define __STDC_LIB_EXT1__ +#define __STDC_LIB_EXT1__ #endif #ifdef __STDC_WANT_SECURE_LIB__ - #if !defined(__STDC_WANT_LIB_EXT1__) - #define __STDC_WANT_LIB_EXT1__ 1 - #endif +#if !defined(__STDC_WANT_LIB_EXT1__) +#define __STDC_WANT_LIB_EXT1__ 1 +#endif #endif #define EXIT_SUCCESS 0 @@ -36,6 +36,11 @@ #define RAND_MAX 65536 // #define MB_CUR_MAX 5 +// Microsoft extension, COUNTOF(x) counts array elements +#ifndef COUNTOF +#define COUNTOF(...) (sizeof(__VA_ARGS__) / sizeof((__VA_ARGS__)[0])) +#endif + double atof(const char *nptr); int atoi(const char *nptr); long int atol(const char *nptr); @@ -59,7 +64,7 @@ void *malloc(size_t size); void *realloc(void *ptr, size_t size); _Noreturn void abort(void); -// int atexit(void (*func)(void)); +int atexit(void (*func)(void)); // int at_quick_exit(void (*func)(void)); _Noreturn void exit(int status); _Noreturn void _Exit(int status); diff --git a/test/test.c b/test/test.c index d26020f..bdf2e73 100644 --- a/test/test.c +++ b/test/test.c @@ -16,7 +16,13 @@ int test() { return a; } +void wack() { + printf("BYE!!!\n"); +} + int main(int argc, char** argv) { + atexit(wack); + test(); char input[] = "A bird came down the walk"; printf("Parsing the input string '%s'\n", input); @@ -25,10 +31,10 @@ int main(int argc, char** argv) { printf("%s\n", token); token = strtok(NULL, " "); } - + printf("Contents of the input string now: '"); for(size_t n = 0; n < sizeof input; ++n) input[n] ? printf("%c", input[n]) : printf("\\0"); printf("'"); return 0; -} \ No newline at end of file +} diff --git a/test/test2.c b/test/test2.c new file mode 100644 index 0000000..2ba72d0 --- /dev/null +++ b/test/test2.c @@ -0,0 +1,25 @@ +#include +#include +#include + +int main(void) { + double v0 = strtod("0X1.BC70A3D70A3D7P+6", NULL); + + // parsing with error handling + const char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz"; + + char *end; + for (double f = strtod(p, &end); p != end; f = strtod(p, &end)) { + // printf("'%.*s' -> ", (int)(end-p), p); + p = end; + if (errno == ERANGE){ + // printf("range error, got "); + errno = 0; + } + // printf("%f\n", f); + } + + // parsing without error handling + double v1 = strtod(" -0.0000000123junk", NULL); + double v2 = strtod("junk", NULL); +} diff --git a/test/test3.c b/test/test3.c new file mode 100644 index 0000000..9c240ce --- /dev/null +++ b/test/test3.c @@ -0,0 +1,9 @@ +#include +#include +#include + +int main(int argc, char** argv) { + for (int i = 0; i < argv; i++) { + printf("[%d] = %s\n", i, argv[i]); + } +}