From d232486a1189e94d732c425a8c868bc1e63d4439 Mon Sep 17 00:00:00 2001 From: bumbread Date: Mon, 27 Jun 2022 13:04:46 +1100 Subject: [PATCH] stdlib.h: quick exit --- inc/stdlib.h | 76 ++++++++++++---------- src/win/win_environment.c | 132 ++++++++++++++++++++++---------------- 2 files changed, 117 insertions(+), 91 deletions(-) diff --git a/inc/stdlib.h b/inc/stdlib.h index ecf2fba..3bf4470 100644 --- a/inc/stdlib.h +++ b/inc/stdlib.h @@ -30,8 +30,8 @@ typedef struct lldiv_t { long long rem; } lldiv_t; -// #define EXIT_FAILURE 1 -// #define EXIT_SUCCESS 0 +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 #define RAND_MAX 65536 #define MB_CUR_MAX 4 @@ -41,48 +41,54 @@ typedef struct lldiv_t { #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); -long long int atoll(const char *nptr); -double strtod(const char * restrict nptr, char ** restrict endptr); -float strtof(const char * restrict nptr, char ** restrict endptr); -long double strtold(const char * restrict nptr, char ** restrict endptr); -long int strtol(const char *restrict nptr, char **restrict endptr, int base); -long long int strtoll(const char *restrict nptr, char **restrict endptr, int base); -unsigned long int strtoul(const char *restrict nptr, char **restrict endptr, int base); -unsigned long long int strtoull(const char *restrict nptr, char **restrict endptr, int base); +// Some number stuff +int abs (int i); +long labs (long i); +long long llabs(long long i); +div_t div (int numer, int denom); +ldiv_t ldiv (long numer, long denom); +lldiv_t lldiv(long long numer, long long denom); + +// String conversion routines +double atof (const char *nptr); +int atoi (const char *nptr); +long atol (const char *nptr); +long long atoll (const char *nptr); +double strtod (const char *restrict nptr, char **restrict endptr); +float strtof (const char *restrict nptr, char **restrict endptr); +long double strtold (const char *restrict nptr, char **restrict endptr); +long strtol (const char *restrict nptr, char **restrict endptr, int base); +long long strtoll (const char *restrict nptr, char **restrict endptr, int base); +unsigned long strtoul (const char *restrict nptr, char **restrict endptr, int base); +unsigned long long strtoull(const char *restrict nptr, char **restrict endptr, int base); char *itoa(int value, char *str, int base); -int rand(void); +// PRNG +int rand (void); void srand(unsigned int seed); -typedef struct _os_heap _os_heap; -void _heap_setup(_os_heap *heap); -void *aligned_alloc(size_t alignment, size_t size); -void *calloc(size_t nmemb, size_t size); -void free(void *ptr); -void *malloc(size_t size); -void *realloc(void *ptr, size_t size); +// Memory management functions +void *malloc (size_t size); +void *calloc (size_t nmemb, size_t size); +void *aligned_alloc(size_t align, size_t size); +void *realloc (void *ptr, size_t size); +void free (void *ptr); +// Communication with environment +_Noreturn void abort (void); +_Noreturn void quick_exit (int status); +_Noreturn void _Exit (int status); +_Noreturn void exit (int status); +int atexit (void (*func)(void)); +int at_quick_exit(void (*func)(void)); +char *getenv (const char *name); +int system (const char *string); -_Noreturn void abort(void); -int atexit(void (*func)(void)); -// int at_quick_exit(void (*func)(void)); -_Noreturn void exit(int status); -_Noreturn void _Exit(int status); -char *getenv(const char *name); -// _Noreturn void quick_exit(int status); -int system(const char *string); const void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); // void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); -// int abs(int j); -// long int labs(long int j); -// long long int llabs(long long int j); -// div_t div(int numer, int denom); -// ldiv_t ldiv(long int numer, long int denom); -// lldiv_t lldiv(long long int numer, long long int denom); + +// Multibyte strings // int mblen(const char *s, size_t n); // int mbtowc(wchar_t * restrict pwc, const char * restrict s, size_t n); // int wctomb(char *s, wchar_t wchar); diff --git a/src/win/win_environment.c b/src/win/win_environment.c index b053ee9..f1e8d95 100644 --- a/src/win/win_environment.c +++ b/src/win/win_environment.c @@ -13,62 +13,14 @@ int _fltused=0; extern int main(int argc, char** argv); // Exit routines -#define ATEXIT_FUNC_COUNT 64 -static void (*atexit_funcs[ATEXIT_FUNC_COUNT])(void); +#define ATEXIT_FUNC_COUNT 64 +#define ATQEXIT_FUNC_COUNT 64 +static void (*atexit_funcs [ATEXIT_FUNC_COUNT])(void); +static void (*atqexit_funcs[ATQEXIT_FUNC_COUNT])(void); static int atexit_func_count; +static int atqexit_func_count; - -int _wcsicmp(wchar_t const* s1, wchar_t const* s2) { - int diff; - do { - diff = *s1 - *s2; - } while(diff != 0 && *s1 != 0 && *s2 != 0); - return diff; -} - -static size_t count_wide_chars(const wchar_t* str) { - size_t len = 0; - while (str[len] != 0) len++; - return len; -} - -static bool wchar_to_ansi(char* out, const wchar_t* str, size_t len) { - for (size_t i = 0; i < len; i++) { - wchar_t ch = *str++; - if (ch < 0 || ch > 0x7F) { - *out++ = 0; - return false; - } - *out++ = ch; - } - - *out++ = 0; - return true; -} - -static char **get_command_args(int *argc_ptr) { - int argc; - char** args; - - LPCWSTR command_line = GetCommandLineW(); - LPWSTR* args_wide = CommandLineToArgvW(command_line, &argc); - if (!args_wide || argc <= 0) { - ExitProcess(-69420); - } - - args = calloc(argc, sizeof(char*)); - - // Convert wide chars into ANSI - for (int i = 0; i < argc; i++) { - size_t arg_len = count_wide_chars(args_wide[i]); - args[i] = malloc(arg_len+1); - wchar_to_ansi(args[i], args_wide[i], arg_len+1); - } - - *argc_ptr = argc; - return args; -} - +static char **get_command_args(int *argc_ptr); void mainCRTStartup() { // Set-up some platform stuff @@ -91,9 +43,17 @@ void mainCRTStartup() { exit(exit_code); } + +_Noreturn void quick_exit(int status) { + while(atqexit_func_count--) { + atqexit_funcs[atqexit_func_count](); + } + ExitProcess(status); +} + _Noreturn void exit(int status) { - for (int i = atexit_func_count; i--;) { - atexit_funcs[i](); + while(atexit_func_count--) { + atexit_funcs[atqexit_func_count](); } _close_io(); ExitProcess(status); @@ -116,6 +76,14 @@ int atexit(void (*func)(void)) { return 1; } +int at_quick_exit(void (*func)(void)) { + if(atqexit_func_count >= ATQEXIT_FUNC_COUNT) { + return 0; + } + atqexit_funcs[atqexit_func_count++] = func; + return 1; +} + char *getenv(const char *name) { // The string pointed to shall not be modified by the program, but may be // overwritten by a subsequent call to the getenv function @@ -184,3 +152,55 @@ int system(const char* string) { free(cmd_line); return -1; } + +int _wcsicmp(wchar_t const* s1, wchar_t const* s2) { + int diff; + do { + diff = *s1 - *s2; + } while(diff != 0 && *s1 != 0 && *s2 != 0); + return diff; +} + +static size_t count_wide_chars(const wchar_t* str) { + size_t len = 0; + while (str[len] != 0) len++; + return len; +} + +static bool wchar_to_ansi(char* out, const wchar_t* str, size_t len) { + for (size_t i = 0; i < len; i++) { + wchar_t ch = *str++; + if (ch < 0 || ch > 0x7F) { + *out++ = 0; + return false; + } + *out++ = ch; + } + + *out++ = 0; + return true; +} + +static char **get_command_args(int *argc_ptr) { + int argc; + char** args; + + LPCWSTR command_line = GetCommandLineW(); + LPWSTR* args_wide = CommandLineToArgvW(command_line, &argc); + if (!args_wide || argc <= 0) { + ExitProcess(-69420); + } + + args = calloc(argc, sizeof(char*)); + + // Convert wide chars into ANSI + for (int i = 0; i < argc; i++) { + size_t arg_len = count_wide_chars(args_wide[i]); + args[i] = malloc(arg_len+1); + wchar_to_ansi(args[i], args_wide[i], arg_len+1); + } + + *argc_ptr = argc; + return args; +} +