diff --git a/Userspace/libc/include/stdlib.h b/Userspace/libc/include/stdlib.h index 478ee63f..ac6a43e8 100644 --- a/Userspace/libc/include/stdlib.h +++ b/Userspace/libc/include/stdlib.h @@ -86,11 +86,12 @@ extern "C" long int nrand48(unsigned short int[3]); char *ptsname(int); int putenv(char *); - void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)); int rand(void); int rand_r(unsigned int *); long random(void); - void *realloc(void *, size_t); + void *realloc(void *ptr, size_t size); + void *reallocarray(void *ptr, size_t nelem, size_t elsize); char *realpath(const char *, char *); unsigned short int seed48(unsigned short int[3]); void setkey(const char *); diff --git a/Userspace/libc/src/std/stdlib.c b/Userspace/libc/src/std/stdlib.c index c8f177e8..a9171559 100644 --- a/Userspace/libc/src/std/stdlib.c +++ b/Userspace/libc/src/std/stdlib.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "../mem/liballoc_1_1.h" #define MAX_ATEXIT_FUNCS 32 @@ -97,11 +98,63 @@ export long int mrand48(void); export long int nrand48(unsigned short int[3]); export char *ptsname(int); export int putenv(char *); -export void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + +export void qsort(void *base, size_t nel, size_t width, int (*compar)(const void *, const void *)) +{ + if (nel < 2 || width == 0) + return; + + char *pivot = (char *)base + (nel / 2) * width; + char *left = (char *)base; + char *right = (char *)base + (nel - 1) * width; + + while (left <= right) + { + while (compar(left, pivot) < 0) + left += width; + while (compar(right, pivot) > 0) + right -= width; + + if (left <= right) + { + for (size_t i = 0; i < width; i++) + { + char tmp = left[i]; + left[i] = right[i]; + right[i] = tmp; + } + left += width; + right -= width; + } + } + + size_t left_size = (right - (char *)base) / width + 1; + size_t right_size = nel - left_size - 1; + + qsort(base, left_size, width, compar); + qsort(left, right_size, width, compar); +} + export int rand(void); export int rand_r(unsigned int *); export long random(void); -export void *realloc(void *, size_t); + +export void *realloc(void *ptr, size_t size) +{ + return PREFIX(realloc)(ptr, size); +} + +export void *reallocarray(void *ptr, size_t nelem, size_t elsize) +{ + if (nelem && elsize > __SIZE_MAX__ / nelem) + { + errno = ENOMEM; + return NULL; + } + + return PREFIX(realloc)(ptr, nelem * elsize); +} + export char *realpath(const char *, char *); export unsigned short int seed48(unsigned short int[3]); export void setkey(const char *);