diff options
Diffstat (limited to 'libc/stdlib')
39 files changed, 553 insertions, 499 deletions
diff --git a/libc/stdlib/_atexit.c b/libc/stdlib/_atexit.c index 75fe41fa2..e5840f471 100644 --- a/libc/stdlib/_atexit.c +++ b/libc/stdlib/_atexit.c @@ -20,7 +20,7 @@ * _stdio_term. * * Jul 2001 Steve Thayer - * + * * Added an on_exit implementation (that now matches gnu libc definition.) * Pulled atexit_handler out of the atexit object since it is now required by * on_exit as well. Renamed it to __exit_handler. @@ -43,17 +43,12 @@ #include <errno.h> #include <atomic.h> +#include <bits/uClibc_mutex.h> +__UCLIBC_MUTEX_EXTERN(__atexit_lock); + libc_hidden_proto(exit) libc_hidden_proto(_exit) -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -# include <pthreadP.h> -extern pthread_mutex_t mylock; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) - typedef void (*aefuncp) (void); /* atexit function pointer */ typedef void (*oefuncp) (int, void *); /* on_exit function pointer */ @@ -112,12 +107,13 @@ extern void *__dso_handle __attribute__ ((__weak__)); #ifdef L_atexit int attribute_hidden atexit(aefuncp func) #else +int old_atexit(aefuncp func); int old_atexit(aefuncp func) #endif { /* * glibc casts aefuncp to cxaefuncp. - * This seems dodgy, but I guess callling a function with more + * This seems dodgy, but I guess calling a function with more * parameters than it needs will work everywhere? */ return __cxa_atexit((cxaefuncp)func, NULL, @@ -138,7 +134,7 @@ weak_alias(old_atexit,atexit) int on_exit(oefuncp func, void *arg) { struct exit_function *efp; - + if (func == NULL) { return 0; } @@ -162,7 +158,7 @@ libc_hidden_proto(__cxa_atexit) int __cxa_atexit (cxaefuncp func, void *arg, void *dso_handle) { struct exit_function *efp; - + if (func == NULL) { return 0; } @@ -244,26 +240,25 @@ struct exit_function attribute_hidden *__new_exitfn(void) { struct exit_function *efp; - LOCK; + __UCLIBC_MUTEX_LOCK(__atexit_lock); #ifdef __UCLIBC_DYNAMIC_ATEXIT__ /* If we are out of function table slots, make some more */ if (__exit_slots < __exit_count+1) { - efp=realloc(__exit_function_table, + efp=realloc(__exit_function_table, (__exit_slots+20)*sizeof(struct exit_function)); if (efp == NULL) { - UNLOCK; __set_errno(ENOMEM); - return 0; + goto DONE; } __exit_function_table = efp; __exit_slots += 20; } #else if (__exit_count >= __UCLIBC_MAX_ATEXIT) { - UNLOCK; __set_errno(ENOMEM); - return 0; + efp = NULL; + goto DONE; } #endif @@ -271,8 +266,8 @@ struct exit_function attribute_hidden *__new_exitfn(void) efp = &__exit_function_table[__exit_count++]; efp->type = ef_in_use; - UNLOCK; - +DONE: + __UCLIBC_MUTEX_UNLOCK(__atexit_lock); return efp; } @@ -303,9 +298,8 @@ void __exit_handler(int status) } } #ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* Free up memory used by the __exit_function_table structure */ - if (__exit_function_table) - free(__exit_function_table); + /* Free up memory used by the __exit_function_table structure */ + free(__exit_function_table); #endif } #endif @@ -313,9 +307,7 @@ void __exit_handler(int status) #ifdef L_exit extern void weak_function _stdio_term(void) attribute_hidden; attribute_hidden void (*__exit_cleanup) (int) = 0; -#ifdef __UCLIBC_HAS_THREADS__ -pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif +__UCLIBC_MUTEX_INIT(__atexit_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); extern void __uClibc_fini(void); libc_hidden_proto(__uClibc_fini) @@ -326,11 +318,11 @@ libc_hidden_proto(__uClibc_fini) void exit(int rv) { /* Perform exit-specific cleanup (atexit and on_exit) */ - LOCK; + __UCLIBC_MUTEX_LOCK(__atexit_lock); if (__exit_cleanup) { __exit_cleanup(rv); } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(__atexit_lock); __uClibc_fini(); @@ -338,7 +330,7 @@ void exit(int rv) * this will attempt to commit all buffered writes. It may also * unbuffer all writable files, or close them outright. * Check the stdio routines for details. */ - if (_stdio_term) + if (_stdio_term) _stdio_term(); _exit(rv); diff --git a/libc/stdlib/_strtod.c b/libc/stdlib/_strtod.c index 219d0d051..1b2adc986 100644 --- a/libc/stdlib/_strtod.c +++ b/libc/stdlib/_strtod.c @@ -177,7 +177,7 @@ extern void __fp_range_check(__fpmax_t y, __fpmax_t x) attribute_hidden; #ifdef __UCLIBC_HAS_XLOCALE__ libc_hidden_proto(__ctype_b_loc) -#elif __UCLIBC_HAS_CTYPE_TABLES__ +#elif defined __UCLIBC_HAS_CTYPE_TABLES__ libc_hidden_proto(__ctype_b) libc_hidden_proto(__ctype_tolower) #endif @@ -215,7 +215,7 @@ __fpmax_t attribute_hidden __strtofpmax(const Wchar *str, Wchar **endptr, int ex #else /* defined(__UCLIBC_HAS_XLOCALE__) && !defined(__UCLIBC_DO_XLOCALE) */ -libc_hidden_proto(memcmp) +/* Experimentally off - libc_hidden_proto(memcmp) */ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endptr, int exponent_power __LOCALE_PARAM ) @@ -234,7 +234,7 @@ __fpmax_t attribute_hidden __XL_NPP(__strtofpmax)(const Wchar *str, Wchar **endp #endif #ifdef __UCLIBC_HAS_LOCALE__ #if defined(L___wcstofpmax) || defined(L___wcstofpmax_l) - wchar_t decpt_wc = __LOCALE_PTR->decimal_point; + wchar_t decpt_wc = __LOCALE_PTR->decimal_point_wc; #else const char *decpt = __LOCALE_PTR->decimal_point; int decpt_len = __LOCALE_PTR->decimal_point_len; diff --git a/libc/stdlib/a64l.c b/libc/stdlib/a64l.c index 23faf2744..d09dbf464 100644 --- a/libc/stdlib/a64l.c +++ b/libc/stdlib/a64l.c @@ -36,9 +36,7 @@ static const char a64l_table[TABLE_SIZE] = }; -long int -a64l (string) - const char *string; +long int a64l (const char *string) { const char *ptr = string; unsigned long int result = 0ul; diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c index a940768c0..e2c9962f2 100644 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -29,7 +29,7 @@ Cambridge, MA 02139, USA. */ libc_hidden_proto(abort) -libc_hidden_proto(memset) +/* Experimentally off - libc_hidden_proto(memset) */ libc_hidden_proto(sigaction) libc_hidden_proto(sigprocmask) libc_hidden_proto(raise) @@ -46,15 +46,11 @@ libc_hidden_proto(_exit) #ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__ extern void weak_function _stdio_term(void) attribute_hidden; #endif -static int been_there_done_that = 0; +static smallint been_there_done_that = 0; /* Be prepared in case multiple threads try to abort() */ -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include <bits/uClibc_mutex.h> +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); /* Cause an abnormal program termination with core-dump */ void abort(void) @@ -62,7 +58,7 @@ void abort(void) sigset_t sigs; /* Make sure we acquire the lock before proceeding */ - LOCK; + __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock); /* Unmask SIGABRT to be sure we can get it */ if (__sigemptyset(&sigs) == 0 && __sigaddset(&sigs, SIGABRT) == 0) { @@ -85,9 +81,9 @@ void abort(void) #endif abort_it: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(mylock); raise(SIGABRT); - LOCK; + __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock); } /* Still here? Try to remove any signal handlers */ diff --git a/libc/stdlib/bsd_getpt.c b/libc/stdlib/bsd_getpt.c index 9b885c4e5..1afd57f47 100644 --- a/libc/stdlib/bsd_getpt.c +++ b/libc/stdlib/bsd_getpt.c @@ -22,13 +22,13 @@ #include <string.h> #include <unistd.h> +#if defined __USE_BSD libc_hidden_proto(open) -libc_hidden_proto(mempcpy) +/* Experimentally off - libc_hidden_proto(mempcpy) */ /* Prefix for master pseudo terminal nodes. */ #define _PATH_PTY "/dev/pty" - /* Letters indicating a series of pseudo terminals. */ #ifndef PTYNAME1 #define PTYNAME1 "pqrsPQRS" @@ -41,7 +41,6 @@ const char __libc_ptyname1[] attribute_hidden = PTYNAME1; #endif const char __libc_ptyname2[] attribute_hidden = PTYNAME2; - /* Open a master pseudo terminal and return its file descriptor. */ int __getpt (void) @@ -76,3 +75,4 @@ __getpt (void) __set_errno (ENOENT); return -1; } +#endif /* __USE_BSD */ diff --git a/libc/stdlib/drand48-iter.c b/libc/stdlib/drand48-iter.c index 0e674a3ce..221cbe08f 100644 --- a/libc/stdlib/drand48-iter.c +++ b/libc/stdlib/drand48-iter.c @@ -26,12 +26,11 @@ /* Global state for non-reentrant functions. */ struct drand48_data __libc_drand48_data attribute_hidden; - +#ifdef __UCLIBC_MJN3_ONLY__ +#warning turn int __drand48_iterate into void +#endif /* __UCLIBC_MJN3_ONLY__ */ int __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) attribute_hidden; -int -__drand48_iterate (xsubi, buffer) - unsigned short int xsubi[3]; - struct drand48_data *buffer; +int __drand48_iterate (unsigned short int xsubi[3], struct drand48_data *buffer) { uint64_t X; uint64_t result; diff --git a/libc/stdlib/drand48.c b/libc/stdlib/drand48.c index ab6239d75..f96947cb2 100644 --- a/libc/stdlib/drand48.c +++ b/libc/stdlib/drand48.c @@ -24,8 +24,7 @@ libc_hidden_proto(erand48_r) /* Global state for non-reentrant functions. Defined in drand48-iter.c. */ extern struct drand48_data __libc_drand48_data attribute_hidden; -double -drand48 () +double drand48 (void) { double result; diff --git a/libc/stdlib/getenv.c b/libc/stdlib/getenv.c index c7940f398..230ec0051 100644 --- a/libc/stdlib/getenv.c +++ b/libc/stdlib/getenv.c @@ -9,8 +9,8 @@ #include <stdlib.h> libc_hidden_proto(getenv) -libc_hidden_proto(memcmp) -libc_hidden_proto(strlen) +/* Experimentally off - libc_hidden_proto(memcmp) */ +/* Experimentally off - libc_hidden_proto(strlen) */ /* IEEE Std 1003.1-2001 says getenv need not be thread safe, so * don't bother locking access to __environ */ diff --git a/libc/stdlib/getpt.c b/libc/stdlib/getpt.c index cab96bb06..1b5de7c16 100644 --- a/libc/stdlib/getpt.c +++ b/libc/stdlib/getpt.c @@ -20,8 +20,13 @@ #include <errno.h> #include <fcntl.h> #include <stdlib.h> +#include <stdbool.h> #include <unistd.h> #include <paths.h> +#include <sys/statfs.h> + +extern __typeof(statfs) __libc_statfs; +libc_hidden_proto(__libc_statfs) libc_hidden_proto(open) libc_hidden_proto(close) @@ -40,43 +45,44 @@ libc_hidden_proto(close) /* Directory containing the UNIX98 pseudo terminals. */ #define _PATH_DEVPTS _PATH_DEV "pts" -#if !defined __UNIX98PTY_ONLY__ +#if !defined __UNIX98PTY_ONLY__ && defined __UCLIBC_HAS_GETPT__ /* Prototype for function that opens BSD-style master pseudo-terminals. */ extern int __bsd_getpt (void) attribute_hidden; #endif /* Open a master pseudo terminal and return its file descriptor. */ int -getpt (void) +posix_openpt (int flags) { +#define have_no_dev_ptmx (1<<0) +#define devpts_mounted (1<<1) #if !defined __UNIX98PTY_ONLY__ - static int have_no_dev_ptmx; + static smallint _state; #endif int fd; #if !defined __UNIX98PTY_ONLY__ - if (!have_no_dev_ptmx) + if (!(_state & have_no_dev_ptmx)) #endif { - fd = open (_PATH_DEVPTMX, O_RDWR); + fd = open (_PATH_DEVPTMX, flags); if (fd != -1) { #if defined __ASSUME_DEVPTS__ return fd; #else struct statfs fsbuf; - static int devpts_mounted; /* Check that the /dev/pts filesystem is mounted or if /dev is a devfs filesystem (this implies /dev/pts). */ - if (devpts_mounted - || (statfs (_PATH_DEVPTS, &fsbuf) == 0 + if ((_state & devpts_mounted) + || (__libc_statfs (_PATH_DEVPTS, &fsbuf) == 0 && fsbuf.f_type == DEVPTS_SUPER_MAGIC) - || (statfs (_PATH_DEV, &fsbuf) == 0 + || (__libc_statfs (_PATH_DEV, &fsbuf) == 0 && fsbuf.f_type == DEVFS_SUPER_MAGIC)) { /* Everything is ok. */ - devpts_mounted = 1; + _state |= devpts_mounted; return fd; } @@ -84,7 +90,7 @@ getpt (void) are not usable. */ close (fd); #if !defined __UNIX98PTY_ONLY__ - have_no_dev_ptmx = 1; + _state |= have_no_dev_ptmx; #endif #endif } @@ -92,16 +98,27 @@ getpt (void) { #if !defined __UNIX98PTY_ONLY__ if (errno == ENOENT || errno == ENODEV) - have_no_dev_ptmx = 1; + _state |= have_no_dev_ptmx; else #endif return -1; } } + return -1; +} +#undef have_no_dev_ptmx +#undef devpts_mounted +#if defined __USE_GNU && defined __UCLIBC_HAS_GETPT__ +int +getpt (void) +{ + int fd = posix_openpt(O_RDWR); #if !defined __UNIX98PTY_ONLY__ - return __bsd_getpt (); + if (fd == -1) + fd = __bsd_getpt(); #endif + return fd; } #if !defined __UNIX98PTY_ONLY__ @@ -111,3 +128,4 @@ getpt (void) # define __getpt __bsd_getpt # include "bsd_getpt.c" #endif +#endif /* GNU && __UCLIBC_HAS_GETPT__ */ diff --git a/libc/stdlib/l64a.c b/libc/stdlib/l64a.c index f3a249fed..a8b2d551e 100644 --- a/libc/stdlib/l64a.c +++ b/libc/stdlib/l64a.c @@ -32,9 +32,7 @@ static const char conv_table[64] = 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; -char * -l64a (n) - long int n; +char * l64a (long int n) { unsigned long int m = (unsigned long int) n; static char result[7]; diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c index a1c7b93c9..13d4166a7 100644 --- a/libc/stdlib/malloc-simple/alloc.c +++ b/libc/stdlib/malloc-simple/alloc.c @@ -13,11 +13,10 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> #include <errno.h> #include <sys/mman.h> -libc_hidden_proto(memcpy) +/* Experimentally off - libc_hidden_proto(memcpy) */ /*libc_hidden_proto(memset)*/ libc_hidden_proto(mmap) libc_hidden_proto(munmap) @@ -115,12 +114,11 @@ void free(void *ptr) #endif #ifdef L_memalign -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif -#define LOCK __pthread_mutex_lock(&__malloc_lock) -#define UNLOCK __pthread_mutex_unlock(&__malloc_lock) + +#include <bits/uClibc_mutex.h> +__UCLIBC_MUTEX_STATIC(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); +#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) +#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) /* List of blocks allocated with memalign or valloc */ struct alignlist @@ -139,7 +137,7 @@ int __libc_free_aligned(void *ptr) if (ptr == NULL) return 0; - LOCK; + __MALLOC_LOCK; for (l = _aligned_blocks; l != NULL; l = l->next) { if (l->aligned == ptr) { /* Mark the block as free */ @@ -150,7 +148,7 @@ int __libc_free_aligned(void *ptr) return 1; } } - UNLOCK; + __MALLOC_UNLOCK; return 0; } void * memalign (size_t alignment, size_t size) @@ -162,11 +160,10 @@ void * memalign (size_t alignment, size_t size) if (result == NULL) return NULL; - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % alignment; + adj = (unsigned long int) ((unsigned long int) ((char *) result - (char *) NULL)) % alignment; if (adj != 0) { struct alignlist *l; - LOCK; + __MALLOC_LOCK; for (l = _aligned_blocks; l != NULL; l = l->next) if (l->aligned == NULL) /* This slot is free. Use it. */ @@ -175,15 +172,16 @@ void * memalign (size_t alignment, size_t size) l = (struct alignlist *) malloc (sizeof (struct alignlist)); if (l == NULL) { free(result); - UNLOCK; - return NULL; + result = NULL; + goto DONE; } l->next = _aligned_blocks; _aligned_blocks = l; } l->exact = result; result = l->aligned = (char *) result + alignment - adj; - UNLOCK; +DONE: + __MALLOC_UNLOCK; } return result; diff --git a/libc/stdlib/malloc-standard/calloc.c b/libc/stdlib/malloc-standard/calloc.c index 99e8884ad..80ba3d04a 100644 --- a/libc/stdlib/malloc-standard/calloc.c +++ b/libc/stdlib/malloc-standard/calloc.c @@ -16,7 +16,7 @@ #include "malloc.h" -libc_hidden_proto(memset) +/* Experimentally off - libc_hidden_proto(memset) */ /* ------------------------------ calloc ------------------------------ */ void* calloc(size_t n_elements, size_t elem_size) @@ -36,7 +36,7 @@ void* calloc(size_t n_elements, size_t elem_size) return NULL; } - LOCK; + __MALLOC_LOCK; mem = malloc(size); if (mem != 0) { p = mem2chunk(mem); @@ -88,7 +88,7 @@ void* calloc(size_t n_elements, size_t elem_size) } #endif } - UNLOCK; + __MALLOC_UNLOCK; return mem; } diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c index e0c6ef061..4d24697be 100644 --- a/libc/stdlib/malloc-standard/free.c +++ b/libc/stdlib/malloc-standard/free.c @@ -282,7 +282,7 @@ void free(void* mem) if (mem == NULL) return; - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); p = mem2chunk(mem); size = chunksize(p); @@ -406,6 +406,6 @@ void free(void* mem) av->mmapped_mem -= (size + offset); munmap((char*)p - offset, size + offset); } - UNLOCK; + __MALLOC_UNLOCK; } diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c index 4f274ed32..18331010a 100644 --- a/libc/stdlib/malloc-standard/mallinfo.c +++ b/libc/stdlib/malloc-standard/mallinfo.c @@ -32,7 +32,7 @@ struct mallinfo mallinfo(void) int nblocks; int nfastblocks; - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); /* Ensure initialization */ if (av->top == 0) { @@ -77,7 +77,7 @@ struct mallinfo mallinfo(void) mi.fsmblks = fastavail; mi.keepcost = chunksize(av->top); mi.usmblks = av->max_total_mem; - UNLOCK; + __MALLOC_UNLOCK; return mi; } libc_hidden_def(mallinfo) @@ -91,19 +91,36 @@ void malloc_stats(FILE *file) } mi = mallinfo(); - fprintf(file, "total bytes allocated = %10u\n", (unsigned int)(mi.arena + mi.hblkhd)); - fprintf(file, "total bytes in use bytes = %10u\n", (unsigned int)(mi.uordblks + mi.hblkhd)); - fprintf(file, "total non-mmapped bytes allocated = %10d\n", mi.arena); - fprintf(file, "number of mmapped regions = %10d\n", mi.hblks); - fprintf(file, "total allocated mmap space = %10d\n", mi.hblkhd); - fprintf(file, "total allocated sbrk space = %10d\n", mi.uordblks); + fprintf(file, + "total bytes allocated = %10u\n" + "total bytes in use bytes = %10u\n" + "total non-mmapped bytes allocated = %10d\n" + "number of mmapped regions = %10d\n" + "total allocated mmap space = %10d\n" + "total allocated sbrk space = %10d\n" #if 0 - fprintf(file, "number of free chunks = %10d\n", mi.ordblks); - fprintf(file, "number of fastbin blocks = %10d\n", mi.smblks); - fprintf(file, "space in freed fastbin blocks = %10d\n", mi.fsmblks); + "number of free chunks = %10d\n" + "number of fastbin blocks = %10d\n" + "space in freed fastbin blocks = %10d\n" #endif - fprintf(file, "maximum total allocated space = %10d\n", mi.usmblks); - fprintf(file, "total free space = %10d\n", mi.fordblks); - fprintf(file, "memory releasable via malloc_trim = %10d\n", mi.keepcost); + "maximum total allocated space = %10d\n" + "total free space = %10d\n" + "memory releasable via malloc_trim = %10d\n", + + (unsigned int)(mi.arena + mi.hblkhd), + (unsigned int)(mi.uordblks + mi.hblkhd), + mi.arena, + mi.hblks, + mi.hblkhd, + mi.uordblks, +#if 0 + mi.ordblks, + mi.smblks, + mi.fsmblks, +#endif + mi.usmblks, + mi.fordblks, + mi.keepcost + ); } diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index 0dc208fb6..3253ebda6 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -17,9 +17,7 @@ #include "malloc.h" -#ifdef __UCLIBC_HAS_THREADS__ -pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif +__UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); /* There is exactly one instance of this struct in this malloc. @@ -33,7 +31,7 @@ struct malloc_state __malloc_state; /* never directly referenced */ /* forward declaration */ static int __malloc_largebin_index(unsigned int sz); -#ifdef __MALLOC_DEBUGGING +#ifdef __UCLIBC_MALLOC_DEBUGGING__ /* Debugging support @@ -43,21 +41,21 @@ static int __malloc_largebin_index(unsigned int sz); programs. This can be very effective (albeit in an annoying way) in helping track down dangling pointers. - If you compile with -D__MALLOC_DEBUGGING, a number of assertion checks are + If you compile with __UCLIBC_MALLOC_DEBUGGING__, a number of assertion checks are enabled that will catch more memory errors. You probably won't be able to make much sense of the actual assertion errors, but they should help you locate incorrectly overwritten memory. The checking is fairly extensive, and will slow down execution - noticeably. Calling malloc_stats or mallinfo with __MALLOC_DEBUGGING set will + noticeably. Calling malloc_stats or mallinfo with __UCLIBC_MALLOC_DEBUGGING__ set will attempt to check every non-mmapped allocated and free chunk in the course of computing the summmaries. (By nature, mmapped regions cannot be checked very much automatically.) - Setting __MALLOC_DEBUGGING may also be helpful if you are trying to modify + Setting __UCLIBC_MALLOC_DEBUGGING__ may also be helpful if you are trying to modify this code. The assertions in the check routines spell out in more detail the assumptions and invariants underlying the algorithms. - Setting __MALLOC_DEBUGGING does NOT provide an automated mechanism for checking + Setting __UCLIBC_MALLOC_DEBUGGING__ does NOT provide an automated mechanism for checking that all accesses to malloced memory stay within their bounds. However, there are several add-ons and adaptations of this or other mallocs available that do this. @@ -351,7 +349,7 @@ static void* __malloc_alloc(size_t nb, mstate av) char* old_end; /* its end address */ long size; /* arg to first MORECORE or mmap call */ - char* brk; /* return value from MORECORE */ + char* fst_brk; /* return value from MORECORE */ long correction; /* arg to 2nd MORECORE call */ char* snd_brk; /* 2nd return val */ @@ -455,7 +453,7 @@ static void* __malloc_alloc(size_t nb, mstate av) old_size = chunksize(old_top); old_end = (char*)(chunk_at_offset(old_top, old_size)); - brk = snd_brk = (char*)(MORECORE_FAILURE); + fst_brk = snd_brk = (char*)(MORECORE_FAILURE); /* If not the first time through, we require old_size to * be at least MINSIZE and to have prev_inuse set. */ @@ -501,7 +499,7 @@ static void* __malloc_alloc(size_t nb, mstate av) */ if (size > 0) - brk = (char*)(MORECORE(size)); + fst_brk = (char*)(MORECORE(size)); /* If have mmap, try using it as a backup when MORECORE fails or @@ -512,7 +510,7 @@ static void* __malloc_alloc(size_t nb, mstate av) segregated mmap region. */ - if (brk == (char*)(MORECORE_FAILURE)) { + if (fst_brk == (char*)(MORECORE_FAILURE)) { /* Cannot merge with old top, so add its size back in */ if (contiguous(av)) @@ -525,12 +523,12 @@ static void* __malloc_alloc(size_t nb, mstate av) /* Don't try if size wraps around 0 */ if ((unsigned long)(size) > (unsigned long)(nb)) { - brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); + fst_brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); - if (brk != (char*)(MORECORE_FAILURE)) { + if (fst_brk != (char*)(MORECORE_FAILURE)) { /* We do not need, and cannot use, another sbrk call to find end */ - snd_brk = brk + size; + snd_brk = fst_brk + size; /* Record that we no longer have a contiguous sbrk region. After the first time mmap is used as backup, we do not @@ -542,14 +540,14 @@ static void* __malloc_alloc(size_t nb, mstate av) } } - if (brk != (char*)(MORECORE_FAILURE)) { + if (fst_brk != (char*)(MORECORE_FAILURE)) { av->sbrked_mem += size; /* If MORECORE extends previous space, we can likewise extend top size. */ - if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { + if (fst_brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { set_head(old_top, (size + old_size) | PREV_INUSE); } @@ -576,7 +574,7 @@ static void* __malloc_alloc(size_t nb, mstate av) front_misalign = 0; end_misalign = 0; correction = 0; - aligned_brk = brk; + aligned_brk = fst_brk; /* If MORECORE returns an address lower than we have seen before, @@ -586,7 +584,7 @@ static void* __malloc_alloc(size_t nb, mstate av) malloc or by other threads. We cannot guarantee to detect these in all cases, but cope with the ones we do detect. */ - if (contiguous(av) && old_size != 0 && brk < old_end) { + if (contiguous(av) && old_size != 0 && fst_brk < old_end) { set_noncontiguous(av); } @@ -597,11 +595,11 @@ static void* __malloc_alloc(size_t nb, mstate av) to foreign calls) but treat them as part of our space for stats reporting. */ if (old_size != 0) - av->sbrked_mem += brk - old_end; + av->sbrked_mem += fst_brk - old_end; /* Guarantee alignment of first new chunk made from this space */ - front_misalign = (size_t)chunk2mem(brk) & MALLOC_ALIGN_MASK; + front_misalign = (size_t)chunk2mem(fst_brk) & MALLOC_ALIGN_MASK; if (front_misalign > 0) { /* @@ -624,7 +622,7 @@ static void* __malloc_alloc(size_t nb, mstate av) correction += old_size; /* Extend the end address to hit a page boundary */ - end_misalign = (size_t)(brk + size + correction); + end_misalign = (size_t)(fst_brk + size + correction); correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; assert(correction >= 0); @@ -638,7 +636,7 @@ static void* __malloc_alloc(size_t nb, mstate av) correction = 0; snd_brk = (char*)(MORECORE(0)); } - else if (snd_brk < brk) { + else if (snd_brk < fst_brk) { /* If the second call gives noncontiguous space even though it says it won't, the only course of action is to ignore @@ -651,7 +649,7 @@ static void* __malloc_alloc(size_t nb, mstate av) there is no reliable way to detect a noncontiguity producing a forward gap for the second call. */ - snd_brk = brk + size; + snd_brk = fst_brk + size; correction = 0; set_noncontiguous(av); } @@ -661,12 +659,12 @@ static void* __malloc_alloc(size_t nb, mstate av) /* handle non-contiguous cases */ else { /* MORECORE/mmap must correctly align */ - assert(aligned_OK(chunk2mem(brk))); + assert(aligned_OK(chunk2mem(fst_brk))); /* Find out current end of memory */ if (snd_brk == (char*)(MORECORE_FAILURE)) { snd_brk = (char*)(MORECORE(0)); - av->sbrked_mem += snd_brk - brk - size; + av->sbrked_mem += snd_brk - fst_brk - size; } } @@ -825,6 +823,7 @@ void* malloc(size_t bytes) mchunkptr fwd; /* misc temp for linking */ mchunkptr bck; /* misc temp for linking */ void * sysmem; + void * retval; #if !defined(__MALLOC_GLIBC_COMPAT__) if (!bytes) { @@ -833,7 +832,7 @@ void* malloc(size_t bytes) } #endif - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); /* Convert request size to internal form by adding (sizeof(size_t)) bytes @@ -864,8 +863,8 @@ void* malloc(size_t bytes) if ( (victim = *fb) != 0) { *fb = victim->fd; check_remalloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } @@ -888,8 +887,8 @@ void* malloc(size_t bytes) bck->fd = bin; check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } @@ -945,8 +944,8 @@ void* malloc(size_t bytes) set_foot(remainder, remainder_size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* remove from unsorted list */ @@ -958,8 +957,8 @@ void* malloc(size_t bytes) if (size == nb) { set_inuse_bit_at_offset(victim, size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* place chunk in bin */ @@ -1022,8 +1021,8 @@ void* malloc(size_t bytes) if (remainder_size < MINSIZE) { set_inuse_bit_at_offset(victim, size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* Split */ else { @@ -1034,8 +1033,8 @@ void* malloc(size_t bytes) set_head(remainder, remainder_size | PREV_INUSE); set_foot(remainder, remainder_size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } } @@ -1103,8 +1102,8 @@ void* malloc(size_t bytes) if (remainder_size < MINSIZE) { set_inuse_bit_at_offset(victim, size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* Split */ @@ -1121,8 +1120,8 @@ void* malloc(size_t bytes) set_head(remainder, remainder_size | PREV_INUSE); set_foot(remainder, remainder_size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } } @@ -1154,13 +1153,15 @@ use_top: set_head(remainder, remainder_size | PREV_INUSE); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* If no space in top, relay to handle system-dependent cases */ sysmem = __malloc_alloc(nb, av); - UNLOCK; - return sysmem; + retval = sysmem; +DONE: + __MALLOC_UNLOCK; + return retval; } diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h index 453d69736..389f1f7d4 100644 --- a/libc/stdlib/malloc-standard/malloc.h +++ b/libc/stdlib/malloc-standard/malloc.h @@ -22,18 +22,17 @@ #include <malloc.h> #include <stdlib.h> #include <sys/mman.h> +#include <bits/uClibc_mutex.h> libc_hidden_proto(mmap) libc_hidden_proto(sysconf) libc_hidden_proto(sbrk) libc_hidden_proto(abort) -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -extern pthread_mutex_t __malloc_lock; -#endif -#define LOCK __pthread_mutex_lock(&__malloc_lock) -#define UNLOCK __pthread_mutex_unlock(&__malloc_lock) + +__UCLIBC_MUTEX_EXTERN(__malloc_lock); +#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) +#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) @@ -925,7 +924,7 @@ extern struct malloc_state __malloc_state; /* never directly referenced */ At most one "call" to get_malloc_state is made per invocation of the public versions of malloc and free, but other routines that in turn invoke malloc and/or free may call more then once. - Also, it is called in check* routines if __MALLOC_DEBUGGING is set. + Also, it is called in check* routines if __UCLIBC_MALLOC_DEBUGGING__ is set. */ #define get_malloc_state() (&(__malloc_state)) @@ -935,7 +934,7 @@ void __malloc_consolidate(mstate) attribute_hidden; /* Debugging support */ -#if ! __MALLOC_DEBUGGING +#ifndef __UCLIBC_MALLOC_DEBUGGING__ #define check_chunk(P) #define check_free_chunk(P) diff --git a/libc/stdlib/malloc-standard/mallopt.c b/libc/stdlib/malloc-standard/mallopt.c index e28792099..053242dbe 100644 --- a/libc/stdlib/malloc-standard/mallopt.c +++ b/libc/stdlib/malloc-standard/mallopt.c @@ -25,7 +25,7 @@ int mallopt(int param_number, int value) ret = 0; - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); /* Ensure initialization/consolidation */ __malloc_consolidate(av); @@ -58,7 +58,7 @@ int mallopt(int param_number, int value) ret = 1; break; } - UNLOCK; + __MALLOC_UNLOCK; return ret; } diff --git a/libc/stdlib/malloc-standard/memalign.c b/libc/stdlib/malloc-standard/memalign.c index 27502893d..7e0674be5 100644 --- a/libc/stdlib/malloc-standard/memalign.c +++ b/libc/stdlib/malloc-standard/memalign.c @@ -35,6 +35,7 @@ void* memalign(size_t alignment, size_t bytes) mchunkptr remainder; /* spare room at end to split off */ unsigned long remainder_size; /* its size */ size_t size; + void *retval; /* If need less alignment than we give anyway, just relay to malloc */ @@ -51,7 +52,7 @@ void* memalign(size_t alignment, size_t bytes) alignment = a; } - LOCK; + __MALLOC_LOCK; checked_request2size(bytes, nb); /* Strategy: find a spot within that chunk that meets the alignment @@ -63,8 +64,8 @@ void* memalign(size_t alignment, size_t bytes) m = (char*)(malloc(nb + alignment + MINSIZE)); if (m == 0) { - UNLOCK; - return 0; /* propagate failure */ + retval = 0; /* propagate failure */ + goto DONE; } p = mem2chunk(m); @@ -92,8 +93,8 @@ void* memalign(size_t alignment, size_t bytes) if (chunk_is_mmapped(p)) { newp->prev_size = p->prev_size + leadsize; set_head(newp, newsize|IS_MMAPPED); - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } /* Otherwise, give back leader, use the rest */ @@ -120,7 +121,10 @@ void* memalign(size_t alignment, size_t bytes) } check_inuse_chunk(p); - UNLOCK; - return chunk2mem(p); + retval = chunk2mem(p); + + DONE: + __MALLOC_UNLOCK; + return retval; } diff --git a/libc/stdlib/malloc-standard/realloc.c b/libc/stdlib/malloc-standard/realloc.c index f25d6d989..41cae43d1 100644 --- a/libc/stdlib/malloc-standard/realloc.c +++ b/libc/stdlib/malloc-standard/realloc.c @@ -17,7 +17,7 @@ #include "malloc.h" libc_hidden_proto(mremap) -libc_hidden_proto(memcpy) +/* Experimentally off - libc_hidden_proto(memcpy) */ /* ------------------------------ realloc ------------------------------ */ void* realloc(void* oldmem, size_t bytes) @@ -46,6 +46,7 @@ void* realloc(void* oldmem, size_t bytes) size_t* s; /* copy source */ size_t* d; /* copy destination */ + void *retval; /* Check for special cases. */ if (! oldmem) @@ -55,7 +56,7 @@ void* realloc(void* oldmem, size_t bytes) return NULL; } - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); checked_request2size(bytes, nb); @@ -82,8 +83,8 @@ void* realloc(void* oldmem, size_t bytes) set_head_size(oldp, nb); av->top = chunk_at_offset(oldp, nb); set_head(av->top, (newsize - nb) | PREV_INUSE); - UNLOCK; - return chunk2mem(oldp); + retval = chunk2mem(oldp); + goto DONE; } /* Try to expand forward into next chunk; split off remainder below */ @@ -99,8 +100,8 @@ void* realloc(void* oldmem, size_t bytes) else { newmem = malloc(nb - MALLOC_ALIGN_MASK); if (newmem == 0) { - UNLOCK; - return 0; /* propagate failure */ + retval = 0; /* propagate failure */ + goto DONE; } newp = mem2chunk(newmem); @@ -149,8 +150,8 @@ void* realloc(void* oldmem, size_t bytes) free(oldmem); check_inuse_chunk(newp); - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } } } @@ -175,8 +176,8 @@ void* realloc(void* oldmem, size_t bytes) } check_inuse_chunk(newp); - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } /* @@ -194,8 +195,8 @@ void* realloc(void* oldmem, size_t bytes) /* don't need to remap if still within same page */ if (oldsize == newsize - offset) { - UNLOCK; - return oldmem; + retval = oldmem; + goto DONE; } cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); @@ -216,8 +217,8 @@ void* realloc(void* oldmem, size_t bytes) if (sum > (unsigned long)(av->max_total_mem)) av->max_total_mem = sum; - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } /* Note the extra (sizeof(size_t)) overhead. */ @@ -231,8 +232,11 @@ void* realloc(void* oldmem, size_t bytes) free(oldmem); } } - UNLOCK; - return newmem; + retval = newmem; } + + DONE: + __MALLOC_UNLOCK; + return retval; } diff --git a/libc/stdlib/malloc/calloc.c b/libc/stdlib/malloc/calloc.c index 5925a9e0a..79e6ec6c7 100644 --- a/libc/stdlib/malloc/calloc.c +++ b/libc/stdlib/malloc/calloc.c @@ -22,7 +22,7 @@ #include <string.h> #include <errno.h> -libc_hidden_proto(memset) +/* Experimentally off - libc_hidden_proto(memset) */ void * calloc(size_t nmemb, size_t lsize) { diff --git a/libc/stdlib/malloc/free.c b/libc/stdlib/malloc/free.c index 81c718376..da395331b 100644 --- a/libc/stdlib/malloc/free.c +++ b/libc/stdlib/malloc/free.c @@ -7,7 +7,7 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License. See the file COPYING.LIB in the main * directory of this archive for more details. - * + * * Written by Miles Bader <miles@gnu.org> */ diff --git a/libc/stdlib/malloc/heap.h b/libc/stdlib/malloc/heap.h index b66b5ecef..38ec41cbf 100644 --- a/libc/stdlib/malloc/heap.h +++ b/libc/stdlib/malloc/heap.h @@ -7,7 +7,7 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License. See the file COPYING.LIB in the main * directory of this archive for more details. - * + * * Written by Miles Bader <miles@gnu.org> */ @@ -17,6 +17,7 @@ /* On multi-threaded systems, the heap includes a lock. */ #ifdef __UCLIBC_HAS_THREADS__ # include <pthread.h> +# include <bits/uClibc_pthread.h> # define HEAP_USE_LOCKING #endif @@ -24,7 +25,7 @@ /* The heap allocates in multiples of, and aligned to, HEAP_GRANULARITY. HEAP_GRANULARITY must be a power of 2. Malloc depends on this being the same as MALLOC_ALIGNMENT. */ -#define HEAP_GRANULARITY_TYPE double +#define HEAP_GRANULARITY_TYPE double __attribute_aligned__ (sizeof (size_t)) #define HEAP_GRANULARITY (__alignof__ (HEAP_GRANULARITY_TYPE)) diff --git a/libc/stdlib/malloc/heap_alloc.c b/libc/stdlib/malloc/heap_alloc.c index 8a6c7842e..f8d596506 100644 --- a/libc/stdlib/malloc/heap_alloc.c +++ b/libc/stdlib/malloc/heap_alloc.c @@ -7,7 +7,7 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License. See the file COPYING.LIB in the main * directory of this archive for more details. - * + * * Written by Miles Bader <miles@gnu.org> */ diff --git a/libc/stdlib/malloc/heap_alloc_at.c b/libc/stdlib/malloc/heap_alloc_at.c index de84e99ee..296c6e552 100644 --- a/libc/stdlib/malloc/heap_alloc_at.c +++ b/libc/stdlib/malloc/heap_alloc_at.c @@ -7,7 +7,7 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License. See the file COPYING.LIB in the main * directory of this archive for more details. - * + * * Written by Miles Bader <miles@gnu.org> */ diff --git a/libc/stdlib/malloc/heap_debug.c b/libc/stdlib/malloc/heap_debug.c index e83831d3a..a2a9f4ec1 100644 --- a/libc/stdlib/malloc/heap_debug.c +++ b/libc/stdlib/malloc/heap_debug.c @@ -49,7 +49,7 @@ __heap_dump_freelist (struct heap *heap) void __heap_dump (struct heap *heap, const char *str) { - static int recursed = 0; + static smallint recursed; if (! recursed) { diff --git a/libc/stdlib/malloc/heap_free.c b/libc/stdlib/malloc/heap_free.c index a4b5259af..8bc740dd8 100644 --- a/libc/stdlib/malloc/heap_free.c +++ b/libc/stdlib/malloc/heap_free.c @@ -7,7 +7,7 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License. See the file COPYING.LIB in the main * directory of this archive for more details. - * + * * Written by Miles Bader <miles@gnu.org> */ diff --git a/libc/stdlib/malloc/malloc.c b/libc/stdlib/malloc/malloc.c index 770d7aea3..ce74c5608 100644 --- a/libc/stdlib/malloc/malloc.c +++ b/libc/stdlib/malloc/malloc.c @@ -184,7 +184,7 @@ malloc (size_t size) { void *mem; #ifdef MALLOC_DEBUGGING - static int debugging_initialized = 0; + static smallint debugging_initialized; if (! debugging_initialized) { debugging_initialized = 1; diff --git a/libc/stdlib/malloc/malloc.h b/libc/stdlib/malloc/malloc.h index b41c4b08e..7277cd2cf 100644 --- a/libc/stdlib/malloc/malloc.h +++ b/libc/stdlib/malloc/malloc.h @@ -11,8 +11,13 @@ * Written by Miles Bader <miles@gnu.org> */ -/* The alignment we guarantee for malloc return values. */ -#define MALLOC_ALIGNMENT (__alignof__ (double)) +/* The alignment we guarantee for malloc return values. We prefer this + to be at least sizeof (size_t) bytes because (a) we have to allocate + that many bytes for the header anyway and (b) guaranteeing word + alignment can be a significant win on targets like m68k and Coldfire, + where __alignof__(double) == 2. */ +#define MALLOC_ALIGNMENT \ + __alignof__ (double __attribute_aligned__ (sizeof (size_t))) /* The system pagesize... */ extern size_t __pagesize; @@ -79,7 +84,6 @@ extern struct heap __malloc_mmb_heap; to stderr, when the variable __malloc_mmb_debug is set to true. */ #ifdef MALLOC_MMB_DEBUGGING # include <stdio.h> -extern int __putc(int c, FILE *stream) attribute_hidden; extern int __malloc_mmb_debug; # define MALLOC_MMB_DEBUG(indent, fmt, args...) \ @@ -98,17 +102,20 @@ extern int __malloc_mmb_debug; /* The size of a malloc allocation is stored in a size_t word - MALLOC_ALIGNMENT bytes prior to the start address of the allocation: + MALLOC_HEADER_SIZE bytes prior to the start address of the allocation: +--------+---------+-------------------+ | SIZE |(unused) | allocation ... | +--------+---------+-------------------+ ^ BASE ^ ADDR - ^ ADDR - MALLOC_ALIGN + ^ ADDR - MALLOC_HEADER_SIZE */ /* The amount of extra space used by the malloc header. */ -#define MALLOC_HEADER_SIZE MALLOC_ALIGNMENT +#define MALLOC_HEADER_SIZE \ + (MALLOC_ALIGNMENT < sizeof (size_t) \ + ? sizeof (size_t) \ + : MALLOC_ALIGNMENT) /* Set up the malloc header, and return the user address of a malloc block. */ #define MALLOC_SETUP(base, size) \ @@ -126,6 +133,7 @@ extern int __malloc_mmb_debug; #ifdef __UCLIBC_HAS_THREADS__ # include <pthread.h> +# include <bits/uClibc_pthread.h> # define MALLOC_USE_LOCKING diff --git a/libc/stdlib/malloc/malloc_debug.c b/libc/stdlib/malloc/malloc_debug.c index 6c74d78bb..39c3919c5 100644 --- a/libc/stdlib/malloc/malloc_debug.c +++ b/libc/stdlib/malloc/malloc_debug.c @@ -7,7 +7,7 @@ * This file is subject to the terms and conditions of the GNU Lesser * General Public License. See the file COPYING.LIB in the main * directory of this archive for more details. - * + * * Written by Miles Bader <miles@gnu.org> */ diff --git a/libc/stdlib/malloc/realloc.c b/libc/stdlib/malloc/realloc.c index ec57b874e..948326762 100644 --- a/libc/stdlib/malloc/realloc.c +++ b/libc/stdlib/malloc/realloc.c @@ -15,7 +15,7 @@ #include <string.h> #include <errno.h> -libc_hidden_proto(memcpy) +/* Experimentally off - libc_hidden_proto(memcpy) */ #include "malloc.h" #include "heap.h" diff --git a/libc/stdlib/mkdtemp.c b/libc/stdlib/mkdtemp.c index 6773a5bb3..fa9ae3b05 100644 --- a/libc/stdlib/mkdtemp.c +++ b/libc/stdlib/mkdtemp.c @@ -29,7 +29,7 @@ (This function comes from OpenBSD.) */ char * mkdtemp (char *template) { - if (__gen_tempname (template, __GT_DIR)) + if (__gen_tempname (template, __GT_DIR)) return NULL; else return template; diff --git a/libc/stdlib/ptsname.c b/libc/stdlib/ptsname.c index dfb0d19db..1fd516234 100644 --- a/libc/stdlib/ptsname.c +++ b/libc/stdlib/ptsname.c @@ -29,9 +29,9 @@ #include <unistd.h> #include <bits/uClibc_uintmaxtostr.h> -libc_hidden_proto(strcat) -libc_hidden_proto(strcpy) -libc_hidden_proto(strlen) +/* Experimentally off - libc_hidden_proto(strcat) */ +/* Experimentally off - libc_hidden_proto(strcpy) */ +/* Experimentally off - libc_hidden_proto(strlen) */ libc_hidden_proto(isatty) libc_hidden_proto(ioctl) libc_hidden_proto(fstat) @@ -129,7 +129,7 @@ int ptsname_r (int fd, char *buf, size_t buflen) return ENOTTY; } #else -# if !defined TIOCGPTN +# if defined TIOCGPTN else if (errno == EINVAL) # endif { diff --git a/libc/stdlib/random.c b/libc/stdlib/random.c index 80df7890b..3eb8aed8a 100644 --- a/libc/stdlib/random.c +++ b/libc/stdlib/random.c @@ -32,14 +32,12 @@ libc_hidden_proto(srandom_r) libc_hidden_proto(setstate_r) libc_hidden_proto(initstate_r) -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -# include <pthreadP.h> /* POSIX.1c requires that there is mutual exclusion for the `rand' and `srand' functions to prevent concurrent calls from modifying common data. */ -static pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif +#include <bits/uClibc_mutex.h> +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); + /* An improved random number generation package. In addition to the standard rand()/srand() like interface, this package also has a special state info @@ -187,9 +185,9 @@ static struct random_data unsafe_state = for default usage relies on values produced by this routine. */ void srandom (unsigned int x) { - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); srandom_r (x, &unsafe_state); - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); } strong_alias(srandom,srand) @@ -208,10 +206,10 @@ char * initstate (unsigned int seed, char *arg_state, size_t n) { int32_t *ostate; - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); ostate = &unsafe_state.state[-1]; initstate_r (seed, arg_state, n, &unsafe_state); - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); return (char *) ostate; } @@ -227,11 +225,11 @@ char * setstate (char *arg_state) { int32_t *ostate; - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); ostate = &unsafe_state.state[-1]; if (setstate_r (arg_state, &unsafe_state) < 0) ostate = NULL; - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); return (char *) ostate; } @@ -251,9 +249,9 @@ long int random (void) { int32_t retval; - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); random_r (&unsafe_state, &retval); - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); return retval; } libc_hidden_def(random) diff --git a/libc/stdlib/realpath.c b/libc/stdlib/realpath.c index b28d6f07e..e9eabdfaa 100644 --- a/libc/stdlib/realpath.c +++ b/libc/stdlib/realpath.c @@ -21,9 +21,9 @@ #include <sys/stat.h> /* for S_IFLNK */ -libc_hidden_proto(strcat) -libc_hidden_proto(strcpy) -libc_hidden_proto(strlen) +/* Experimentally off - libc_hidden_proto(strcat) */ +/* Experimentally off - libc_hidden_proto(strcpy) */ +/* Experimentally off - libc_hidden_proto(strlen) */ libc_hidden_proto(readlink) libc_hidden_proto(getcwd) @@ -42,20 +42,23 @@ libc_hidden_proto(getcwd) #define MAX_READLINKS 32 #ifdef __STDC__ -char *realpath(const char *path, char resolved_path[]) +char *realpath(const char *path, char got_path[]) #else -char *realpath(path, resolved_path) +char *realpath(path, got_path) const char *path; -char resolved_path[]; +char got_path[]; #endif { char copy_path[PATH_MAX]; - char link_path[PATH_MAX]; - char got_path[PATH_MAX]; - char *new_path = got_path; + /* use user supplied buffer directly - reduces stack usage */ + /* char got_path[PATH_MAX]; */ char *max_path; + char *new_path; + size_t path_len; int readlinks = 0; - int n; +#ifdef S_IFLNK + int link_len; +#endif if (path == NULL) { __set_errno(EINVAL); @@ -66,17 +69,20 @@ char resolved_path[]; return NULL; } /* Make a copy of the source path since we may need to modify it. */ - if (strlen(path) >= PATH_MAX - 2) { + path_len = strlen(path); + if (path_len >= PATH_MAX - 2) { __set_errno(ENAMETOOLONG); return NULL; } - strcpy(copy_path, path); - path = copy_path; - max_path = copy_path + PATH_MAX - 2; - /* If it's a relative pathname use getcwd for starters. */ + /* Copy so that path is at the end of copy_path[] */ + strcpy(copy_path + (PATH_MAX-1) - path_len, path); + path = copy_path + (PATH_MAX-1) - path_len; + max_path = got_path + PATH_MAX - 2; /* points to last non-NUL char */ + new_path = got_path; if (*path != '/') { - /* Ohoo... */ - getcwd(new_path, PATH_MAX - 1); + /* If it's a relative pathname use getcwd for starters. */ + if (!getcwd(new_path, PATH_MAX - 1)) + return NULL; new_path += strlen(new_path); if (new_path[-1] != '/') *new_path++ = '/'; @@ -111,7 +117,7 @@ char resolved_path[]; } /* Safely copy the next pathname component. */ while (*path != '\0' && *path != '/') { - if (path > max_path) { + if (new_path > max_path) { __set_errno(ENAMETOOLONG); return NULL; } @@ -123,35 +129,36 @@ char resolved_path[]; __set_errno(ELOOP); return NULL; } - /* See if latest pathname component is a symlink. */ + path_len = strlen(path); + /* See if last (so far) pathname component is a symlink. */ *new_path = '\0'; - n = readlink(got_path, link_path, PATH_MAX - 1); - if (n < 0) { - /* EINVAL means the file exists but isn't a symlink. */ - if (errno != EINVAL) { - /* Make sure it's null terminated. */ - *new_path = '\0'; - strcpy(resolved_path, got_path); - return NULL; - } - } else { - /* Note: readlink doesn't add the null byte. */ - link_path[n] = '\0'; - if (*link_path == '/') - /* Start over for an absolute symlink. */ - new_path = got_path; - else - /* Otherwise back up over this component. */ - while (*(--new_path) != '/'); - /* Safe sex check. */ - if (strlen(path) + n >= PATH_MAX - 2) { - __set_errno(ENAMETOOLONG); - return NULL; + { + int sv_errno = errno; + link_len = readlink(got_path, copy_path, PATH_MAX - 1); + if (link_len < 0) { + /* EINVAL means the file exists but isn't a symlink. */ + if (errno != EINVAL) { + return NULL; + } + } else { + /* Safe sex check. */ + if (path_len + link_len >= PATH_MAX - 2) { + __set_errno(ENAMETOOLONG); + return NULL; + } + /* Note: readlink doesn't add the null byte. */ + /* copy_path[link_len] = '\0'; - we don't need it too */ + if (*copy_path == '/') + /* Start over for an absolute symlink. */ + new_path = got_path; + else + /* Otherwise back up over this component. */ + while (*(--new_path) != '/'); + /* Prepend symlink contents to path. */ + memmove(copy_path + (PATH_MAX-1) - link_len - path_len, copy_path, link_len); + path = copy_path + (PATH_MAX-1) - link_len - path_len; } - /* Insert symlink contents into path. */ - strcat(link_path, path); - strcpy(copy_path, link_path); - path = copy_path; + __set_errno(sv_errno); } #endif /* S_IFLNK */ *new_path++ = '/'; @@ -161,6 +168,5 @@ char resolved_path[]; new_path--; /* Make sure it's null terminated. */ *new_path = '\0'; - strcpy(resolved_path, got_path); - return resolved_path; + return got_path; } diff --git a/libc/stdlib/seed48_r.c b/libc/stdlib/seed48_r.c index c88d0f23e..3769e0fa7 100644 --- a/libc/stdlib/seed48_r.c +++ b/libc/stdlib/seed48_r.c @@ -21,7 +21,7 @@ #include <string.h> #include <limits.h> -libc_hidden_proto(memcpy) +/* Experimentally off - libc_hidden_proto(memcpy) */ libc_hidden_proto(seed48_r) int seed48_r (unsigned short int seed16v[3], struct drand48_data *buffer) diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c index b2d807b50..833bd8fcd 100644 --- a/libc/stdlib/setenv.c +++ b/libc/stdlib/setenv.c @@ -14,10 +14,10 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. - + 02111-1307 USA. + modified for uClibc by Erik Andersen <andersen@codepoet.org> - */ +*/ #include <features.h> #include <errno.h> @@ -25,20 +25,15 @@ #include <string.h> #include <unistd.h> -libc_hidden_proto(memcpy) -libc_hidden_proto(strchr) -libc_hidden_proto(strlen) -libc_hidden_proto(strncmp) -libc_hidden_proto(strndup) +/* Experimentally off - libc_hidden_proto(memcpy) */ +/* Experimentally off - libc_hidden_proto(strchr) */ +/* Experimentally off - libc_hidden_proto(strlen) */ +/* Experimentally off - libc_hidden_proto(strncmp) */ +/* Experimentally off - libc_hidden_proto(strndup) */ libc_hidden_proto(unsetenv) -#ifdef __UCLIBC_HAS_THREADS__ -# include <pthread.h> -# include <pthreadP.h> -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include <bits/uClibc_mutex.h> +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); /* If this variable is not a null pointer we allocated the current @@ -52,17 +47,18 @@ static char **last_environ; must be used directly. This is all complicated by the fact that we try to reuse values once generated for a `setenv' call since we can never free the strings. */ -int __add_to_environ (const char *name, const char *value, +int __add_to_environ (const char *name, const char *value, const char *combined, int replace) attribute_hidden; -int __add_to_environ (const char *name, const char *value, - const char *combined, int replace) +int __add_to_environ (const char *name, const char *value, + const char *combined, int replace) { register char **ep; register size_t size; const size_t namelen = strlen (name); const size_t vallen = value != NULL ? strlen (value) + 1 : 0; + int rv = -1; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); /* We have to get the pointer now that we have the lock and not earlier since another thread might have created a new environment. */ @@ -70,72 +66,71 @@ int __add_to_environ (const char *name, const char *value, size = 0; if (ep != NULL) { - for (; *ep != NULL; ++ep) { - if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') - break; - else - ++size; - } + for (; *ep != NULL; ++ep) { + if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') + break; + else + ++size; + } } if (ep == NULL || *ep == NULL) { - char **new_environ; - - /* We allocated this space; we can extend it. */ - new_environ = (char **) realloc (last_environ, - (size + 2) * sizeof (char *)); - if (new_environ == NULL) { - UNLOCK; - return -1; - } - - /* If the whole entry is given add it. */ - if (combined != NULL) { - /* We must not add the string to the search tree since it belongs - to the user. */ - new_environ[size] = (char *) combined; - } else { - /* See whether the value is already known. */ - new_environ[size] = (char *) malloc (namelen + 1 + vallen); - if (new_environ[size] == NULL) { - __set_errno (ENOMEM); - UNLOCK; - return -1; - } - - memcpy (new_environ[size], name, namelen); - new_environ[size][namelen] = '='; - memcpy (&new_environ[size][namelen + 1], value, vallen); - } - - if (__environ != last_environ) { - memcpy ((char *) new_environ, (char *) __environ, - size * sizeof (char *)); - } - - new_environ[size + 1] = NULL; - last_environ = __environ = new_environ; + char **new_environ; + + /* We allocated this space; we can extend it. */ + new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *)); + if (new_environ == NULL) { + goto DONE; + } + + /* If the whole entry is given add it. */ + if (combined != NULL) { + /* We must not add the string to the search tree since it belongs + to the user. */ + new_environ[size] = (char *) combined; + } else { + /* See whether the value is already known. */ + new_environ[size] = (char *) malloc (namelen + 1 + vallen); + if (new_environ[size] == NULL) { + __set_errno (ENOMEM); + goto DONE; + } + + memcpy (new_environ[size], name, namelen); + new_environ[size][namelen] = '='; + memcpy (&new_environ[size][namelen + 1], value, vallen); + } + + if (__environ != last_environ) { + memcpy ((char *) new_environ, (char *) __environ, + size * sizeof (char *)); + } + + new_environ[size + 1] = NULL; + last_environ = __environ = new_environ; } else if (replace) { - char *np; - - /* Use the user string if given. */ - if (combined != NULL) { - np = (char *) combined; - } else { - np = malloc (namelen + 1 + vallen); - if (np == NULL) { - UNLOCK; - return -1; - } - memcpy (np, name, namelen); - np[namelen] = '='; - memcpy (&np[namelen + 1], value, vallen); - } - *ep = np; + char *np; + + /* Use the user string if given. */ + if (combined != NULL) { + np = (char *) combined; + } else { + np = malloc (namelen + 1 + vallen); + if (np == NULL) { + goto DONE; + } + memcpy (np, name, namelen); + np[namelen] = '='; + memcpy (&np[namelen + 1], value, vallen); + } + *ep = np; } - UNLOCK; - return 0; + rv = 0; + + DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); + return rv; } libc_hidden_proto(setenv) @@ -152,26 +147,26 @@ int unsetenv (const char *name) char **ep; if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) { - __set_errno (EINVAL); - return -1; + __set_errno (EINVAL); + return -1; } len = strlen (name); - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); ep = __environ; while (*ep != NULL) { - if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { - /* Found it. Remove this pointer by moving later ones back. */ - char **dp = ep; - do { - dp[0] = dp[1]; - } while (*dp++); - /* Continue the loop in case NAME appears again. */ - } else { - ++ep; - } + if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { + /* Found it. Remove this pointer by moving later ones back. */ + char **dp = ep; + do { + dp[0] = dp[1]; + } while (*dp++); + /* Continue the loop in case NAME appears again. */ + } else { + ++ep; + } } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return 0; } libc_hidden_def(unsetenv) @@ -181,15 +176,15 @@ libc_hidden_def(unsetenv) for Fortran 77) requires this function. */ int clearenv (void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (__environ == last_environ && __environ != NULL) { - /* We allocated this environment so we can free it. */ - free (__environ); - last_environ = NULL; + /* We allocated this environment so we can free it. */ + free (__environ); + last_environ = NULL; } /* Clear the environment pointer removes the whole environment. */ __environ = NULL; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return 0; } @@ -200,10 +195,10 @@ int putenv (char *string) const char *const name_end = strchr (string, '='); if (name_end != NULL) { - char *name = strndup(string, name_end - string); - result = __add_to_environ (name, NULL, string, 1); - free(name); - return(result); + char *name = strndup(string, name_end - string); + result = __add_to_environ (name, NULL, string, 1); + free(name); + return(result); } unsetenv (string); return 0; diff --git a/libc/stdlib/stdlib.c b/libc/stdlib/stdlib.c index ccd3c015d..a864dd574 100644 --- a/libc/stdlib/stdlib.c +++ b/libc/stdlib/stdlib.c @@ -34,6 +34,7 @@ #define _ISOC99_SOURCE /* for ULLONG primarily... */ #include <limits.h> +#include <stdint.h> /* Work around gcc's refusal to create aliases. * TODO: Add in a define to disable the aliases? */ @@ -327,9 +328,9 @@ long long atoll(const char *nptr) libc_hidden_proto(__XL_NPP(strtol)) long __XL_NPP(strtol)(const char * __restrict str, char ** __restrict endptr, - int base __LOCALE_PARAM ) + int base __LOCALE_PARAM) { - return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1 __LOCALE_ARG ); + return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 1 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(strtol)) @@ -358,10 +359,9 @@ libc_hidden_def(__XL_NPP(strtoll)) libc_hidden_proto(__XL_NPP(strtoll)) long long __XL_NPP(strtoll)(const char * __restrict str, char ** __restrict endptr, int base - __LOCALE_PARAM ) + __LOCALE_PARAM) { - return (long long) __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 1 - __LOCALE_ARG ); + return (long long) __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 1 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(strtoll)) @@ -381,9 +381,9 @@ strong_alias(strtoll,strtoq) libc_hidden_proto(__XL_NPP(strtoul)) unsigned long __XL_NPP(strtoul)(const char * __restrict str, char ** __restrict endptr, int base - __LOCALE_PARAM ) + __LOCALE_PARAM) { - return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0 __LOCALE_ARG ); + return __XL_NPP(_stdlib_strto_l)(str, endptr, base, 0 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(strtoul)) @@ -413,9 +413,9 @@ libc_hidden_def(__XL_NPP(strtoull)) libc_hidden_proto(__XL_NPP(strtoull)) unsigned long long __XL_NPP(strtoull)(const char * __restrict str, char ** __restrict endptr, int base - __LOCALE_PARAM ) + __LOCALE_PARAM) { - return __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 0 __LOCALE_ARG ); + return __XL_NPP(_stdlib_strto_ll)(str, endptr, base, 0 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(strtoull)) @@ -502,39 +502,39 @@ unsigned long attribute_hidden _stdlib_strto_l(register const Wchar * __restrict #ifdef __UCLIBC_HAS_XLOCALE__ libc_hidden_proto(__ctype_b_loc) -#elif __UCLIBC_HAS_CTYPE_TABLES__ +#elif defined __UCLIBC_HAS_CTYPE_TABLES__ libc_hidden_proto(__ctype_b) #endif unsigned long attribute_hidden __XL_NPP(_stdlib_strto_l)(register const Wchar * __restrict str, Wchar ** __restrict endptr, int base, - int sflag __LOCALE_PARAM ) + int sflag __LOCALE_PARAM) { - unsigned long number, cutoff; + unsigned long number, cutoff; #if _STRTO_ENDPTR - const Wchar *fail_char; -#define SET_FAIL(X) fail_char = (X) + const Wchar *fail_char; +#define SET_FAIL(X) fail_char = (X) #else -#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */ +#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */ #endif - unsigned char negative, digit, cutoff_digit; + unsigned char negative, digit, cutoff_digit; assert(((unsigned int)sflag) <= 1); SET_FAIL(str); - while (ISSPACE(*str)) { /* Skip leading whitespace. */ + while (ISSPACE(*str)) { /* Skip leading whitespace. */ ++str; - } + } - /* Handle optional sign. */ - negative = 0; - switch(*str) { + /* Handle optional sign. */ + negative = 0; + switch (*str) { case '-': negative = 1; /* Fall through to increment str. */ case '+': ++str; - } + } - if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */ + if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */ base += 10; /* Default is 10 (26). */ if (*str == '0') { SET_FAIL(++str); @@ -548,19 +548,19 @@ unsigned long attribute_hidden __XL_NPP(_stdlib_strto_l)(register const Wchar * if (base > 16) { /* Adjust in case base wasn't dynamic. */ base = 16; } - } + } number = 0; - if (((unsigned)(base - 2)) < 35) { /* Legal base. */ + if (((unsigned)(base - 2)) < 35) { /* Legal base. */ cutoff_digit = ULONG_MAX % base; cutoff = ULONG_MAX / base; do { - digit = (((Wuchar)(*str - '0')) <= 9) - ? (*str - '0') - : ((*str >= 'A') - ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */ - : 40); + digit = ((Wuchar)(*str - '0') <= 9) + ? /* 0..9 */ (*str - '0') + : /* else */ (((Wuchar)(0x20 | *str) >= 'a') /* WARNING: assumes ascii. */ + ? /* >= A/a */ ((Wuchar)(0x20 | *str) - ('a' - 10)) + : /* else */ 40 /* bad value */); if (digit >= base) { break; @@ -580,13 +580,13 @@ unsigned long attribute_hidden __XL_NPP(_stdlib_strto_l)(register const Wchar * } #if _STRTO_ENDPTR - if (endptr) { + if (endptr) { *endptr = (Wchar *) fail_char; - } + } #endif { - unsigned long tmp = ((negative) + unsigned long tmp = (negative ? ((unsigned long)(-(1+LONG_MIN)))+1 : LONG_MAX); if (sflag && (number > tmp)) { @@ -660,34 +660,34 @@ libc_hidden_proto(__ctype_b) unsigned long long attribute_hidden __XL_NPP(_stdlib_strto_ll)(register const Wchar * __restrict str, Wchar ** __restrict endptr, int base, - int sflag __LOCALE_PARAM ) + int sflag __LOCALE_PARAM) { - unsigned long long number; + unsigned long long number; #if _STRTO_ENDPTR - const Wchar *fail_char; -#define SET_FAIL(X) fail_char = (X) + const Wchar *fail_char; +#define SET_FAIL(X) fail_char = (X) #else -#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */ +#define SET_FAIL(X) ((void)(X)) /* Keep side effects. */ #endif unsigned int n1; - unsigned char negative, digit; + unsigned char negative, digit; assert(((unsigned int)sflag) <= 1); SET_FAIL(str); - while (ISSPACE(*str)) { /* Skip leading whitespace. */ + while (ISSPACE(*str)) { /* Skip leading whitespace. */ ++str; - } + } - /* Handle optional sign. */ - negative = 0; - switch(*str) { + /* Handle optional sign. */ + negative = 0; + switch (*str) { case '-': negative = 1; /* Fall through to increment str. */ case '+': ++str; - } + } - if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */ + if (!(base & ~0x10)) { /* Either dynamic (base = 0) or base 16. */ base += 10; /* Default is 10 (26). */ if (*str == '0') { SET_FAIL(++str); @@ -701,17 +701,17 @@ unsigned long long attribute_hidden __XL_NPP(_stdlib_strto_ll)(register const Wc if (base > 16) { /* Adjust in case base wasn't dynamic. */ base = 16; } - } + } number = 0; - if (((unsigned)(base - 2)) < 35) { /* Legal base. */ + if (((unsigned)(base - 2)) < 35) { /* Legal base. */ do { - digit = (((Wuchar)(*str - '0')) <= 9) - ? (*str - '0') - : ((*str >= 'A') - ? (((0x20|(*str)) - 'a' + 10)) /* WARNING: assumes ascii. */ - : 40); + digit = ((Wuchar)(*str - '0') <= 9) + ? /* 0..9 */ (*str - '0') + : /* else */ (((Wuchar)(0x20 | *str) >= 'a') /* WARNING: assumes ascii. */ + ? /* >= A/a */ ((Wuchar)(0x20 | *str) - ('a' - 10)) + : /* else */ 40 /* bad value */); if (digit >= base) { break; @@ -742,9 +742,9 @@ unsigned long long attribute_hidden __XL_NPP(_stdlib_strto_ll)(register const Wc } #if _STRTO_ENDPTR - if (endptr) { + if (endptr) { *endptr = (Wchar *) fail_char; - } + } #endif { @@ -817,16 +817,16 @@ void *bsearch(const void *key, const void *base, size_t /* nmemb */ high, * bcc and gcc. */ libc_hidden_proto(qsort) -void qsort (void *base, - size_t nel, - size_t width, - int (*comp)(const void *, const void *)) +void qsort(void *base, + size_t nel, + size_t width, + int (*comp)(const void *, const void *)) { size_t wgap, i, j, k; char tmp; if ((nel > 1) && (width > 0)) { - assert( nel <= ((size_t)(-1)) / width ); /* check for overflow */ + assert(nel <= ((size_t)(-1)) / width); /* check for overflow */ wgap = 0; do { wgap = 3 * wgap + 1; @@ -846,7 +846,7 @@ void qsort (void *base, j -= wgap; a = j + ((char *)base); b = a + wgap; - if ( (*comp)(a, b) <= 0 ) { + if ((*comp)(a, b) <= 0) { break; } k = width; @@ -854,7 +854,7 @@ void qsort (void *base, tmp = *a; *a++ = *b; *b++ = tmp; - } while ( --k ); + } while (--k); } while (j >= wgap); i += width; } while (i < nel); @@ -875,40 +875,36 @@ libc_hidden_def(qsort) #include <stddef.h> -void ssort (void *base, - size_t nel, - size_t width, - int (*comp)(const void *, const void *)) +void ssort(void *base, + size_t nel, + size_t width, + int (*comp)(const void *, const void *)) { - size_t wnel, gap, wgap, i, j, k; - char *a, *b, tmp; - - wnel = width * nel; - for (gap = 0; ++gap < nel;) - gap *= 3; - while ( gap /= 3 ) - { - wgap = width * gap; - for (i = wgap; i < wnel; i += width) - { - for (j = i - wgap; ;j -= wgap) - { - a = j + (char *)base; - b = a + wgap; - if ( (*comp)(a, b) <= 0 ) - break; - k = width; - do - { - tmp = *a; - *a++ = *b; - *b++ = tmp; - } while ( --k ); - if (j < wgap) - break; - } - } - } + size_t wnel, gap, wgap, i, j, k; + char *a, *b, tmp; + + wnel = width * nel; + for (gap = 0; ++gap < nel;) + gap *= 3; + while ((gap /= 3) != 0) { + wgap = width * gap; + for (i = wgap; i < wnel; i += width) { + for (j = i - wgap; ;j -= wgap) { + a = j + (char *)base; + b = a + wgap; + if ((*comp)(a, b) <= 0) + break; + k = width; + do { + tmp = *a; + *a++ = *b; + *b++ = tmp; + } while (--k); + if (j < wgap) + break; + } + } + } } #endif @@ -933,6 +929,31 @@ size_t _stdlib_mb_cur_max(void) libc_hidden_def(_stdlib_mb_cur_max) #endif + +#ifdef __UCLIBC_HAS_LOCALE__ +/* + * The following function return 1 if the encoding is stateful, 0 if stateless. + * To note, until now all the supported encoding are stateless. + */ + +static inline int +is_stateful(unsigned char encoding) +{ + switch (encoding) + { + case __ctype_encoding_7_bit: + case __ctype_encoding_utf8: + case __ctype_encoding_8_bit: + return 0; + default: + assert(0); + return -1; + } +} +#else +#define is_stateful(encoding) 0 +#endif + /**********************************************************************/ #ifdef L_mblen @@ -945,13 +966,16 @@ int mblen(register const char *s, size_t n) if (!s) { state.__mask = 0; -#ifdef __CTYPE_HAS_UTF_8_LOCALES - return ENCODING == __ctype_encoding_utf8; -#else - return 0; -#endif +/* In this case we have to return 0 because the only multibyte supported encoding + is utf-8, that is a stateless encoding. See mblen() documentation.*/ + + return is_stateful(ENCODING); } + if (*s == '\0') + /* According to the ISO C 89 standard this is the expected behaviour. */ + return 0; + if ((r = mbrlen(s, n, &state)) == (size_t) -2) { /* TODO: Should we set an error state? */ state.__wc = 0xffffU; /* Make sure we're in an error state. */ @@ -973,13 +997,16 @@ int mbtowc(wchar_t *__restrict pwc, register const char *__restrict s, size_t n) if (!s) { state.__mask = 0; -#ifdef __CTYPE_HAS_UTF_8_LOCALES - return ENCODING == __ctype_encoding_utf8; -#else - return 0; -#endif +/* In this case we have to return 0 because the only multibyte supported encoding + is utf-8, that is a stateless encoding. See mbtowc() documentation.*/ + + return is_stateful(ENCODING); } + if (*s == '\0') + /* According to the ISO C 89 standard this is the expected behaviour. */ + return 0; + if ((r = mbrtowc(pwc, s, n, &state)) == (size_t) -2) { /* TODO: Should we set an error state? */ state.__wc = 0xffffU; /* Make sure we're in an error state. */ @@ -1000,11 +1027,10 @@ int wctomb(register char *__restrict s, wchar_t swc) { return (!s) ? -#ifdef __CTYPE_HAS_UTF_8_LOCALES - (ENCODING == __ctype_encoding_utf8) -#else - 0 /* Encoding is stateless. */ -#endif +/* In this case we have to return 0 because the only multibyte supported encoding + is utf-8, that is a stateless encoding. See wctomb() documentation.*/ + + is_stateful(ENCODING) : ((ssize_t) wcrtomb(s, swc, NULL)); } @@ -1044,9 +1070,9 @@ size_t wcstombs(char * __restrict s, const wchar_t * __restrict pwcs, size_t n) libc_hidden_proto(__XL_NPP(wcstol)) long __XL_NPP(wcstol)(const wchar_t * __restrict str, - wchar_t ** __restrict endptr, int base __LOCALE_PARAM ) + wchar_t ** __restrict endptr, int base __LOCALE_PARAM) { - return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1 __LOCALE_ARG ); + return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 1 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(wcstol)) @@ -1075,10 +1101,9 @@ libc_hidden_def(__XL_NPP(wcstoll)) libc_hidden_proto(__XL_NPP(wcstoll)) long long __XL_NPP(wcstoll)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base - __LOCALE_PARAM ) + __LOCALE_PARAM) { - return (long long) __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 1 - __LOCALE_ARG ); + return (long long) __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 1 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(wcstoll)) @@ -1098,9 +1123,9 @@ strong_alias(wcstoll,wcstoq) libc_hidden_proto(__XL_NPP(wcstoul)) unsigned long __XL_NPP(wcstoul)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base - __LOCALE_PARAM ) + __LOCALE_PARAM) { - return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0 __LOCALE_ARG ); + return __XL_NPP(_stdlib_wcsto_l)(str, endptr, base, 0 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(wcstoul)) @@ -1129,9 +1154,9 @@ libc_hidden_def(__XL_NPP(wcstoull)) libc_hidden_proto(__XL_NPP(wcstoull)) unsigned long long __XL_NPP(wcstoull)(const wchar_t * __restrict str, wchar_t ** __restrict endptr, int base - __LOCALE_PARAM ) + __LOCALE_PARAM) { - return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0 __LOCALE_ARG ); + return __XL_NPP(_stdlib_wcsto_ll)(str, endptr, base, 0 __LOCALE_ARG); } libc_hidden_def(__XL_NPP(wcstoull)) diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c index d1ff50f51..5b8feacf2 100644 --- a/libc/stdlib/system.c +++ b/libc/stdlib/system.c @@ -3,8 +3,6 @@ * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */ -#define SHELL_PATH "/bin/sh" /* Path of the shell. */ -#define SHELL_NAME "sh" /* Name to give it. */ #include <stdio.h> #include <stddef.h> @@ -57,7 +55,7 @@ int __libc_system(const char *command) signal(SIGINT, SIG_DFL); signal(SIGCHLD, SIG_DFL); - execl(SHELL_PATH, SHELL_NAME, "-c", command, (char *) 0); + execl("/bin/sh", "sh", "-c", command, (char *) 0); _exit(127); } /* Signals are not absolutly guarenteed with vfork */ @@ -180,7 +178,7 @@ do_system (const char *line) { /* Child side. */ const char *new_argv[4]; - new_argv[0] = SHELL_NAME; + new_argv[0] = "/bin/sh"; new_argv[1] = "-c"; new_argv[2] = line; new_argv[3] = NULL; @@ -192,7 +190,7 @@ do_system (const char *line) INIT_LOCK (); /* Exec the shell. */ - (void) execve (SHELL_PATH, (char *const *) new_argv, __environ); + (void) execve ("/bin/sh", (char *const *) new_argv, __environ); _exit (127); } else if (pid < (pid_t) 0) diff --git a/libc/stdlib/unix_grantpt.c b/libc/stdlib/unix_grantpt.c index f88a54bc0..d1eef9efd 100644 --- a/libc/stdlib/unix_grantpt.c +++ b/libc/stdlib/unix_grantpt.c @@ -30,7 +30,7 @@ #include <unistd.h> #include "pty-private.h" -libc_hidden_proto(memchr) +/* Experimentally off - libc_hidden_proto(memchr) */ libc_hidden_proto(getgid) libc_hidden_proto(getuid) libc_hidden_proto(setrlimit) |
