X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc.so_src%2Fstdlib.c;h=e05ddc2d4ed07316e1958507402cd992f91df514;hb=db55040ba8814edf681d4ccc12ad8955d8aa404a;hp=469f51c98638d85f0ea59af6870caaa1093d64ff;hpb=f194730e75d6d3681e5f99a4efed1616fd1ea738;p=tpg%2Facess2.git diff --git a/Usermode/Libraries/libc.so_src/stdlib.c b/Usermode/Libraries/libc.so_src/stdlib.c index 469f51c9..e05ddc2d 100644 --- a/Usermode/Libraries/libc.so_src/stdlib.c +++ b/Usermode/Libraries/libc.so_src/stdlib.c @@ -5,29 +5,36 @@ #include #include #include -#include -#include -#include #include "lib.h" -#define _stdout 1 -#define _stdin 0 +extern void _stdio_cleanup(void); -extern void *_crt0_exit_handler; +#define MAX_ATEXIT_HANDLERS 64 // Standard defines >=32 // === PROTOTYPES === EXPORT int atoi(const char *str); EXPORT void exit(int status); // === GLOBALS === -void (*g_stdlib_exithandler)(void); +typedef void (*stdlib_exithandler_t)(void); +stdlib_exithandler_t g_stdlib_exithandlers[MAX_ATEXIT_HANDLERS]; + int g_stdlib_num_exithandlers; // === CODE === -void atexit(void (*__func)(void)) +void _call_atexit_handlers(void) { - g_stdlib_exithandler = __func; - // TODO: Replace with meta-function to allow multiple atexit() handlers - _crt0_exit_handler = __func; + int i; + for( i = g_stdlib_num_exithandlers; i --; ) + g_stdlib_exithandlers[i](); + _stdio_cleanup(); +} + +EXPORT void atexit(void (*__func)(void)) +{ + if( g_stdlib_num_exithandlers < MAX_ATEXIT_HANDLERS ) + { + g_stdlib_exithandlers[g_stdlib_num_exithandlers++] = __func; + } } /** @@ -36,8 +43,7 @@ void atexit(void (*__func)(void)) */ EXPORT void exit(int status) { - if( g_stdlib_exithandler ) - g_stdlib_exithandler(); + _call_atexit_handlers(); _exit(status); } @@ -71,95 +77,6 @@ EXPORT void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void } } -EXPORT long long strtoll(const char *str, char **end, int base) -{ - int neg = 0; - long long ret = 0; - - if( !str || base < 0 || base > 36 || base == 1 ) { - if(end) - *end = (char*)str; - errno = EINVAL; - return 0; - } - - while( isspace(*str) ) - str++; - - // Check for negative (or positive) sign - if(*str == '-' || *str == '+') { - neg = (*str == '-'); - str++; - } - - if( base == 0 || base == 16 ) { - if( *str == '0' && str[1] == 'x' ) { - str += 2; - base = 16; - } - } - - if( base == 0 && *str == '0' ) { - str ++; - base = 8; - } - - if( base == 0 ) - base = 10; - - while( *str ) - { - int next = -1; - if( base <= 10 ) { - if( '0' <= *str && *str <= '0'+base-1 ) - next = *str - '0'; - } - else { - if( '0' <= *str && *str <= '9' ) - next = *str - '0'; - if( 'A' <= *str && *str <= 'A'+base-10-1 ) - next = *str - 'A'; - if( 'a' <= *str && *str <= 'a'+base-10-1 ) - next = *str - 'a'; - } - if( next < 0 ) - break; - ret *= base; - ret += next; - str ++; - } - - if( neg ) - ret = -ret; - - if(end) - *end = (char*)str; - return ret; -} - -EXPORT long strtol(const char *str, char **end, int base) -{ - long long tmp = strtoll(str, end, base); - if( tmp > LONG_MAX || tmp < LONG_MIN ) { - errno = ERANGE; - return (tmp > LONG_MAX) ? LONG_MAX : LONG_MIN; - } - return tmp; -} - -/** - * \fn EXPORT int atoi(const char *str) - * \brief Convert a string to an integer - */ -EXPORT int atoi(const char *str) -{ - long long tmp = strtoll(str, NULL, 0); - if( tmp > INT_MAX || tmp < INT_MIN ) { - errno = ERANGE; - return (tmp > INT_MAX) ? INT_MAX : INT_MIN; - } - return tmp; -} int abs(int j) { return j < 0 ? -j : j; } long int labs(long int j) { return j < 0 ? -j : j; }