diff options
Diffstat (limited to 'toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch')
-rw-r--r-- | toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch | 8631 |
1 files changed, 0 insertions, 8631 deletions
diff --git a/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch b/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch deleted file mode 100644 index 5e56a7397..000000000 --- a/toolchain/uClibc/uClibc-0.9.28-500-mutex-cancel.patch +++ /dev/null @@ -1,8631 +0,0 @@ -diff --git a/include/printf.h b/include/printf.h -index 340b6cb..2dea58f 100644 ---- a/include/printf.h -+++ b/include/printf.h -@@ -75,6 +75,7 @@ struct printf_info - unsigned int is_short:1; /* h flag. */ - unsigned int is_long:1; /* l flag. */ - unsigned int is_long_double:1;/* L flag. */ -+ unsigned int __padding:20;/* non-gnu -- total of 32 bits on 32bit arch */ - - #elif __BYTE_ORDER == __BIG_ENDIAN - -diff --git a/include/pthread.h b/include/pthread.h -index 8c01172..cee112b 100644 ---- a/include/pthread.h -+++ b/include/pthread.h -@@ -644,7 +644,8 @@ extern void _pthread_cleanup_pop (struct - /* Install a cleanup handler as pthread_cleanup_push does, but also - saves the current cancellation type and set it to deferred cancellation. */ - --#ifdef __USE_GNU -+/* #ifdef __USE_GNU */ -+#if defined(__USE_GNU) || defined(_LIBC) - # define pthread_cleanup_push_defer_np(routine,arg) \ - { struct _pthread_cleanup_buffer _buffer; \ - _pthread_cleanup_push_defer (&_buffer, (routine), (arg)); -diff --git a/libc/inet/getnetent.c b/libc/inet/getnetent.c -index 181c5ad..659bf5d 100644 ---- a/libc/inet/getnetent.c -+++ b/libc/inet/getnetent.c -@@ -22,18 +22,9 @@ - #include <netdb.h> - #include <arpa/inet.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -- -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - #define MAXALIASES 35 - static const char NETDB[] = _PATH_NETWORKS; -@@ -46,25 +37,25 @@ int _net_stayopen; - - void setnetent(int f) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (netf == NULL) -- netf = fopen(NETDB, "r" ); -+ netf = fopen(NETDB, "r" ); - else -- rewind(netf); -+ rewind(netf); - _net_stayopen |= f; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return; - } - - void endnetent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (netf) { -- fclose(netf); -- netf = NULL; -+ fclose(netf); -+ netf = NULL; - } - _net_stayopen = 0; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - static char * any(register char *cp, char *match) -@@ -72,10 +63,10 @@ static char * any(register char *cp, cha - register char *mp, c; - - while ((c = *cp)) { -- for (mp = match; *mp; mp++) -- if (*mp == c) -- return (cp); -- cp++; -+ for (mp = match; *mp; mp++) -+ if (*mp == c) -+ return (cp); -+ cp++; - } - return ((char *)0); - } -@@ -84,59 +75,62 @@ struct netent * getnetent(void) - { - char *p; - register char *cp, **q; -+ struct netent *rv = NULL; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (netf == NULL && (netf = fopen(NETDB, "r" )) == NULL) { -- UNLOCK; -- return (NULL); -+ goto DONE; - } --again: -+ again: - - if (!line) { -- line = malloc(BUFSIZ + 1); -- if (!line) -- abort(); -+ line = malloc(BUFSIZ + 1); -+ if (!line) -+ abort(); - } - - p = fgets(line, BUFSIZ, netf); - if (p == NULL) { -- UNLOCK; -- return (NULL); -+ goto DONE; - } - if (*p == '#') -- goto again; -+ goto again; - cp = any(p, "#\n"); - if (cp == NULL) -- goto again; -+ goto again; - *cp = '\0'; - net.n_name = p; - cp = any(p, " \t"); - if (cp == NULL) -- goto again; -+ goto again; - *cp++ = '\0'; - while (*cp == ' ' || *cp == '\t') -- cp++; -+ cp++; - p = any(cp, " \t"); - if (p != NULL) -- *p++ = '\0'; -+ *p++ = '\0'; - net.n_net = inet_network(cp); - net.n_addrtype = AF_INET; - q = net.n_aliases = net_aliases; - if (p != NULL) -- cp = p; -+ cp = p; - while (cp && *cp) { -- if (*cp == ' ' || *cp == '\t') { -- cp++; -- continue; -- } -- if (q < &net_aliases[MAXALIASES - 1]) -- *q++ = cp; -- cp = any(cp, " \t"); -- if (cp != NULL) -- *cp++ = '\0'; -+ if (*cp == ' ' || *cp == '\t') { -+ cp++; -+ continue; -+ } -+ if (q < &net_aliases[MAXALIASES - 1]) -+ *q++ = cp; -+ cp = any(cp, " \t"); -+ if (cp != NULL) -+ *cp++ = '\0'; - } - *q = NULL; -- UNLOCK; -- return (&net); -+ -+ rv = &net; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - -diff --git a/libc/inet/getproto.c b/libc/inet/getproto.c -index c9f35f1..3665d89 100644 ---- a/libc/inet/getproto.c -+++ b/libc/inet/getproto.c -@@ -62,17 +62,9 @@ - #include <string.h> - #include <errno.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -+#include <bits/uClibc_mutex.h> - -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - #define MAXALIASES 35 - #define SBUFSIZE (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES)) -@@ -85,109 +77,114 @@ static int proto_stayopen; - static void __initbuf(void) - { - if (!static_aliases) { -- static_aliases = malloc(SBUFSIZE); -- if (!static_aliases) -- abort(); -+ static_aliases = malloc(SBUFSIZE); -+ if (!static_aliases) -+ abort(); - } - } - - void setprotoent(int f) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (protof == NULL) -- protof = fopen(_PATH_PROTOCOLS, "r" ); -+ protof = fopen(_PATH_PROTOCOLS, "r" ); - else -- rewind(protof); -+ rewind(protof); - proto_stayopen |= f; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endprotoent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (protof) { -- fclose(protof); -- protof = NULL; -+ fclose(protof); -+ protof = NULL; - } - proto_stayopen = 0; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int getprotoent_r(struct protoent *result_buf, -- char *buf, size_t buflen, -- struct protoent **result) -+ char *buf, size_t buflen, -+ struct protoent **result) - { - char *p; - register char *cp, **q; - char **proto_aliases; - char *line; -+ int rv; - - *result = NULL; - - if (buflen < sizeof(*proto_aliases)*MAXALIASES) { -- errno=ERANGE; -- return errno; -+ errno=ERANGE; -+ return errno; - } -- LOCK; -+ -+ __UCLIBC_MUTEX_LOCK(mylock); - proto_aliases=(char **)buf; - buf+=sizeof(*proto_aliases)*MAXALIASES; - buflen-=sizeof(*proto_aliases)*MAXALIASES; - - if (buflen < BUFSIZ+1) { -- UNLOCK; -- errno=ERANGE; -- return errno; -+ errno=rv=ERANGE; -+ goto DONE; - } - line=buf; - buf+=BUFSIZ+1; - buflen-=BUFSIZ+1; - - if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) { -- UNLOCK; -- return errno; -+ rv=errno; -+ goto DONE; - } --again: -+ again: - if ((p = fgets(line, BUFSIZ, protof)) == NULL) { -- UNLOCK; -- return TRY_AGAIN; -+ rv=TRY_AGAIN; -+ goto DONE; - } - - if (*p == '#') -- goto again; -+ goto again; - cp = strpbrk(p, "#\n"); - if (cp == NULL) -- goto again; -+ goto again; - *cp = '\0'; - result_buf->p_name = p; - cp = strpbrk(p, " \t"); - if (cp == NULL) -- goto again; -+ goto again; - *cp++ = '\0'; - while (*cp == ' ' || *cp == '\t') -- cp++; -+ cp++; - p = strpbrk(cp, " \t"); - if (p != NULL) -- *p++ = '\0'; -+ *p++ = '\0'; - result_buf->p_proto = atoi(cp); - q = result_buf->p_aliases = proto_aliases; - if (p != NULL) { -- cp = p; -- while (cp && *cp) { -- if (*cp == ' ' || *cp == '\t') { -- cp++; -- continue; -- } -- if (q < &proto_aliases[MAXALIASES - 1]) -- *q++ = cp; -- cp = strpbrk(cp, " \t"); -- if (cp != NULL) -- *cp++ = '\0'; -- } -+ cp = p; -+ while (cp && *cp) { -+ if (*cp == ' ' || *cp == '\t') { -+ cp++; -+ continue; -+ } -+ if (q < &proto_aliases[MAXALIASES - 1]) -+ *q++ = cp; -+ cp = strpbrk(cp, " \t"); -+ if (cp != NULL) -+ *cp++ = '\0'; -+ } - } - *q = NULL; - *result=result_buf; -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - struct protoent * getprotoent(void) -@@ -201,26 +198,26 @@ struct protoent * getprotoent(void) - - - int getprotobyname_r(const char *name, -- struct protoent *result_buf, -- char *buf, size_t buflen, -- struct protoent **result) -+ struct protoent *result_buf, -+ char *buf, size_t buflen, -+ struct protoent **result) - { - register char **cp; - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setprotoent(proto_stayopen); - while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) { -- if (strcmp(result_buf->p_name, name) == 0) -- break; -- for (cp = result_buf->p_aliases; *cp != 0; cp++) -- if (strcmp(*cp, name) == 0) -- goto found; -+ if (strcmp(result_buf->p_name, name) == 0) -+ break; -+ for (cp = result_buf->p_aliases; *cp != 0; cp++) -+ if (strcmp(*cp, name) == 0) -+ goto found; - } --found: -+ found: - if (!proto_stayopen) -- endprotoent(); -- UNLOCK; -+ endprotoent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } - -@@ -236,20 +233,20 @@ struct protoent * getprotobyname(const c - - - int getprotobynumber_r (int proto_num, -- struct protoent *result_buf, -- char *buf, size_t buflen, -- struct protoent **result) -+ struct protoent *result_buf, -+ char *buf, size_t buflen, -+ struct protoent **result) - { - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setprotoent(proto_stayopen); - while (!(ret=getprotoent_r(result_buf, buf, buflen, result))) -- if (result_buf->p_proto == proto_num) -- break; -+ if (result_buf->p_proto == proto_num) -+ break; - if (!proto_stayopen) -- endprotoent(); -- UNLOCK; -+ endprotoent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } - -diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c -index cbe5c50..b666057 100644 ---- a/libc/inet/getservice.c -+++ b/libc/inet/getservice.c -@@ -65,20 +65,9 @@ - #include <arpa/inet.h> - #include <errno.h> - -+#include <bits/uClibc_mutex.h> - -- --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -- -- -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - #define MAXALIASES 35 - #define SBUFSIZE (BUFSIZ + 1 + (sizeof(char *) * MAXALIASES)) -@@ -91,32 +80,32 @@ static int serv_stayopen; - static void __initbuf(void) - { - if (!servbuf) { -- servbuf = malloc(SBUFSIZE); -- if (!servbuf) -- abort(); -+ servbuf = malloc(SBUFSIZE); -+ if (!servbuf) -+ abort(); - } - } - - void setservent(int f) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (servf == NULL) -- servf = fopen(_PATH_SERVICES, "r" ); -+ servf = fopen(_PATH_SERVICES, "r" ); - else -- rewind(servf); -+ rewind(servf); - serv_stayopen |= f; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endservent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (servf) { -- fclose(servf); -- servf = NULL; -+ fclose(servf); -+ servf = NULL; - } - serv_stayopen = 0; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - struct servent * getservent(void) -@@ -149,127 +138,129 @@ struct servent * getservbyport(int port, - } - - int getservent_r(struct servent * result_buf, -- char * buf, size_t buflen, -- struct servent ** result) -+ char * buf, size_t buflen, -+ struct servent ** result) - { - char *p; - register char *cp, **q; - char **serv_aliases; - char *line; -+ int rv; - - *result=NULL; - - if (buflen < sizeof(*serv_aliases)*MAXALIASES) { -- errno=ERANGE; -- return errno; -+ errno=ERANGE; -+ return errno; - } -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - serv_aliases=(char **)buf; - buf+=sizeof(*serv_aliases)*MAXALIASES; - buflen-=sizeof(*serv_aliases)*MAXALIASES; - - if (buflen < BUFSIZ+1) { -- UNLOCK; -- errno=ERANGE; -- return errno; -+ errno=rv=ERANGE; -+ goto DONE; - } - line=buf; - buf+=BUFSIZ+1; - buflen-=BUFSIZ+1; - - if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) { -- UNLOCK; -- errno=EIO; -- return errno; -+ errno=rv=EIO; -+ goto DONE; - } --again: -+ again: - if ((p = fgets(line, BUFSIZ, servf)) == NULL) { -- UNLOCK; -- errno=EIO; -- return errno; -+ errno=rv=EIO; -+ goto DONE; - } - if (*p == '#') -- goto again; -+ goto again; - cp = strpbrk(p, "#\n"); - if (cp == NULL) -- goto again; -+ goto again; - *cp = '\0'; - result_buf->s_name = p; - p = strpbrk(p, " \t"); - if (p == NULL) -- goto again; -+ goto again; - *p++ = '\0'; - while (*p == ' ' || *p == '\t') -- p++; -+ p++; - cp = strpbrk(p, ",/"); - if (cp == NULL) -- goto again; -+ goto again; - *cp++ = '\0'; - result_buf->s_port = htons((u_short)atoi(p)); - result_buf->s_proto = cp; - q = result_buf->s_aliases = serv_aliases; - cp = strpbrk(cp, " \t"); - if (cp != NULL) -- *cp++ = '\0'; -+ *cp++ = '\0'; - while (cp && *cp) { -- if (*cp == ' ' || *cp == '\t') { -- cp++; -- continue; -- } -- if (q < &serv_aliases[MAXALIASES - 1]) -- *q++ = cp; -- cp = strpbrk(cp, " \t"); -- if (cp != NULL) -- *cp++ = '\0'; -+ if (*cp == ' ' || *cp == '\t') { -+ cp++; -+ continue; -+ } -+ if (q < &serv_aliases[MAXALIASES - 1]) -+ *q++ = cp; -+ cp = strpbrk(cp, " \t"); -+ if (cp != NULL) -+ *cp++ = '\0'; - } - *q = NULL; - *result=result_buf; -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - int getservbyname_r(const char *name, const char *proto, -- struct servent * result_buf, char * buf, size_t buflen, -- struct servent ** result) -+ struct servent * result_buf, char * buf, size_t buflen, -+ struct servent ** result) - { - register char **cp; - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setservent(serv_stayopen); - while (!(ret=getservent_r(result_buf, buf, buflen, result))) { -- if (strcmp(name, result_buf->s_name) == 0) -- goto gotname; -- for (cp = result_buf->s_aliases; *cp; cp++) -- if (strcmp(name, *cp) == 0) -- goto gotname; -- continue; --gotname: -- if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -- break; -+ if (strcmp(name, result_buf->s_name) == 0) -+ goto gotname; -+ for (cp = result_buf->s_aliases; *cp; cp++) -+ if (strcmp(name, *cp) == 0) -+ goto gotname; -+ continue; -+ gotname: -+ if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -+ break; - } - if (!serv_stayopen) -- endservent(); -- UNLOCK; -+ endservent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } - - int getservbyport_r(int port, const char *proto, -- struct servent * result_buf, char * buf, -- size_t buflen, struct servent ** result) -+ struct servent * result_buf, char * buf, -+ size_t buflen, struct servent ** result) - { - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - setservent(serv_stayopen); - while (!(ret=getservent_r(result_buf, buf, buflen, result))) { -- if (result_buf->s_port != port) -- continue; -- if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -- break; -+ if (result_buf->s_port != port) -+ continue; -+ if (proto == 0 || strcmp(result_buf->s_proto, proto) == 0) -+ break; - } - if (!serv_stayopen) -- endservent(); -- UNLOCK; -+ endservent(); -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return *result?0:ret; - } -diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c -index 27b60ef..0f583ab 100644 ---- a/libc/inet/resolv.c -+++ b/libc/inet/resolv.c -@@ -7,7 +7,7 @@ - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. --*/ -+ */ - - /* - * Portions Copyright (c) 1985, 1993 -@@ -153,6 +153,11 @@ - #include <sys/utsname.h> - #include <sys/un.h> - -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_EXTERN(__resolv_lock); -+ -+ - #define MAX_RECURSE 5 - #define REPLY_TIMEOUT 10 - #define MAX_RETRIES 3 -@@ -180,18 +185,6 @@ extern char * __nameserver[MAX_SERVERS]; - extern int __searchdomains; - extern char * __searchdomain[MAX_SEARCH]; - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --extern pthread_mutex_t __resolv_lock; --# define BIGLOCK __pthread_mutex_lock(&__resolv_lock) --# define BIGUNLOCK __pthread_mutex_unlock(&__resolv_lock); --#else --# define BIGLOCK --# define BIGUNLOCK --#endif -- -- -- - /* Structs */ - struct resolv_header { - int id; -@@ -229,49 +222,49 @@ enum etc_hosts_action { - - /* function prototypes */ - extern int __get_hosts_byname_r(const char * name, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop); -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop); - extern int __get_hosts_byaddr_r(const char * addr, int len, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop); -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop); - extern void __open_etc_hosts(FILE **fp); - extern int __read_etc_hosts_r(FILE *fp, const char * name, int type, -- enum etc_hosts_action action, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop); -+ enum etc_hosts_action action, -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop); - extern int __dns_lookup(const char * name, int type, int nscount, -- char ** nsip, unsigned char ** outpacket, struct resolv_answer * a); -+ char ** nsip, unsigned char ** outpacket, struct resolv_answer * a); - - extern int __encode_dotted(const char * dotted, unsigned char * dest, int maxlen); - extern int __decode_dotted(const unsigned char * message, int offset, -- char * dest, int maxlen); -+ char * dest, int maxlen); - extern int __length_dotted(const unsigned char * message, int offset); - extern int __encode_header(struct resolv_header * h, unsigned char * dest, int maxlen); - extern int __decode_header(unsigned char * data, struct resolv_header * h); - extern int __encode_question(struct resolv_question * q, -- unsigned char * dest, int maxlen); -+ unsigned char * dest, int maxlen); - extern int __decode_question(unsigned char * message, int offset, -- struct resolv_question * q); -+ struct resolv_question * q); - extern int __encode_answer(struct resolv_answer * a, -- unsigned char * dest, int maxlen); -+ unsigned char * dest, int maxlen); - extern int __decode_answer(unsigned char * message, int offset, -- struct resolv_answer * a); -+ struct resolv_answer * a); - extern int __length_question(unsigned char * message, int offset); - extern int __open_nameservers(void); - extern void __close_nameservers(void); - extern int __dn_expand(const u_char *, const u_char *, const u_char *, -- char *, int); -+ char *, int); - extern int __ns_name_uncompress(const u_char *, const u_char *, -- const u_char *, char *, size_t); -+ const u_char *, char *, size_t); - extern int __ns_name_ntop(const u_char *, char *, size_t); - extern int __ns_name_unpack(const u_char *, const u_char *, const u_char *, -- u_char *, size_t); -+ u_char *, size_t); - - - #ifdef L_encodeh -@@ -361,7 +354,7 @@ int __encode_dotted(const char *dotted, - This routine understands compressed data. */ - - int __decode_dotted(const unsigned char *data, int offset, -- char *dest, int maxlen) -+ char *dest, int maxlen) - { - int l; - int measure = 1; -@@ -435,7 +428,7 @@ int __length_dotted(const unsigned char - - #ifdef L_encodeq - int __encode_question(struct resolv_question *q, -- unsigned char *dest, int maxlen) -+ unsigned char *dest, int maxlen) - { - int i; - -@@ -460,7 +453,7 @@ int __encode_question(struct resolv_ques - - #ifdef L_decodeq - int __decode_question(unsigned char *message, int offset, -- struct resolv_question *q) -+ struct resolv_question *q) - { - char temp[256]; - int i; -@@ -525,7 +518,7 @@ int __encode_answer(struct resolv_answer - - #ifdef L_decodea - int __decode_answer(unsigned char *message, int offset, -- struct resolv_answer *a) -+ struct resolv_answer *a) - { - char temp[256]; - int i; -@@ -557,11 +550,11 @@ int __decode_answer(unsigned char *messa - - #ifdef L_encodep - int __encode_packet(struct resolv_header *h, -- struct resolv_question **q, -- struct resolv_answer **an, -- struct resolv_answer **ns, -- struct resolv_answer **ar, -- unsigned char *dest, int maxlen) -+ struct resolv_question **q, -+ struct resolv_answer **an, -+ struct resolv_answer **ns, -+ struct resolv_answer **ar, -+ unsigned char *dest, int maxlen) - { - int i, total = 0; - int j; -@@ -621,7 +614,7 @@ int __decode_packet(unsigned char *data, - - #ifdef L_formquery - int __form_query(int id, const char *name, int type, unsigned char *packet, -- int maxlen) -+ int maxlen) - { - struct resolv_header h; - struct resolv_question q; -@@ -649,14 +642,7 @@ int __form_query(int id, const char *nam - - #ifdef L_dnslookup - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* Just for the record, having to lock __dns_lookup() just for these two globals - * is pretty lame. I think these two variables can probably be de-global-ized, -@@ -665,7 +651,7 @@ static pthread_mutex_t mylock = PTHREAD_ - static int ns=0, id=1; - - int __dns_lookup(const char *name, int type, int nscount, char **nsip, -- unsigned char **outpacket, struct resolv_answer *a) -+ unsigned char **outpacket, struct resolv_answer *a) - { - int i, j, len, fd, pos, rc; - struct timeval tv; -@@ -693,10 +679,10 @@ int __dns_lookup(const char *name, int t - DPRINTF("Looking up type %d answer for '%s'\n", type, name); - - /* Mess with globals while under lock */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - local_ns = ns % nscount; - local_id = id; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - while (retries < MAX_RETRIES) { - if (fd != -1) -@@ -722,13 +708,13 @@ int __dns_lookup(const char *name, int t - - strncpy(lookup,name,MAXDNAME); - if (variant >= 0) { -- BIGLOCK; -- if (variant < __searchdomains) { -- strncat(lookup,".", MAXDNAME); -- strncat(lookup,__searchdomain[variant], MAXDNAME); -- } -- BIGUNLOCK; -- } -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); -+ if (variant < __searchdomains) { -+ strncat(lookup,".", MAXDNAME); -+ strncat(lookup,__searchdomain[variant], MAXDNAME); -+ } -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); -+ } - DPRINTF("lookup name: %s\n", lookup); - q.dotted = (char *)lookup; - q.qtype = type; -@@ -750,7 +736,7 @@ int __dns_lookup(const char *name, int t - fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - #endif - if (fd < 0) { -- retries++; -+ retries++; - continue; - } - -@@ -772,11 +758,11 @@ int __dns_lookup(const char *name, int t - #endif - if (rc < 0) { - if (errno == ENETUNREACH) { -- /* routing error, presume not transient */ -- goto tryall; -+ /* routing error, presume not transient */ -+ goto tryall; - } else -- /* retry */ -- retries++; -+ /* retry */ -+ retries++; - continue; - } - -@@ -838,55 +824,55 @@ int __dns_lookup(const char *name, int t - - first_answer = 1; - for (j=0;j<h.ancount;j++,pos += i) -- { -- i = __decode_answer(packet, pos, &ma); -+ { -+ i = __decode_answer(packet, pos, &ma); - -- if (i<0) { -- DPRINTF("failed decode %d\n", i); -- goto again; -- } -+ if (i<0) { -+ DPRINTF("failed decode %d\n", i); -+ goto again; -+ } - -- if ( first_answer ) -- { -- ma.buf = a->buf; -- ma.buflen = a->buflen; -- ma.add_count = a->add_count; -- memcpy(a, &ma, sizeof(ma)); -- if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA))) -- { -- break; -- } -- if (a->atype != type) -- { -- free(a->dotted); -- continue; -- } -- a->add_count = h.ancount - j - 1; -- if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) -- { -- break; -- } -- a->add_count = 0; -- first_answer = 0; -- } -- else -- { -- free(ma.dotted); -- if (ma.atype != type) -- { -- continue; -- } -- if (a->rdlength != ma.rdlength) -- { -- free(a->dotted); -- DPRINTF("Answer address len(%u) differs from original(%u)\n", -- ma.rdlength, a->rdlength); -- goto again; -+ if ( first_answer ) -+ { -+ ma.buf = a->buf; -+ ma.buflen = a->buflen; -+ ma.add_count = a->add_count; -+ memcpy(a, &ma, sizeof(ma)); -+ if (a->atype != T_SIG && (0 == a->buf || (type != T_A && type != T_AAAA))) -+ { -+ break; -+ } -+ if (a->atype != type) -+ { -+ free(a->dotted); -+ continue; -+ } -+ a->add_count = h.ancount - j - 1; -+ if ((a->rdlength + sizeof(struct in_addr*)) * a->add_count > a->buflen) -+ { -+ break; -+ } -+ a->add_count = 0; -+ first_answer = 0; -+ } -+ else -+ { -+ free(ma.dotted); -+ if (ma.atype != type) -+ { -+ continue; -+ } -+ if (a->rdlength != ma.rdlength) -+ { -+ free(a->dotted); -+ DPRINTF("Answer address len(%u) differs from original(%u)\n", -+ ma.rdlength, a->rdlength); -+ goto again; -+ } -+ memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength); -+ ++a->add_count; -+ } - } -- memcpy(a->buf + (a->add_count * ma.rdlength), ma.rdata, ma.rdlength); -- ++a->add_count; -- } -- } - - DPRINTF("Answer name = |%s|\n", a->dotted); - DPRINTF("Answer type = |%d|\n", a->atype); -@@ -900,48 +886,48 @@ int __dns_lookup(const char *name, int t - free(lookup); - - /* Mess with globals while under lock */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - ns = local_ns; - id = local_id; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return (len); /* success! */ - -- tryall: -+ tryall: - /* if there are other nameservers, give them a go, - otherwise return with error */ - { - variant = -1; -- local_ns = (local_ns + 1) % nscount; -- if (local_ns == 0) -- retries++; -+ local_ns = (local_ns + 1) % nscount; -+ if (local_ns == 0) -+ retries++; - -- continue; -+ continue; - } - -- again: -+ again: - /* if there are searchdomains, try them or fallback as passed */ - { - int sdomains; -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - sdomains=__searchdomains; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - - if (variant < sdomains - 1) { -- /* next search */ -- variant++; -+ /* next search */ -+ variant++; - } else { -- /* next server, first search */ -- local_ns = (local_ns + 1) % nscount; -- if (local_ns == 0) -- retries++; -+ /* next server, first search */ -+ local_ns = (local_ns + 1) % nscount; -+ if (local_ns == 0) -+ retries++; - -- variant = -1; -+ variant = -1; - } - } - } - --fail: -+ fail: - if (fd != -1) - close(fd); - if (lookup) -@@ -951,10 +937,10 @@ fail: - h_errno = NETDB_INTERNAL; - /* Mess with globals while under lock */ - if (local_ns != -1) { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - ns = local_ns; - id = local_id; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - return -1; - } -@@ -966,9 +952,8 @@ int __nameservers; - char * __nameserver[MAX_SERVERS]; - int __searchdomains; - char * __searchdomain[MAX_SEARCH]; --#ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t __resolv_lock = PTHREAD_MUTEX_INITIALIZER; --#endif -+ -+__UCLIBC_MUTEX_INIT(__resolv_lock, PTHREAD_MUTEX_INITIALIZER); - - /* - * we currently read formats not quite the same as that on normal -@@ -982,60 +967,63 @@ int __open_nameservers() - #define RESOLV_ARGS 5 - char szBuffer[128], *p, *argv[RESOLV_ARGS]; - int argc; -+ int rv = 0; - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - if (__nameservers > 0) { -- BIGUNLOCK; -- return 0; -+ goto DONE; - } - - if ((fp = fopen("/etc/resolv.conf", "r")) || -- (fp = fopen("/etc/config/resolv.conf", "r"))) -- { -- -- while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { -+ (fp = fopen("/etc/config/resolv.conf", "r"))) -+ { - -- for (p = szBuffer; *p && isspace(*p); p++) -- /* skip white space */; -- if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */ -- continue; -- argc = 0; -- while (*p && argc < RESOLV_ARGS) { -- argv[argc++] = p; -- while (*p && !isspace(*p) && *p != '\n') -- p++; -- while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */ -- *p++ = '\0'; -- } -+ while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { - -- if (strcmp(argv[0], "nameserver") == 0) { -- for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) { -- __nameserver[__nameservers++] = strdup(argv[i]); -- DPRINTF("adding nameserver %s\n", argv[i]); -+ for (p = szBuffer; *p && isspace(*p); p++) -+ /* skip white space */; -+ if (*p == '\0' || *p == '\n' || *p == '#') /* skip comments etc */ -+ continue; -+ argc = 0; -+ while (*p && argc < RESOLV_ARGS) { -+ argv[argc++] = p; -+ while (*p && !isspace(*p) && *p != '\n') -+ p++; -+ while (*p && (isspace(*p) || *p == '\n')) /* remove spaces */ -+ *p++ = '\0'; - } -- } - -- /* domain and search are mutually exclusive, the last one wins */ -- if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) { -- while (__searchdomains > 0) { -- free(__searchdomain[--__searchdomains]); -- __searchdomain[__searchdomains] = NULL; -+ if (strcmp(argv[0], "nameserver") == 0) { -+ for (i = 1; i < argc && __nameservers < MAX_SERVERS; i++) { -+ __nameserver[__nameservers++] = strdup(argv[i]); -+ DPRINTF("adding nameserver %s\n", argv[i]); -+ } - } -- for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) { -- __searchdomain[__searchdomains++] = strdup(argv[i]); -- DPRINTF("adding search %s\n", argv[i]); -+ -+ /* domain and search are mutually exclusive, the last one wins */ -+ if (strcmp(argv[0],"domain")==0 || strcmp(argv[0],"search")==0) { -+ while (__searchdomains > 0) { -+ free(__searchdomain[--__searchdomains]); -+ __searchdomain[__searchdomains] = NULL; -+ } -+ for (i=1; i < argc && __searchdomains < MAX_SEARCH; i++) { -+ __searchdomain[__searchdomains++] = strdup(argv[i]); -+ DPRINTF("adding search %s\n", argv[i]); -+ } - } - } -+ fclose(fp); -+ DPRINTF("nameservers = %d\n", __nameservers); -+ goto DONE; - } -- fclose(fp); -- DPRINTF("nameservers = %d\n", __nameservers); -- BIGUNLOCK; -- return 0; -- } - DPRINTF("failed to open %s\n", "resolv.conf"); - h_errno = NO_RECOVERY; -- BIGUNLOCK; -- return -1; -+ -+ rv = -1; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); -+ return rv; - } - #endif - -@@ -1044,7 +1032,7 @@ int __open_nameservers() - - void __close_nameservers(void) - { -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - while (__nameservers > 0) { - free(__nameserver[--__nameservers]); - __nameserver[__nameservers] = NULL; -@@ -1053,7 +1041,7 @@ void __close_nameservers(void) - free(__searchdomain[--__searchdomains]); - __searchdomain[__searchdomains] = NULL; - } -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - } - #endif - -@@ -1063,8 +1051,8 @@ struct hostent *gethostbyname(const char - { - static struct hostent h; - static char buf[sizeof(struct in_addr) + -- sizeof(struct in_addr *)*2 + -- sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; -+ sizeof(struct in_addr *)*2 + -+ sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; - struct hostent *hp; - - gethostbyname_r(name, &h, buf, sizeof(buf), &hp, &h_errno); -@@ -1082,8 +1070,8 @@ struct hostent *gethostbyname2(const cha - #else /* __UCLIBC_HAS_IPV6__ */ - static struct hostent h; - static char buf[sizeof(struct in6_addr) + -- sizeof(struct in6_addr *)*2 + -- sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; -+ sizeof(struct in6_addr *)*2 + -+ sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; - struct hostent *hp; - - gethostbyname2_r(name, family, &h, buf, sizeof(buf), &hp, &h_errno); -@@ -1119,7 +1107,7 @@ int res_init(void) - /** rp->rhook = NULL; **/ - /** rp->_u._ext.nsinit = 0; **/ - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - if(__searchdomains) { - int i; - for(i=0; i<__searchdomains; i++) { -@@ -1139,7 +1127,7 @@ int res_init(void) - } - } - rp->nscount = __nameservers; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - - return(0); - } -@@ -1175,10 +1163,10 @@ int res_query(const char *dname, int cla - - memset((char *) &a, '\0', sizeof(a)); - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - __nameserversXX=__nameservers; - __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - i = __dns_lookup(dname, type, __nameserversXX, __nameserverXX, &packet, &a); - - if (i < 0) { -@@ -1207,10 +1195,10 @@ int res_query(const char *dname, int cla - * is detected. Error code, if any, is left in h_errno. - */ - int res_search(name, class, type, answer, anslen) -- const char *name; /* domain name */ -- int class, type; /* class and type of query */ -- u_char *answer; /* buffer to put answer */ -- int anslen; /* size of answer */ -+ const char *name; /* domain name */ -+ int class, type; /* class and type of query */ -+ u_char *answer; /* buffer to put answer */ -+ int anslen; /* size of answer */ - { - const char *cp, * const *domain; - HEADER *hp = (HEADER *)(void *)answer; -@@ -1256,11 +1244,11 @@ int res_search(name, class, type, answer - int done = 0; - - for (domain = (const char * const *)_res.dnsrch; -- *domain && !done; -- domain++) { -+ *domain && !done; -+ domain++) { - - ret = res_querydomain(name, *domain, class, type, -- answer, anslen); -+ answer, anslen); - if (ret > 0) - return (ret); - -@@ -1283,22 +1271,22 @@ int res_search(name, class, type, answer - } - - switch (h_errno) { -- case NO_DATA: -- got_nodata++; -- /* FALLTHROUGH */ -- case HOST_NOT_FOUND: -- /* keep trying */ -- break; -- case TRY_AGAIN: -- if (hp->rcode == SERVFAIL) { -- /* try next search element, if any */ -- got_servfail++; -+ case NO_DATA: -+ got_nodata++; -+ /* FALLTHROUGH */ -+ case HOST_NOT_FOUND: -+ /* keep trying */ - break; -- } -- /* FALLTHROUGH */ -- default: -- /* anything else implies that we're done */ -- done++; -+ case TRY_AGAIN: -+ if (hp->rcode == SERVFAIL) { -+ /* try next search element, if any */ -+ got_servfail++; -+ break; -+ } -+ /* FALLTHROUGH */ -+ default: -+ /* anything else implies that we're done */ -+ done++; - } - /* - * if we got here for some reason other than DNSRCH, -@@ -1342,10 +1330,10 @@ int res_search(name, class, type, answer - * removing a trailing dot from name if domain is NULL. - */ - int res_querydomain(name, domain, class, type, answer, anslen) -- const char *name, *domain; -- int class, type; /* class and type of query */ -- u_char *answer; /* buffer to put answer */ -- int anslen; /* size of answer */ -+ const char *name, *domain; -+ int class, type; /* class and type of query */ -+ u_char *answer; /* buffer to put answer */ -+ int anslen; /* size of answer */ - { - char nbuf[MAXDNAME]; - const char *longname = nbuf; -@@ -1359,7 +1347,7 @@ int res_querydomain(name, domain, class, - #ifdef DEBUG - if (_res.options & RES_DEBUG) - printf(";; res_querydomain(%s, %s, %d, %d)\n", -- name, domain?domain:"<Nil>", class, type); -+ name, domain?domain:"<Nil>", class, type); - #endif - if (domain == NULL) { - /* -@@ -1400,11 +1388,11 @@ struct hostent *gethostbyaddr (const voi - static struct hostent h; - static char buf[ - #ifndef __UCLIBC_HAS_IPV6__ -- sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + -+ sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + - #else -- sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + -+ sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + - #endif /* __UCLIBC_HAS_IPV6__ */ -- sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; -+ sizeof(char *)*(ALIAS_DIM) + 384/*namebuffer*/ + 32/* margin */]; - struct hostent *hp; - - gethostbyaddr_r(addr, len, type, &h, buf, sizeof(buf), &hp, &h_errno); -@@ -1425,11 +1413,11 @@ void __open_etc_hosts(FILE **fp) - } - - int __read_etc_hosts_r(FILE * fp, const char * name, int type, -- enum etc_hosts_action action, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ enum etc_hosts_action action, -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - struct in_addr *in=NULL; - struct in_addr **addr_list=NULL; -@@ -1576,56 +1564,49 @@ int __read_etc_hosts_r(FILE * fp, const - - #ifdef L_gethostent - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static int __stay_open; - static FILE * __gethostent_fp; - - void endhostent (void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - __stay_open = 0; - if (__gethostent_fp) { -- fclose(__gethostent_fp); -+ fclose(__gethostent_fp); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void sethostent (int stay_open) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - __stay_open = stay_open; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen, -- struct hostent **result, int *h_errnop) -+ struct hostent **result, int *h_errnop) - { -- int ret; -+ int ret = 0; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (__gethostent_fp == NULL) { -- __open_etc_hosts(&__gethostent_fp); -- if (__gethostent_fp == NULL) { -- UNLOCK; -- *result=NULL; -- return 0; -- } -+ __open_etc_hosts(&__gethostent_fp); -+ if (__gethostent_fp == NULL) { -+ *result=NULL; -+ goto DONE; -+ } - } - - ret = __read_etc_hosts_r(__gethostent_fp, NULL, AF_INET, GETHOSTENT, -- result_buf, buf, buflen, result, h_errnop); -+ result_buf, buf, buflen, result, h_errnop); - if (__stay_open==0) { -- fclose(__gethostent_fp); -+ fclose(__gethostent_fp); - } -- UNLOCK; -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return(ret); - } - -@@ -1634,17 +1615,17 @@ struct hostent *gethostent (void) - static struct hostent h; - static char buf[ - #ifndef __UCLIBC_HAS_IPV6__ -- sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + -+ sizeof(struct in_addr) + sizeof(struct in_addr *)*2 + - #else -- sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + -+ sizeof(struct in6_addr) + sizeof(struct in6_addr *)*2 + - #endif /* __UCLIBC_HAS_IPV6__ */ -- sizeof(char *)*(ALIAS_DIM) + -- 80/*namebuffer*/ + 2/* margin */]; -+ sizeof(char *)*(ALIAS_DIM) + -+ 80/*namebuffer*/ + 2/* margin */]; - struct hostent *host; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - gethostent_r(&h, buf, sizeof(buf), &host, &h_errno); -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return(host); - } - #endif -@@ -1652,23 +1633,23 @@ struct hostent *gethostent (void) - #ifdef L_get_hosts_byname_r - - int __get_hosts_byname_r(const char * name, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - return(__read_etc_hosts_r(NULL, name, type, GET_HOSTS_BYNAME, -- result_buf, buf, buflen, result, h_errnop)); -+ result_buf, buf, buflen, result, h_errnop)); - } - #endif - - #ifdef L_get_hosts_byaddr_r - - int __get_hosts_byaddr_r(const char * addr, int len, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - #ifndef __UCLIBC_HAS_IPV6__ - char ipaddr[INET_ADDRSTRLEN]; -@@ -1677,24 +1658,24 @@ int __get_hosts_byaddr_r(const char * ad - #endif /* __UCLIBC_HAS_IPV6__ */ - - switch (type) { -- case AF_INET: -- if (len != sizeof(struct in_addr)) -- return 0; -- break; -+ case AF_INET: -+ if (len != sizeof(struct in_addr)) -+ return 0; -+ break; - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -- if (len != sizeof(struct in6_addr)) -- return 0; -- break; -+ case AF_INET6: -+ if (len != sizeof(struct in6_addr)) -+ return 0; -+ break; - #endif /* __UCLIBC_HAS_IPV6__ */ -- default: -- return 0; -+ default: -+ return 0; - } - - inet_ntop(type, addr, ipaddr, sizeof(ipaddr)); - - return(__read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR, -- result_buf, buf, buflen, result, h_errnop)); -+ result_buf, buf, buflen, result, h_errnop)); - } - #endif - -@@ -1705,8 +1686,8 @@ int __get_hosts_byaddr_r(const char * ad - #endif /* min */ - - int getnameinfo (const struct sockaddr *sa, socklen_t addrlen, char *host, -- socklen_t hostlen, char *serv, socklen_t servlen, -- unsigned int flags) -+ socklen_t hostlen, char *serv, socklen_t servlen, -+ unsigned int flags) - { - int serrno = errno; - int ok = 0; -@@ -1720,167 +1701,167 @@ int getnameinfo (const struct sockaddr * - return EAI_FAMILY; - - switch (sa->sa_family) { -- case AF_LOCAL: -- break; -- case AF_INET: -- if (addrlen < sizeof (struct sockaddr_in)) -- return EAI_FAMILY; -- break; -+ case AF_LOCAL: -+ break; -+ case AF_INET: -+ if (addrlen < sizeof (struct sockaddr_in)) -+ return EAI_FAMILY; -+ break; - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -- if (addrlen < sizeof (struct sockaddr_in6)) -- return EAI_FAMILY; -- break; -+ case AF_INET6: -+ if (addrlen < sizeof (struct sockaddr_in6)) -+ return EAI_FAMILY; -+ break; - #endif /* __UCLIBC_HAS_IPV6__ */ -- default: -- return EAI_FAMILY; -+ default: -+ return EAI_FAMILY; - } - - if (host != NULL && hostlen > 0) - switch (sa->sa_family) { -- case AF_INET: -+ case AF_INET: - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -+ case AF_INET6: - #endif /* __UCLIBC_HAS_IPV6__ */ -- if (!(flags & NI_NUMERICHOST)) { -+ if (!(flags & NI_NUMERICHOST)) { - #ifdef __UCLIBC_HAS_IPV6__ -- if (sa->sa_family == AF_INET6) -- h = gethostbyaddr ((const void *) -- &(((const struct sockaddr_in6 *) sa)->sin6_addr), -- sizeof(struct in6_addr), AF_INET6); -- else --#endif /* __UCLIBC_HAS_IPV6__ */ -- h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr), -- sizeof(struct in_addr), AF_INET); -- -- if (h) { -- char *c; -- if ((flags & NI_NOFQDN) -- && (getdomainname (domain, sizeof(domain)) == 0) -- && (c = strstr (h->h_name, domain)) -- && (c != h->h_name) && (*(--c) == '.')) { -- strncpy (host, h->h_name, -- min(hostlen, (size_t) (c - h->h_name))); -- host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0'; -- ok = 1; -- } else { -- strncpy (host, h->h_name, hostlen); -- ok = 1; -+ if (sa->sa_family == AF_INET6) -+ h = gethostbyaddr ((const void *) -+ &(((const struct sockaddr_in6 *) sa)->sin6_addr), -+ sizeof(struct in6_addr), AF_INET6); -+ else -+#endif /* __UCLIBC_HAS_IPV6__ */ -+ h = gethostbyaddr ((const void *) &(((const struct sockaddr_in *)sa)->sin_addr), -+ sizeof(struct in_addr), AF_INET); -+ -+ if (h) { -+ char *c; -+ if ((flags & NI_NOFQDN) -+ && (getdomainname (domain, sizeof(domain)) == 0) -+ && (c = strstr (h->h_name, domain)) -+ && (c != h->h_name) && (*(--c) == '.')) { -+ strncpy (host, h->h_name, -+ min(hostlen, (size_t) (c - h->h_name))); -+ host[min(hostlen - 1, (size_t) (c - h->h_name))] = '\0'; -+ ok = 1; -+ } else { -+ strncpy (host, h->h_name, hostlen); -+ ok = 1; -+ } - } -- } -- } -+ } - -- if (!ok) { -- if (flags & NI_NAMEREQD) { -- errno = serrno; -- return EAI_NONAME; -- } else { -- const char *c; -+ if (!ok) { -+ if (flags & NI_NAMEREQD) { -+ errno = serrno; -+ return EAI_NONAME; -+ } else { -+ const char *c; - #ifdef __UCLIBC_HAS_IPV6__ -- if (sa->sa_family == AF_INET6) { -- const struct sockaddr_in6 *sin6p; -+ if (sa->sa_family == AF_INET6) { -+ const struct sockaddr_in6 *sin6p; - -- sin6p = (const struct sockaddr_in6 *) sa; -+ sin6p = (const struct sockaddr_in6 *) sa; - -- c = inet_ntop (AF_INET6, -- (const void *) &sin6p->sin6_addr, host, hostlen); -+ c = inet_ntop (AF_INET6, -+ (const void *) &sin6p->sin6_addr, host, hostlen); - #if 0 -- /* Does scope id need to be supported? */ -- uint32_t scopeid; -- scopeid = sin6p->sin6_scope_id; -- if (scopeid != 0) { -- /* Buffer is >= IFNAMSIZ+1. */ -- char scopebuf[IFNAMSIZ + 1]; -- char *scopeptr; -- int ni_numericscope = 0; -- size_t real_hostlen = __strnlen (host, hostlen); -- size_t scopelen = 0; -- -- scopebuf[0] = SCOPE_DELIMITER; -- scopebuf[1] = '\0'; -- scopeptr = &scopebuf[1]; -- -- if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr) -- || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) { -- if (if_indextoname (scopeid, scopeptr) == NULL) -+ /* Does scope id need to be supported? */ -+ uint32_t scopeid; -+ scopeid = sin6p->sin6_scope_id; -+ if (scopeid != 0) { -+ /* Buffer is >= IFNAMSIZ+1. */ -+ char scopebuf[IFNAMSIZ + 1]; -+ char *scopeptr; -+ int ni_numericscope = 0; -+ size_t real_hostlen = __strnlen (host, hostlen); -+ size_t scopelen = 0; -+ -+ scopebuf[0] = SCOPE_DELIMITER; -+ scopebuf[1] = '\0'; -+ scopeptr = &scopebuf[1]; -+ -+ if (IN6_IS_ADDR_LINKLOCAL (&sin6p->sin6_addr) -+ || IN6_IS_ADDR_MC_LINKLOCAL (&sin6p->sin6_addr)) { -+ if (if_indextoname (scopeid, scopeptr) == NULL) -+ ++ni_numericscope; -+ else -+ scopelen = strlen (scopebuf); -+ } else { - ++ni_numericscope; -- else -- scopelen = strlen (scopebuf); -- } else { -- ++ni_numericscope; -- } -+ } - -- if (ni_numericscope) -- scopelen = 1 + snprintf (scopeptr, -- (scopebuf -- + sizeof scopebuf -- - scopeptr), -- "%u", scopeid); -- -- if (real_hostlen + scopelen + 1 > hostlen) -- return EAI_SYSTEM; -- memcpy (host + real_hostlen, scopebuf, scopelen + 1); -- } -+ if (ni_numericscope) -+ scopelen = 1 + snprintf (scopeptr, -+ (scopebuf -+ + sizeof scopebuf -+ - scopeptr), -+ "%u", scopeid); -+ -+ if (real_hostlen + scopelen + 1 > hostlen) -+ return EAI_SYSTEM; -+ memcpy (host + real_hostlen, scopebuf, scopelen + 1); -+ } - #endif -- } else -+ } else - #endif /* __UCLIBC_HAS_IPV6__ */ -- c = inet_ntop (AF_INET, (const void *) -- &(((const struct sockaddr_in *) sa)->sin_addr), -- host, hostlen); -- -- if (c == NULL) { -- errno = serrno; -- return EAI_SYSTEM; -+ c = inet_ntop (AF_INET, (const void *) -+ &(((const struct sockaddr_in *) sa)->sin_addr), -+ host, hostlen); -+ -+ if (c == NULL) { -+ errno = serrno; -+ return EAI_SYSTEM; -+ } - } -+ ok = 1; - } -- ok = 1; -- } -- break; -- -- case AF_LOCAL: -- if (!(flags & NI_NUMERICHOST)) { -- struct utsname utsname; -+ break; - -- if (!uname (&utsname)) { -- strncpy (host, utsname.nodename, hostlen); -- break; -+ case AF_LOCAL: -+ if (!(flags & NI_NUMERICHOST)) { -+ struct utsname utsname; -+ -+ if (!uname (&utsname)) { -+ strncpy (host, utsname.nodename, hostlen); -+ break; -+ }; - }; -- }; - -- if (flags & NI_NAMEREQD) { -- errno = serrno; -- return EAI_NONAME; -- } -+ if (flags & NI_NAMEREQD) { -+ errno = serrno; -+ return EAI_NONAME; -+ } - -- strncpy (host, "localhost", hostlen); -- break; -+ strncpy (host, "localhost", hostlen); -+ break; - -- default: -- return EAI_FAMILY; -- } -+ default: -+ return EAI_FAMILY; -+ } - - if (serv && (servlen > 0)) { - switch (sa->sa_family) { -- case AF_INET: -+ case AF_INET: - #ifdef __UCLIBC_HAS_IPV6__ -- case AF_INET6: -+ case AF_INET6: - #endif /* __UCLIBC_HAS_IPV6__ */ -- if (!(flags & NI_NUMERICSERV)) { -- struct servent *s; -- s = getservbyport (((const struct sockaddr_in *) sa)->sin_port, -- ((flags & NI_DGRAM) ? "udp" : "tcp")); -- if (s) { -- strncpy (serv, s->s_name, servlen); -- break; -+ if (!(flags & NI_NUMERICSERV)) { -+ struct servent *s; -+ s = getservbyport (((const struct sockaddr_in *) sa)->sin_port, -+ ((flags & NI_DGRAM) ? "udp" : "tcp")); -+ if (s) { -+ strncpy (serv, s->s_name, servlen); -+ break; -+ } - } -- } -- snprintf (serv, servlen, "%d", -- ntohs (((const struct sockaddr_in *) sa)->sin_port)); -- break; -+ snprintf (serv, servlen, "%d", -+ ntohs (((const struct sockaddr_in *) sa)->sin_port)); -+ break; - -- case AF_LOCAL: -- strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen); -- break; -+ case AF_LOCAL: -+ strncpy (serv, ((const struct sockaddr_un *) sa)->sun_path, servlen); -+ break; - } - } - if (host && (hostlen > 0)) -@@ -1896,10 +1877,10 @@ int getnameinfo (const struct sockaddr * - #ifdef L_gethostbyname_r - - int gethostbyname_r(const char * name, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - struct in_addr *in; - struct in_addr **addr_list; -@@ -1921,7 +1902,7 @@ int gethostbyname_r(const char * name, - __set_errno(0); /* to check for missing /etc/hosts. */ - - if ((i=__get_hosts_byname_r(name, AF_INET, result_buf, -- buf, buflen, result, h_errnop))==0) -+ buf, buflen, result, h_errnop))==0) - return i; - switch (*h_errnop) { - case HOST_NOT_FOUND: -@@ -1983,60 +1964,60 @@ int gethostbyname_r(const char * name, - - for (;;) { - -- BIGLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); - __nameserversXX=__nameservers; - __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - a.buf = buf; - a.buflen = buflen; - a.add_count = 0; - i = __dns_lookup(name, T_A, __nameserversXX, __nameserverXX, &packet, &a); - - if (i < 0) { -- *h_errnop = HOST_NOT_FOUND; -- DPRINTF("__dns_lookup\n"); -- return TRY_AGAIN; -+ *h_errnop = HOST_NOT_FOUND; -+ DPRINTF("__dns_lookup\n"); -+ return TRY_AGAIN; - } - - if ((a.rdlength + sizeof(struct in_addr*)) * a.add_count + 256 > buflen) -- { -- free(a.dotted); -- free(packet); -- *h_errnop = NETDB_INTERNAL; -- DPRINTF("buffer too small for all addresses\n"); -- return ERANGE; -- } -+ { -+ free(a.dotted); -+ free(packet); -+ *h_errnop = NETDB_INTERNAL; -+ DPRINTF("buffer too small for all addresses\n"); -+ return ERANGE; -+ } - else if(a.add_count > 0) -- { -- memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength); -- addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength); -- addr_list[0] = in; -- for (i = a.add_count-1; i>=0; --i) -- addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i); -- addr_list[a.add_count + 1] = 0; -- buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf); -- buf = (char*)&addr_list[a.add_count + 2]; -- } -+ { -+ memmove(buf - sizeof(struct in_addr*)*2, buf, a.add_count * a.rdlength); -+ addr_list = (struct in_addr**)(buf + a.add_count * a.rdlength); -+ addr_list[0] = in; -+ for (i = a.add_count-1; i>=0; --i) -+ addr_list[i+1] = (struct in_addr*)(buf - sizeof(struct in_addr*)*2 + a.rdlength * i); -+ addr_list[a.add_count + 1] = 0; -+ buflen -= (((char*)&(addr_list[a.add_count + 2])) - buf); -+ buf = (char*)&addr_list[a.add_count + 2]; -+ } - - strncpy(buf, a.dotted, buflen); - free(a.dotted); - - if (a.atype == T_A) { /* ADDRESS */ -- memcpy(in, a.rdata, sizeof(*in)); -- result_buf->h_name = buf; -- result_buf->h_addrtype = AF_INET; -- result_buf->h_length = sizeof(*in); -- result_buf->h_addr_list = (char **) addr_list; -+ memcpy(in, a.rdata, sizeof(*in)); -+ result_buf->h_name = buf; -+ result_buf->h_addrtype = AF_INET; -+ result_buf->h_length = sizeof(*in); -+ result_buf->h_addr_list = (char **) addr_list; - #ifdef __UCLIBC_MJN3_ONLY__ - #warning TODO -- generate the full list - #endif -- result_buf->h_aliases = alias; /* TODO: generate the full list */ -- free(packet); -- break; -+ result_buf->h_aliases = alias; /* TODO: generate the full list */ -+ free(packet); -+ break; - } else { -- free(packet); -- *h_errnop=HOST_NOT_FOUND; -- return TRY_AGAIN; -+ free(packet); -+ *h_errnop=HOST_NOT_FOUND; -+ return TRY_AGAIN; - } - } - -@@ -2049,14 +2030,14 @@ int gethostbyname_r(const char * name, - #ifdef L_gethostbyname2_r - - int gethostbyname2_r(const char *name, int family, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - { - #ifndef __UCLIBC_HAS_IPV6__ - return family == (AF_INET)? gethostbyname_r(name, result_buf, -- buf, buflen, result, h_errnop) : HOST_NOT_FOUND; -+ buf, buflen, result, h_errnop) : HOST_NOT_FOUND; - #else /* __UCLIBC_HAS_IPV6__ */ - struct in6_addr *in; - struct in6_addr **addr_list; -@@ -2084,7 +2065,7 @@ int gethostbyname2_r(const char *name, i - __set_errno(0); /* to check for missing /etc/hosts. */ - - if ((i=__get_hosts_byname_r(name, AF_INET, result_buf, -- buf, buflen, result, h_errnop))==0) -+ buf, buflen, result, h_errnop))==0) - return i; - switch (*h_errnop) { - case HOST_NOT_FOUND: -@@ -2137,10 +2118,10 @@ int gethostbyname2_r(const char *name, i - memset((char *) &a, '\0', sizeof(a)); - - for (;;) { -- BIGLOCK; -- __nameserversXX=__nameservers; -- __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); -+ __nameserversXX=__nameservers; -+ __nameserverXX=__nameserver; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - - i = __dns_lookup(buf, T_AAAA, __nameserversXX, __nameserverXX, &packet, &a); - -@@ -2190,10 +2171,10 @@ int gethostbyname2_r(const char *name, i - - #ifdef L_gethostbyaddr_r - int gethostbyaddr_r (const void *addr, socklen_t len, int type, -- struct hostent * result_buf, -- char * buf, size_t buflen, -- struct hostent ** result, -- int * h_errnop) -+ struct hostent * result_buf, -+ char * buf, size_t buflen, -+ struct hostent ** result, -+ int * h_errnop) - - { - struct in_addr *in; -@@ -2234,7 +2215,7 @@ int gethostbyaddr_r (const void *addr, s - - /* do /etc/hosts first */ - if ((i=__get_hosts_byaddr_r(addr, len, type, result_buf, -- buf, buflen, result, h_errnop))==0) -+ buf, buflen, result, h_errnop))==0) - return i; - switch (*h_errnop) { - case HOST_NOT_FOUND: -@@ -2294,7 +2275,7 @@ int gethostbyaddr_r (const void *addr, s - addr_list[0] = in; - - sprintf(buf, "%u.%u.%u.%u.in-addr.arpa", -- tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); -+ tmp_addr[3], tmp_addr[2], tmp_addr[1], tmp_addr[0]); - #ifdef __UCLIBC_HAS_IPV6__ - } else { - memcpy(in6->s6_addr, addr, len); -@@ -2304,7 +2285,7 @@ int gethostbyaddr_r (const void *addr, s - - for (i = len - 1; i >= 0; i--) { - qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf, -- (in6->s6_addr[i] >> 4) & 0xf); -+ (in6->s6_addr[i] >> 4) & 0xf); - } - strcpy(qp, "ip6.int"); - #endif /* __UCLIBC_HAS_IPV6__ */ -@@ -2314,10 +2295,10 @@ int gethostbyaddr_r (const void *addr, s - - for (;;) { - -- BIGLOCK; -- __nameserversXX=__nameservers; -- __nameserverXX=__nameserver; -- BIGUNLOCK; -+ __UCLIBC_MUTEX_LOCK(__resolv_lock); -+ __nameserversXX=__nameservers; -+ __nameserverXX=__nameserver; -+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock); - i = __dns_lookup(buf, T_PTR, __nameserversXX, __nameserverXX, &packet, &a); - - if (i < 0) { -@@ -2381,7 +2362,7 @@ int gethostbyaddr_r (const void *addr, s - * Return size of compressed name or -1 if there was an error. - */ - int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src, -- char *dst, int dstsiz) -+ char *dst, int dstsiz) - { - int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz); - -@@ -2401,7 +2382,7 @@ int __dn_expand(const u_char *msg, const - */ - static int printable(int ch) - { -- return (ch > 0x20 && ch < 0x7f); -+ return (ch > 0x20 && ch < 0x7f); - } - - /* -@@ -2413,18 +2394,18 @@ static int printable(int ch) - */ - static int special(int ch) - { -- switch (ch) { -+ switch (ch) { - case 0x22: /* '"' */ - case 0x2E: /* '.' */ - case 0x3B: /* ';' */ - case 0x5C: /* '\\' */ -- /* Special modifiers in zone files. */ -+ /* Special modifiers in zone files. */ - case 0x40: /* '@' */ - case 0x24: /* '$' */ -- return (1); -+ return (1); - default: -- return (0); -- } -+ return (0); -+ } - } - - /* -@@ -2436,7 +2417,7 @@ static int special(int ch) - * Root domain returns as "." not "". - */ - int __ns_name_uncompress(const u_char *msg, const u_char *eom, -- const u_char *src, char *dst, size_t dstsiz) -+ const u_char *src, char *dst, size_t dstsiz) - { - u_char tmp[NS_MAXCDNAME]; - int n; -@@ -2525,7 +2506,7 @@ int __ns_name_ntop(const u_char *src, ch - return (-1); - } - *dn++ = '\0'; -- return (dn - dst); -+ return (dn - dst); - } - - /* -@@ -2535,7 +2516,7 @@ int __ns_name_ntop(const u_char *src, ch - * -1 if it fails, or consumed octets if it succeeds. - */ - int __ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, -- u_char *dst, size_t dstsiz) -+ u_char *dst, size_t dstsiz) - { - const u_char *srcp, *dstlim; - u_char *dstp; -@@ -2554,46 +2535,46 @@ int __ns_name_unpack(const u_char *msg, - while ((n = *srcp++) != 0) { - /* Check for indirection. */ - switch (n & NS_CMPRSFLGS) { -- case 0: -- /* Limit checks. */ -- if (dstp + n + 1 >= dstlim || srcp + n >= eom) { -- __set_errno (EMSGSIZE); -- return (-1); -- } -- checked += n + 1; -- *dstp++ = n; -- memcpy(dstp, srcp, n); -- dstp += n; -- srcp += n; -- break; -+ case 0: -+ /* Limit checks. */ -+ if (dstp + n + 1 >= dstlim || srcp + n >= eom) { -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ checked += n + 1; -+ *dstp++ = n; -+ memcpy(dstp, srcp, n); -+ dstp += n; -+ srcp += n; -+ break; - -- case NS_CMPRSFLGS: -- if (srcp >= eom) { -- __set_errno (EMSGSIZE); -- return (-1); -- } -- if (len < 0) -- len = srcp - src + 1; -- srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); -- if (srcp < msg || srcp >= eom) { /* Out of range. */ -- __set_errno (EMSGSIZE); -- return (-1); -- } -- checked += 2; -- /* -- * Check for loops in the compressed name; -- * if we've looked at the whole message, -- * there must be a loop. -- */ -- if (checked >= eom - msg) { -- __set_errno (EMSGSIZE); -- return (-1); -- } -- break; -+ case NS_CMPRSFLGS: -+ if (srcp >= eom) { -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ if (len < 0) -+ len = srcp - src + 1; -+ srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff)); -+ if (srcp < msg || srcp >= eom) { /* Out of range. */ -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ checked += 2; -+ /* -+ * Check for loops in the compressed name; -+ * if we've looked at the whole message, -+ * there must be a loop. -+ */ -+ if (checked >= eom - msg) { -+ __set_errno (EMSGSIZE); -+ return (-1); -+ } -+ break; - -- default: -- __set_errno (EMSGSIZE); -- return (-1); /* flag error */ -+ default: -+ __set_errno (EMSGSIZE); -+ return (-1); /* flag error */ - } - } - *dstp = '\0'; -diff --git a/libc/inet/rpc/create_xid.c b/libc/inet/rpc/create_xid.c -index cbb961e..c86cbb4 100644 ---- a/libc/inet/rpc/create_xid.c -+++ b/libc/inet/rpc/create_xid.c -@@ -27,15 +27,7 @@ - - /* The RPC code is not threadsafe, but new code should be threadsafe. */ - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t createxid_lock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&createxid_lock) --# define UNLOCK __pthread_mutex_unlock(&createxid_lock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static int is_initialized; - static struct drand48_data __rpc_lrand48_data; -@@ -43,22 +35,22 @@ static struct drand48_data __rpc_lrand48 - unsigned long - _create_xid (void) - { -- unsigned long res; -+ unsigned long res; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - -- if (!is_initialized) -- { -- struct timeval now; -+ if (!is_initialized) -+ { -+ struct timeval now; - -- gettimeofday (&now, (struct timezone *) 0); -- srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data); -- is_initialized = 1; -- } -+ gettimeofday (&now, (struct timezone *) 0); -+ srand48_r (now.tv_sec ^ now.tv_usec, &__rpc_lrand48_data); -+ is_initialized = 1; -+ } - -- lrand48_r (&__rpc_lrand48_data, &res); -+ lrand48_r (&__rpc_lrand48_data, &res); - -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - -- return res; -+ return res; - } -diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c -index 068e2d3..56adb23 100644 ---- a/libc/misc/dirent/closedir.c -+++ b/libc/misc/dirent/closedir.c -@@ -4,7 +4,6 @@ - #include <unistd.h> - #include "dirstream.h" - -- - int closedir(DIR * dir) - { - int fd; -@@ -19,14 +18,10 @@ int closedir(DIR * dir) - __set_errno(EBADF); - return -1; - } --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - fd = dir->dd_fd; - dir->dd_fd = -1; --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - free(dir->dd_buf); - free(dir); - return close(fd); -diff --git a/libc/misc/dirent/dirstream.h b/libc/misc/dirent/dirstream.h -index 2dd0264..bd721c5 100644 ---- a/libc/misc/dirent/dirstream.h -+++ b/libc/misc/dirent/dirstream.h -@@ -26,9 +26,8 @@ Cambridge, MA 02139, USA. */ - - #include <features.h> - #include <sys/types.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif -+ -+#include <bits/uClibc_mutex.h> - - /* For now, syscall readdir () only supports one entry at a time. It - * will be changed in the future. -@@ -63,11 +62,7 @@ struct __dirstream { - size_t dd_max; - - /* lock */ --#ifdef __UCLIBC_HAS_THREADS__ -- pthread_mutex_t dd_lock; --#else -- void *dd_lock; --#endif -+ __UCLIBC_MUTEX(dd_lock); - }; /* stream data from opendir() */ - - -diff --git a/libc/misc/dirent/readdir.c b/libc/misc/dirent/readdir.c -index 1f196e1..c55317a 100644 ---- a/libc/misc/dirent/readdir.c -+++ b/libc/misc/dirent/readdir.c -@@ -5,7 +5,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - struct dirent *readdir(DIR * dir) - { - ssize_t bytes; -@@ -16,9 +15,7 @@ struct dirent *readdir(DIR * dir) - return NULL; - } - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -@@ -44,8 +41,6 @@ struct dirent *readdir(DIR * dir) - } while (de->d_ino == 0); - - all_done: --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - return de; - } -diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c -index f798c6f..6da3b0d 100644 ---- a/libc/misc/dirent/readdir64.c -+++ b/libc/misc/dirent/readdir64.c -@@ -20,7 +20,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - struct dirent64 *readdir64(DIR * dir) - { - ssize_t bytes; -@@ -31,9 +30,7 @@ struct dirent64 *readdir64(DIR * dir) - return NULL; - } - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -@@ -59,9 +56,7 @@ struct dirent64 *readdir64(DIR * dir) - } while (de->d_ino == 0); - - all_done: --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - - return de; - } -diff --git a/libc/misc/dirent/readdir64_r.c b/libc/misc/dirent/readdir64_r.c -index da3564e..cc96eff 100644 ---- a/libc/misc/dirent/readdir64_r.c -+++ b/libc/misc/dirent/readdir64_r.c -@@ -19,7 +19,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result) - { - int ret; -@@ -32,21 +31,19 @@ int readdir64_r(DIR *dir, struct dirent6 - } - de = NULL; - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -- /* read dir->dd_max bytes of directory entries. */ -- bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max); -- if (bytes <= 0) { -- *result = NULL; -- ret = errno; -- goto all_done; -- } -- dir->dd_size = bytes; -- dir->dd_nextloc = 0; -+ /* read dir->dd_max bytes of directory entries. */ -+ bytes = __getdents64(dir->dd_fd, dir->dd_buf, dir->dd_max); -+ if (bytes <= 0) { -+ *result = NULL; -+ ret = errno; -+ goto all_done; -+ } -+ dir->dd_size = bytes; -+ dir->dd_nextloc = 0; - } - - de = (struct dirent64 *) (((char *) dir->dd_buf) + dir->dd_nextloc); -@@ -66,12 +63,10 @@ int readdir64_r(DIR *dir, struct dirent6 - } - ret = 0; - --all_done: -+ all_done: - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -- return((de != NULL)? 0 : ret); -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); -+ return((de != NULL)? 0 : ret); - } - #endif /* __UCLIBC_HAS_LFS__ */ - -diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c -index 245dcbd..aeccdd8 100644 ---- a/libc/misc/dirent/readdir_r.c -+++ b/libc/misc/dirent/readdir_r.c -@@ -5,7 +5,6 @@ - #include <dirent.h> - #include "dirstream.h" - -- - int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) - { - int ret; -@@ -18,21 +17,19 @@ int readdir_r(DIR *dir, struct dirent *e - } - de = NULL; - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - - do { - if (dir->dd_size <= dir->dd_nextloc) { -- /* read dir->dd_max bytes of directory entries. */ -- bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max); -- if (bytes <= 0) { -- *result = NULL; -- ret = errno; -- goto all_done; -- } -- dir->dd_size = bytes; -- dir->dd_nextloc = 0; -+ /* read dir->dd_max bytes of directory entries. */ -+ bytes = __getdents(dir->dd_fd, dir->dd_buf, dir->dd_max); -+ if (bytes <= 0) { -+ *result = NULL; -+ ret = errno; -+ goto all_done; -+ } -+ dir->dd_size = bytes; -+ dir->dd_nextloc = 0; - } - - de = (struct dirent *) (((char *) dir->dd_buf) + dir->dd_nextloc); -@@ -52,10 +49,8 @@ int readdir_r(DIR *dir, struct dirent *e - } - ret = 0; - --all_done: -+ all_done: - --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -- return((de != NULL)? 0 : ret); -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); -+ return((de != NULL)? 0 : ret); - } -diff --git a/libc/misc/dirent/rewinddir.c b/libc/misc/dirent/rewinddir.c -index 60ef71d..fe8fc2a 100644 ---- a/libc/misc/dirent/rewinddir.c -+++ b/libc/misc/dirent/rewinddir.c -@@ -3,7 +3,6 @@ - #include <unistd.h> - #include "dirstream.h" - -- - /* rewinddir() just does an lseek(fd,0,0) - see close for comments */ - void rewinddir(DIR * dir) - { -@@ -11,12 +10,8 @@ void rewinddir(DIR * dir) - __set_errno(EBADF); - return; - } --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - lseek(dir->dd_fd, 0, SEEK_SET); - dir->dd_nextoff = dir->dd_nextloc = dir->dd_size = 0; --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - } -diff --git a/libc/misc/dirent/seekdir.c b/libc/misc/dirent/seekdir.c -index 139f1e1..6d6f5f0 100644 ---- a/libc/misc/dirent/seekdir.c -+++ b/libc/misc/dirent/seekdir.c -@@ -3,19 +3,14 @@ - #include <unistd.h> - #include "dirstream.h" - -- - void seekdir(DIR * dir, long int offset) - { - if (!dir) { - __set_errno(EBADF); - return; - } --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_lock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_LOCK(dir->dd_lock); - dir->dd_nextoff = lseek(dir->dd_fd, offset, SEEK_SET); - dir->dd_size = dir->dd_nextloc = 0; --#ifdef __UCLIBC_HAS_THREADS__ -- __pthread_mutex_unlock(&(dir->dd_lock)); --#endif -+ __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); - } -diff --git a/libc/misc/mntent/mntent.c b/libc/misc/mntent/mntent.c -index d98a687..af6d848 100644 ---- a/libc/misc/mntent/mntent.c -+++ b/libc/misc/mntent/mntent.c -@@ -3,15 +3,9 @@ - #include <string.h> - #include <mntent.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* Reentrant version of getmntent. */ - struct mntent *getmntent_r (FILE *filep, -@@ -67,7 +61,7 @@ struct mntent *getmntent(FILE * filep) - struct mntent *tmp; - static char *buff = NULL; - static struct mntent mnt; -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - if (!buff) { - buff = malloc(BUFSIZ); -@@ -76,7 +70,7 @@ struct mntent *getmntent(FILE * filep) - } - - tmp = getmntent_r(filep, &mnt, buff, BUFSIZ); -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return(tmp); - } - -diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c -index 89c2611..c27bd10 100644 ---- a/libc/misc/pthread/weaks.c -+++ b/libc/misc/pthread/weaks.c -@@ -21,6 +21,7 @@ - #include <limits.h> - #include <stdlib.h> - -+static void __pthread_return_void __P ((void)); - static int __pthread_return_0 __P ((void)); - static int __pthread_return_1 __P ((void)); - -@@ -104,8 +105,17 @@ weak_alias (__pthread_return_0, __pthrea - weak_alias (__pthread_return_0, __pthread_mutex_trylock) - weak_alias (__pthread_return_0, __pthread_mutex_unlock) - -+weak_alias (__pthread_return_void, _pthread_cleanup_push_defer) -+weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore) -+ - /**********************************************************************/ - -+static void -+__pthread_return_void (void) -+{ -+ return; -+} -+ - static int - __pthread_return_0 (void) - { -diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c -index 2b478e1..9e9ddbf 100644 ---- a/libc/misc/syslog/syslog.c -+++ b/libc/misc/syslog/syslog.c -@@ -80,17 +80,9 @@ - #include <ctype.h> - #include <signal.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - static int LogFile = -1; /* fd for log */ - static int connected; /* have done connect */ -@@ -110,26 +102,26 @@ int setlogmask(int pmask); - static void - closelog_intern(int to_default) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (LogFile != -1) { - (void) close(LogFile); - } - LogFile = -1; - connected = 0; - if (to_default) -- { -- LogStat = 0; -- LogTag = "syslog"; -- LogFacility = LOG_USER; -- LogMask = 0xff; -- } -- UNLOCK; -+ { -+ LogStat = 0; -+ LogTag = "syslog"; -+ LogFacility = LOG_USER; -+ LogMask = 0xff; -+ } -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - static void - sigpipe_handler (int sig) - { -- closelog_intern (0); -+ closelog_intern (0); - } - - /* -@@ -165,7 +157,7 @@ vsyslog( int pri, const char *fmt, va_li - - saved_errno = errno; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - /* See if we should just throw out this message. */ - if (!(LogMask & LOG_MASK(LOG_PRI(pri))) || (pri &~ (LOG_PRIMASK|LOG_FACMASK))) -@@ -208,7 +200,7 @@ vsyslog( int pri, const char *fmt, va_li - if (p >= end || p < head_end) { /* Returned -1 in case of error... */ - static const char truncate_msg[12] = "[truncated] "; - memmove(head_end + sizeof(truncate_msg), head_end, -- end - head_end - sizeof(truncate_msg)); -+ end - head_end - sizeof(truncate_msg)); - memcpy(head_end, truncate_msg, sizeof(truncate_msg)); - if (p < head_end) { - while (p < end && *p) { -@@ -261,11 +253,11 @@ vsyslog( int pri, const char *fmt, va_li - (void)close(fd); - } - --getout: -- UNLOCK; -+ getout: -+ __UCLIBC_MUTEX_UNLOCK(mylock); - if (sigpipe == 0) - sigaction (SIGPIPE, &oldaction, -- (struct sigaction *) NULL); -+ (struct sigaction *) NULL); - } - - /* -@@ -276,48 +268,48 @@ openlog( const char *ident, int logstat, - { - int logType = SOCK_DGRAM; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - if (ident != NULL) -- LogTag = ident; -+ LogTag = ident; - LogStat = logstat; - if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0) -- LogFacility = logfac; -+ LogFacility = logfac; - if (LogFile == -1) { -- SyslogAddr.sa_family = AF_UNIX; -- (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, -- sizeof(SyslogAddr.sa_data)); --retry: -- if (LogStat & LOG_NDELAY) { -- if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){ -- UNLOCK; -- return; -- } -- /* fcntl(LogFile, F_SETFD, 1); */ -- } -+ SyslogAddr.sa_family = AF_UNIX; -+ (void)strncpy(SyslogAddr.sa_data, _PATH_LOG, -+ sizeof(SyslogAddr.sa_data)); -+ retry: -+ if (LogStat & LOG_NDELAY) { -+ if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){ -+ goto DONE; -+ } -+ /* fcntl(LogFile, F_SETFD, 1); */ -+ } - } - - if (LogFile != -1 && !connected) { -- if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - -- sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1) -- { -- connected = 1; -- } else if (logType == SOCK_DGRAM) { -- logType = SOCK_STREAM; -- if (LogFile != -1) { -- close(LogFile); -- LogFile = -1; -- } -- goto retry; -- } else { -- if (LogFile != -1) { -- close(LogFile); -- LogFile = -1; -- } -- } -+ if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - -+ sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1) -+ { -+ connected = 1; -+ } else if (logType == SOCK_DGRAM) { -+ logType = SOCK_STREAM; -+ if (LogFile != -1) { -+ close(LogFile); -+ LogFile = -1; -+ } -+ goto retry; -+ } else { -+ if (LogFile != -1) { -+ close(LogFile); -+ LogFile = -1; -+ } -+ } - } - -- UNLOCK; -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - /* -@@ -335,10 +327,10 @@ int setlogmask(int pmask) - int omask; - - omask = LogMask; -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (pmask != 0) -- LogMask = pmask; -- UNLOCK; -+ LogMask = pmask; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - return (omask); - } - -diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c -index f43bb8a..6165a52 100644 ---- a/libc/misc/time/time.c -+++ b/libc/misc/time/time.c -@@ -143,6 +143,8 @@ - #include <locale.h> - #include <bits/uClibc_uintmaxtostr.h> - -+#include <bits/uClibc_mutex.h> -+ - #ifdef __UCLIBC_HAS_XLOCALE__ - #include <xlocale.h> - #endif -@@ -191,21 +193,7 @@ typedef struct { - char tzname[TZNAME_MAX+1]; - } rule_struct; - --#ifdef __UCLIBC_HAS_THREADS__ -- --#include <pthread.h> -- --extern pthread_mutex_t _time_tzlock; -- --#define TZLOCK __pthread_mutex_lock(&_time_tzlock) --#define TZUNLOCK __pthread_mutex_unlock(&_time_tzlock) -- --#else -- --#define TZLOCK ((void) 0) --#define TZUNLOCK ((void) 0) -- --#endif -+__UCLIBC_MUTEX_EXTERN(_time_tzlock); - - extern rule_struct _time_tzinfo[2]; - -@@ -542,13 +530,13 @@ struct tm *localtime(const time_t *timer - struct tm *localtime_r(register const time_t *__restrict timer, - register struct tm *__restrict result) - { -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - tzset(); - - __time_localtime_tzi(timer, result, _time_tzinfo); - -- TZUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); - - return result; - } -@@ -1037,7 +1025,7 @@ size_t __XL(strftime)(char *__restrict s - goto LOOP; - } - -- o = spec + 26; /* set to "????" */ -+ o = ((const char *) spec) + 26; /* set to "????" */ - if ((code & MASK_SPEC) == CALC_SPEC) { - - if (*p == 's') { -@@ -1073,17 +1061,15 @@ size_t __XL(strftime)(char *__restrict s - - #ifdef __UCLIBC_HAS_TM_EXTENSIONS__ - --#define RSP_TZUNLOCK ((void) 0) - #define RSP_TZNAME timeptr->tm_zone - #define RSP_GMT_OFFSET (-timeptr->tm_gmtoff) - - #else - --#define RSP_TZUNLOCK TZUNLOCK - #define RSP_TZNAME rsp->tzname - #define RSP_GMT_OFFSET rsp->gmt_offset - -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - rsp = _time_tzinfo; - if (timeptr->tm_isdst > 0) { -@@ -1114,15 +1100,17 @@ size_t __XL(strftime)(char *__restrict s - } - #endif - o_count = SIZE_MAX; -- RSP_TZUNLOCK; -+/* RSP_TZUNLOCK; */ -+#ifdef __UCLIBC_HAS_TM_EXTENSIONS__ - goto OUTPUT; -+#endif - } else { /* z */ - *s = '+'; - if ((tzo = -RSP_GMT_OFFSET) < 0) { - tzo = -tzo; - *s = '-'; - } -- RSP_TZUNLOCK; -+/* RSP_TZUNLOCK; */ - ++s; - --count; - -@@ -1131,7 +1119,13 @@ size_t __XL(strftime)(char *__restrict s - - i = 16 + 6; /* 0-fill, width = 4 */ - } -- -+#ifdef __UCLIBC_HAS_TM_EXTENSIONS__ -+#else -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); -+ if (*p == 'Z') { -+ goto OUTPUT; -+ } -+#endif - } else { - /* TODO: don't need year for U, W */ - for (i=0 ; i < 3 ; i++) { -@@ -1664,9 +1658,7 @@ int daylight = 0; - long timezone = 0; - char *tzname[2] = { (char *) UTC, (char *) (UTC-1) }; - --#ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t _time_tzlock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --#endif -+__UCLIBC_MUTEX_INIT(_time_tzlock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - rule_struct _time_tzinfo[2]; - -@@ -1796,7 +1788,7 @@ void tzset(void) - static char oldval[TZ_BUFLEN]; /* BSS-zero'd. */ - #endif /* __UCLIBC_HAS_TZ_CACHING__ */ - -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - e = getenv(TZ); /* TZ env var always takes precedence. */ - -@@ -1962,10 +1954,10 @@ void tzset(void) - daylight = !!_time_tzinfo[1].tzname[0]; - timezone = _time_tzinfo[0].gmt_offset; - --#if defined(__UCLIBC_HAS_TZ_FILE__) -+#if defined(__UCLIBC_HAS_TZ_FILE__) || defined(__UCLIBC_HAS_TZ_CACHING__) - FAST_DONE: - #endif -- TZUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); - } - - #endif -@@ -2167,13 +2159,13 @@ time_t _time_mktime(struct tm *timeptr, - { - time_t t; - -- TZLOCK; -+ __UCLIBC_MUTEX_LOCK(_time_tzlock); - - tzset(); - - t = _time_mktime_tzi(timeptr, store_on_success, _time_tzinfo); - -- TZUNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(_time_tzlock); - - return t; - } -diff --git a/libc/misc/ttyent/getttyent.c b/libc/misc/ttyent/getttyent.c -index 6e2fbd2..c85c73a 100644 ---- a/libc/misc/ttyent/getttyent.c -+++ b/libc/misc/ttyent/getttyent.c -@@ -35,9 +35,6 @@ - #include <ctype.h> - #include <string.h> - #include <stdlib.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif - - static char zapchar; - static FILE *tf; -@@ -50,8 +47,8 @@ struct ttyent * getttynam(const char *tt - - setttyent(); - while ((t = getttyent())) -- if (!strcmp(tty, t->ty_name)) -- break; -+ if (!strcmp(tty, t->ty_name)) -+ break; - endttyent(); - return (t); - } -@@ -67,27 +64,27 @@ static char * skip(register char *p) - register int c, q; - - for (q = 0, t = p; (c = *p) != '\0'; p++) { -- if (c == '"') { -- q ^= QUOTED; /* obscure, but nice */ -- continue; -- } -- if (q == QUOTED && *p == '\\' && *(p+1) == '"') -- p++; -- *t++ = *p; -- if (q == QUOTED) -- continue; -- if (c == '#') { -- zapchar = c; -- *p = 0; -- break; -- } -- if (c == '\t' || c == ' ' || c == '\n') { -- zapchar = c; -- *p++ = 0; -- while ((c = *p) == '\t' || c == ' ' || c == '\n') -- p++; -- break; -- } -+ if (c == '"') { -+ q ^= QUOTED; /* obscure, but nice */ -+ continue; -+ } -+ if (q == QUOTED && *p == '\\' && *(p+1) == '"') -+ p++; -+ *t++ = *p; -+ if (q == QUOTED) -+ continue; -+ if (c == '#') { -+ zapchar = c; -+ *p = 0; -+ break; -+ } -+ if (c == '\t' || c == ' ' || c == '\n') { -+ zapchar = c; -+ *p++ = 0; -+ while ((c = *p) == '\t' || c == ' ' || c == '\n') -+ p++; -+ break; -+ } - } - *--t = '\0'; - return (p); -@@ -104,46 +101,46 @@ struct ttyent * getttyent(void) - register int c; - register char *p; - static char *line = NULL; -+ struct ttyent *retval = NULL; - - if (!tf && !setttyent()) -- return (NULL); -+ return (NULL); - - if (!line) { -- line = malloc(BUFSIZ); -+ line = malloc(BUFSIZ); - if (!line) - abort(); - } - -- __STDIO_ALWAYS_THREADLOCK(tf); -+ __STDIO_ALWAYS_THREADLOCK(tf); - - for (;;) { -- if (!fgets_unlocked(p = line, BUFSIZ, tf)) { -- __STDIO_ALWAYS_THREADUNLOCK(tf); -- return (NULL); -- } -- /* skip lines that are too big */ -- if (!index(p, '\n')) { -- while ((c = getc_unlocked(tf)) != '\n' && c != EOF) -- ; -- continue; -- } -- while (isspace(*p)) -- ++p; -- if (*p && *p != '#') -- break; -+ if (!fgets_unlocked(p = line, BUFSIZ, tf)) { -+ goto DONE; -+ } -+ /* skip lines that are too big */ -+ if (!index(p, '\n')) { -+ while ((c = getc_unlocked(tf)) != '\n' && c != EOF) -+ ; -+ continue; -+ } -+ while (isspace(*p)) -+ ++p; -+ if (*p && *p != '#') -+ break; - } - - zapchar = 0; - tty.ty_name = p; - p = skip(p); - if (!*(tty.ty_getty = p)) -- tty.ty_getty = tty.ty_type = NULL; -+ tty.ty_getty = tty.ty_type = NULL; - else { -- p = skip(p); -- if (!*(tty.ty_type = p)) -- tty.ty_type = NULL; -- else -- p = skip(p); -+ p = skip(p); -+ if (!*(tty.ty_type = p)) -+ tty.ty_type = NULL; -+ else -+ p = skip(p); - } - tty.ty_status = 0; - tty.ty_window = NULL; -@@ -151,43 +148,45 @@ struct ttyent * getttyent(void) - #define scmp(e) !strncmp(p, e, sizeof(e) - 1) && isspace(p[sizeof(e) - 1]) - #define vcmp(e) !strncmp(p, e, sizeof(e) - 1) && p[sizeof(e) - 1] == '=' - for (; *p; p = skip(p)) { -- if (scmp(_TTYS_OFF)) -- tty.ty_status &= ~TTY_ON; -- else if (scmp(_TTYS_ON)) -- tty.ty_status |= TTY_ON; -- else if (scmp(_TTYS_SECURE)) -- tty.ty_status |= TTY_SECURE; -- else if (vcmp(_TTYS_WINDOW)) -- tty.ty_window = value(p); -- else -- break; -+ if (scmp(_TTYS_OFF)) -+ tty.ty_status &= ~TTY_ON; -+ else if (scmp(_TTYS_ON)) -+ tty.ty_status |= TTY_ON; -+ else if (scmp(_TTYS_SECURE)) -+ tty.ty_status |= TTY_SECURE; -+ else if (vcmp(_TTYS_WINDOW)) -+ tty.ty_window = value(p); -+ else -+ break; - } -- /* We can release the lock only here since `zapchar' is global. */ -- __STDIO_ALWAYS_THREADUNLOCK(tf); - - if (zapchar == '#' || *p == '#') -- while ((c = *++p) == ' ' || c == '\t') -- ; -+ while ((c = *++p) == ' ' || c == '\t') -+ ; - tty.ty_comment = p; - if (*p == 0) -- tty.ty_comment = 0; -+ tty.ty_comment = 0; - if ((p = index(p, '\n'))) -- *p = '\0'; -- return (&tty); -+ *p = '\0'; -+ retval = &tty; -+ -+ DONE: -+ __STDIO_ALWAYS_THREADUNLOCK(tf); -+ return retval; - } - - int setttyent(void) - { - - if (tf) { -- rewind(tf); -- return (1); -+ rewind(tf); -+ return (1); - } else if ((tf = fopen(_PATH_TTYS, "r"))) { -- /* We do the locking ourselves. */ -+ /* We do the locking ourselves. */ - #ifdef __UCLIBC_HAS_THREADS__ -- __fsetlocking (tf, FSETLOCKING_BYCALLER); -+ __fsetlocking (tf, FSETLOCKING_BYCALLER); - #endif -- return (1); -+ return (1); - } - return (0); - } -@@ -197,9 +196,9 @@ int endttyent(void) - int rval; - - if (tf) { -- rval = !(fclose(tf) == EOF); -- tf = NULL; -- return (rval); -+ rval = !(fclose(tf) == EOF); -+ tf = NULL; -+ return (rval); - } - return (1); - } -diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c -index c1d8d6f..0fc6df4 100644 ---- a/libc/misc/utmp/utent.c -+++ b/libc/misc/utmp/utent.c -@@ -20,19 +20,9 @@ - #include <string.h> - #include <utmp.h> - -+#include <bits/uClibc_mutex.h> - -- --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t utmplock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&utmplock) --# define UNLOCK __pthread_mutex_unlock(&utmplock) --#else --# define LOCK --# define UNLOCK --#endif -- -- -+__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER); - - /* Some global crap */ - static int static_fd = -1; -@@ -46,19 +36,19 @@ static struct utmp *__getutent(int utmp_ - - { - if (utmp_fd == -1) { -- setutent(); -+ setutent(); - } - if (utmp_fd == -1) { -- return NULL; -+ return NULL; - } - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (read(utmp_fd, (char *) &static_utmp, sizeof(struct utmp)) != sizeof(struct utmp)) -- { -- return NULL; -- } -+ { -+ return NULL; -+ } - -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return &static_utmp; - } - -@@ -66,39 +56,39 @@ void setutent(void) - { - int ret; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (static_fd == -1) { -- if ((static_fd = open(static_ut_name, O_RDWR)) < 0) { -- if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) { -- goto bummer; -- } -- } -- /* Make sure the file will be closed on exec() */ -- ret = fcntl(static_fd, F_GETFD, 0); -- if (ret >= 0) { -- ret = fcntl(static_fd, F_GETFD, 0); -- } -- if (ret < 0) { --bummer: -- UNLOCK; -- static_fd = -1; -- close(static_fd); -- return; -- } -+ if ((static_fd = open(static_ut_name, O_RDWR)) < 0) { -+ if ((static_fd = open(static_ut_name, O_RDONLY)) < 0) { -+ goto bummer; -+ } -+ } -+ /* Make sure the file will be closed on exec() */ -+ ret = fcntl(static_fd, F_GETFD, 0); -+ if (ret >= 0) { -+ ret = fcntl(static_fd, F_GETFD, 0); -+ } -+ if (ret < 0) { -+ bummer: -+ close(static_fd); -+ static_fd = -1; -+ goto DONE; -+ } - } - lseek(static_fd, 0, SEEK_SET); -- UNLOCK; -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return; - } - - void endutent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (static_fd != -1) { -- close(static_fd); -+ close(static_fd); - } - static_fd = -1; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - } - - /* Locking is done in __getutent */ -@@ -113,22 +103,22 @@ struct utmp *getutid (const struct utmp - struct utmp *lutmp; - - while ((lutmp = __getutent(static_fd)) != NULL) { -- if ( (utmp_entry->ut_type == RUN_LVL || -- utmp_entry->ut_type == BOOT_TIME || -- utmp_entry->ut_type == NEW_TIME || -- utmp_entry->ut_type == OLD_TIME) && -- lutmp->ut_type == utmp_entry->ut_type) -- { -- return lutmp; -- } -- if ( (utmp_entry->ut_type == INIT_PROCESS || -- utmp_entry->ut_type == DEAD_PROCESS || -- utmp_entry->ut_type == LOGIN_PROCESS || -- utmp_entry->ut_type == USER_PROCESS) && -- !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) -- { -- return lutmp; -- } -+ if ( (utmp_entry->ut_type == RUN_LVL || -+ utmp_entry->ut_type == BOOT_TIME || -+ utmp_entry->ut_type == NEW_TIME || -+ utmp_entry->ut_type == OLD_TIME) && -+ lutmp->ut_type == utmp_entry->ut_type) -+ { -+ return lutmp; -+ } -+ if ( (utmp_entry->ut_type == INIT_PROCESS || -+ utmp_entry->ut_type == DEAD_PROCESS || -+ utmp_entry->ut_type == LOGIN_PROCESS || -+ utmp_entry->ut_type == USER_PROCESS) && -+ !strncmp(lutmp->ut_id, utmp_entry->ut_id, sizeof(lutmp->ut_id))) -+ { -+ return lutmp; -+ } - } - - return NULL; -@@ -140,11 +130,11 @@ struct utmp *getutline(const struct utmp - struct utmp *lutmp; - - while ((lutmp = __getutent(static_fd)) != NULL) { -- if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) && -- !strcmp(lutmp->ut_line, utmp_entry->ut_line)) -- { -- return lutmp; -- } -+ if ((lutmp->ut_type == USER_PROCESS || lutmp->ut_type == LOGIN_PROCESS) && -+ !strcmp(lutmp->ut_line, utmp_entry->ut_line)) -+ { -+ return lutmp; -+ } - } - - return NULL; -@@ -152,42 +142,42 @@ struct utmp *getutline(const struct utmp - - struct utmp *pututline (const struct utmp *utmp_entry) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - /* Ignore the return value. That way, if they've already positioned - the file pointer where they want it, everything will work out. */ - lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR); - - if (getutid(utmp_entry) != NULL) { -- lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR); -- if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -- return NULL; -+ lseek(static_fd, (off_t) - sizeof(struct utmp), SEEK_CUR); -+ if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -+ return NULL; - } else { -- lseek(static_fd, (off_t) 0, SEEK_END); -- if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -- return NULL; -+ lseek(static_fd, (off_t) 0, SEEK_END); -+ if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) -+ return NULL; - } - -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return (struct utmp *)utmp_entry; - } - - int utmpname (const char *new_ut_name) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(utmplock); - if (new_ut_name != NULL) { -- if (static_ut_name != default_file_name) -- free((char *)static_ut_name); -- static_ut_name = strdup(new_ut_name); -- if (static_ut_name == NULL) { -- /* We should probably whine about out-of-memory -- * errors here... Instead just reset to the default */ -- static_ut_name = default_file_name; -- } -+ if (static_ut_name != default_file_name) -+ free((char *)static_ut_name); -+ static_ut_name = strdup(new_ut_name); -+ if (static_ut_name == NULL) { -+ /* We should probably whine about out-of-memory -+ * errors here... Instead just reset to the default */ -+ static_ut_name = default_file_name; -+ } - } - - if (static_fd != -1) -- close(static_fd); -- UNLOCK; -+ close(static_fd); -+ __UCLIBC_MUTEX_UNLOCK(utmplock); - return 0; - } - -diff --git a/libc/misc/wchar/wstdio.c b/libc/misc/wchar/wstdio.c -index b49494f..408c57a 100644 ---- a/libc/misc/wchar/wstdio.c -+++ b/libc/misc/wchar/wstdio.c -@@ -82,9 +82,6 @@ strong_alias(NAME,NAME##_unlocked) \ - void NAME PARAMS - #endif - --#define __STDIO_THREADLOCK_OPENLIST --#define __STDIO_THREADUNLOCK_OPENLIST -- - #else /* __UCLIBC_HAS_THREADS__ */ - - #include <pthread.h> -@@ -112,15 +109,6 @@ void NAME PARAMS \ - } \ - void NAME##_unlocked PARAMS - --#define __STDIO_THREADLOCK_OPENLIST \ -- __pthread_mutex_lock(&_stdio_openlist_lock) -- --#define __STDIO_THREADUNLOCK_OPENLIST \ -- __pthread_mutex_unlock(&_stdio_openlist_lock) -- --#define __STDIO_THREADTRYLOCK_OPENLIST \ -- __pthread_mutex_trylock(&_stdio_openlist_lock) -- - #endif /* __UCLIBC_HAS_THREADS__ */ - - #ifndef __STDIO_BUFFERS -diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c -index 6b9c251..063fed4 100644 ---- a/libc/pwd_grp/lckpwdf.c -+++ b/libc/pwd_grp/lckpwdf.c -@@ -27,15 +27,9 @@ - #include <sys/file.h> - #include <paths.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* How long to wait for getting the lock before returning with an - error. */ -@@ -57,18 +51,18 @@ int lckpwdf (void) - struct sigaction new_act; /* New signal action. */ - struct flock fl; /* Information struct for locking. */ - int result; -+ int rv = -1; - - if (lock_fd != -1) - /* Still locked by own process. */ - return -1; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - lock_fd = open (_PATH_PASSWD, O_WRONLY); - if (lock_fd == -1) { - /* Cannot create lock file. */ -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Make sure file gets correctly closed when process finished. */ -@@ -77,16 +71,14 @@ int lckpwdf (void) - /* Cannot get file flags. */ - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - flags |= FD_CLOEXEC; /* Close on exit. */ - if (fcntl (lock_fd, F_SETFD, flags) < 0) { - /* Cannot set new flags. */ - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Now we have to get exclusive write access. Since multiple -@@ -107,8 +99,7 @@ int lckpwdf (void) - /* Cannot install signal handler. */ - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Now make sure the alarm signal is not blocked. */ -@@ -118,8 +109,7 @@ int lckpwdf (void) - sigaction (SIGALRM, &saved_act, NULL); - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - - /* Start timer. If we cannot get the lock in the specified time we -@@ -146,12 +136,14 @@ int lckpwdf (void) - if (result < 0) { - close(lock_fd); - lock_fd = -1; -- UNLOCK; -- return -1; -+ goto DONE; - } - -- UNLOCK; -- return 0; -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - -@@ -164,11 +156,11 @@ int ulckpwdf (void) - result = -1; - } - else { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - result = close (lock_fd); - /* Mark descriptor as unused. */ - lock_fd = -1; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - return result; -diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c -index 91c0d83..a302c7c 100644 ---- a/libc/pwd_grp/pwd_grp.c -+++ b/libc/pwd_grp/pwd_grp.c -@@ -42,9 +42,8 @@ - #include <pwd.h> - #include <grp.h> - #include <shadow.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif -+ -+#include <bits/uClibc_mutex.h> - - /**********************************************************************/ - /* Sizes for staticly allocated buffers. */ -@@ -445,34 +444,27 @@ int getpw(uid_t uid, char *buf) - /**********************************************************************/ - #ifdef L_getpwent_r - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static FILE *pwf /*= NULL*/; - - void setpwent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (pwf) { - rewind(pwf); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endpwent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (pwf) { - fclose(pwf); - pwf = NULL; - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - -@@ -482,7 +474,7 @@ int getpwent_r(struct passwd *__restrict - { - int rv; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - *result = NULL; /* In case of error... */ - -@@ -500,7 +492,7 @@ int getpwent_r(struct passwd *__restrict - } - - ERR: -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return rv; - } -@@ -509,34 +501,27 @@ int getpwent_r(struct passwd *__restrict - /**********************************************************************/ - #ifdef L_getgrent_r - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static FILE *grf /*= NULL*/; - - void setgrent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (grf) { - rewind(grf); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endgrent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (grf) { - fclose(grf); - grf = NULL; - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int getgrent_r(struct group *__restrict resultbuf, -@@ -545,7 +530,7 @@ int getgrent_r(struct group *__restrict - { - int rv; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - *result = NULL; /* In case of error... */ - -@@ -563,7 +548,7 @@ int getgrent_r(struct group *__restrict - } - - ERR: -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return rv; - } -@@ -572,34 +557,27 @@ int getgrent_r(struct group *__restrict - /**********************************************************************/ - #ifdef L_getspent_r - --#ifdef __UCLIBC_HAS_THREADS__ --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - static FILE *spf /*= NULL*/; - - void setspent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (spf) { - rewind(spf); - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - void endspent(void) - { -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if (spf) { - fclose(spf); - spf = NULL; - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - } - - int getspent_r(struct spwd *resultbuf, char *buffer, -@@ -607,7 +585,7 @@ int getspent_r(struct spwd *resultbuf, c - { - int rv; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - - *result = NULL; /* In case of error... */ - -@@ -625,7 +603,7 @@ int getspent_r(struct spwd *resultbuf, c - } - - ERR: -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return rv; - } -diff --git a/libc/stdio/_READ.c b/libc/stdio/_READ.c -index 7d3c38c..fe1bc91 100644 ---- a/libc/stdio/_READ.c -+++ b/libc/stdio/_READ.c -@@ -41,7 +41,7 @@ size_t __stdio_READ(register FILE *strea - #warning EINTR? - #endif - /* RETRY: */ -- if ((rv = __READ(stream, buf, bufsize)) <= 0) { -+ if ((rv = __READ(stream, (char *) buf, bufsize)) <= 0) { - if (rv == 0) { - __STDIO_STREAM_SET_EOF(stream); - } else { -diff --git a/libc/stdio/_WRITE.c b/libc/stdio/_WRITE.c -index d300d39..4131eb7 100644 ---- a/libc/stdio/_WRITE.c -+++ b/libc/stdio/_WRITE.c -@@ -47,7 +47,7 @@ size_t __stdio_WRITE(register FILE *stre - return bufsize; - } - stodo = (todo <= SSIZE_MAX) ? todo : SSIZE_MAX; -- if ((rv = __WRITE(stream, buf, stodo)) >= 0) { -+ if ((rv = __WRITE(stream, (char *) buf, stodo)) >= 0) { - #ifdef __UCLIBC_MJN3_ONLY__ - #warning TODO: Make custom stream write return check optional. - #endif -diff --git a/libc/stdio/_fopen.c b/libc/stdio/_fopen.c -index f7f5bb6..4984f11 100644 ---- a/libc/stdio/_fopen.c -+++ b/libc/stdio/_fopen.c -@@ -194,10 +194,23 @@ FILE *_stdio_fopen(intptr_t fname_or_mod - #endif - - #ifdef __STDIO_HAS_OPENLIST -- __STDIO_THREADLOCK_OPENLIST; -- stream->__nextopen = _stdio_openlist; /* New files are inserted at */ -- _stdio_openlist = stream; /* the head of the list. */ -- __STDIO_THREADUNLOCK_OPENLIST; -+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) -+ if (!(stream->__modeflags & __FLAG_FREEFILE)) -+ { -+ /* An freopen call so the file was never removed from the list. */ -+ } -+ else -+#endif -+ { -+ /* We have to lock the del mutex in case another thread wants to fclose() -+ * the last file. */ -+ __STDIO_THREADLOCK_OPENLIST_DEL; -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ stream->__nextopen = _stdio_openlist; /* New files are inserted at */ -+ _stdio_openlist = stream; /* the head of the list. */ -+ __STDIO_THREADUNLOCK_OPENLIST_ADD; -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; -+ } - #endif - - __STDIO_STREAM_VALIDATE(stream); -diff --git a/libc/stdio/_stdio.c b/libc/stdio/_stdio.c -index 4aae3c4..9cfe02c 100644 ---- a/libc/stdio/_stdio.c -+++ b/libc/stdio/_stdio.c -@@ -151,8 +151,12 @@ FILE *__stdout = _stdio_streams + 1; /* - FILE *_stdio_openlist = _stdio_streams; - - # ifdef __UCLIBC_HAS_THREADS__ --pthread_mutex_t _stdio_openlist_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; --int _stdio_openlist_delflag = 0; -+__UCLIBC_MUTEX_INIT(_stdio_openlist_add_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); -+#ifdef __STDIO_BUFFERS -+__UCLIBC_MUTEX_INIT(_stdio_openlist_del_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); -+volatile int _stdio_openlist_use_count = 0; -+int _stdio_openlist_del_count = 0; -+#endif - # endif - - #endif -@@ -162,10 +166,10 @@ int _stdio_openlist_delflag = 0; - /* 2 if threading not initialized and 0 otherwise; */ - int _stdio_user_locking = 2; - --void __stdio_init_mutex(pthread_mutex_t *m) -+void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) - { -- static const pthread_mutex_t __stdio_mutex_initializer -- = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -+ const __UCLIBC_MUTEX_STATIC(__stdio_mutex_initializer, -+ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); - - memcpy(m, &__stdio_mutex_initializer, sizeof(__stdio_mutex_initializer)); - } -@@ -184,7 +188,11 @@ void _stdio_term(void) - * locked, then I suppose there is a chance that a pointer in the - * chain might be corrupt due to a partial store. - */ -- __stdio_init_mutex(&_stdio_openlist_lock); -+ __stdio_init_mutex(&_stdio_openlist_add_lock); -+#warning check -+#ifdef __STDIO_BUFFERS -+ __stdio_init_mutex(&_stdio_openlist_del_lock); -+#endif - - /* Next we need to worry about the streams themselves. If a stream - * is currently locked, then it may be in an invalid state. So we -@@ -192,7 +200,7 @@ void _stdio_term(void) - * Then we reinitialize the locks. - */ - for (ptr = _stdio_openlist ; ptr ; ptr = ptr->__nextopen ) { -- if (__STDIO_ALWAYS_THREADTRYLOCK(ptr)) { -+ if (__STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(ptr)) { - /* The stream is already locked, so we don't want to touch it. - * However, if we have custom streams, we can't just close it - * or leave it locked since a custom stream may be stacked -@@ -258,10 +266,6 @@ void _stdio_init(void) - #error Assumption violated about __MASK_READING and __FLAG_UNGOT - #endif - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --#endif -- - #ifndef NDEBUG - - void _stdio_validate_FILE(const FILE *stream) -diff --git a/libc/stdio/_stdio.h b/libc/stdio/_stdio.h -index e3c2c58..decf57d 100644 ---- a/libc/stdio/_stdio.h -+++ b/libc/stdio/_stdio.h -@@ -22,23 +22,57 @@ - #include <wchar.h> - #endif - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> -+#include <bits/uClibc_mutex.h> - --#define __STDIO_THREADLOCK_OPENLIST \ -- __pthread_mutex_lock(&_stdio_openlist_lock) -+#define __STDIO_THREADLOCK_OPENLIST_ADD \ -+ __UCLIBC_MUTEX_LOCK(_stdio_openlist_add_lock) - --#define __STDIO_THREADUNLOCK_OPENLIST \ -- __pthread_mutex_unlock(&_stdio_openlist_lock) -+#define __STDIO_THREADUNLOCK_OPENLIST_ADD \ -+ __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_add_lock) - --#define __STDIO_THREADTRYLOCK_OPENLIST \ -- __pthread_mutex_trylock(&_stdio_openlist_lock) -+#ifdef __STDIO_BUFFERS - --#else -+#define __STDIO_THREADLOCK_OPENLIST_DEL \ -+ __UCLIBC_MUTEX_LOCK(_stdio_openlist_del_lock) -+ -+#define __STDIO_THREADUNLOCK_OPENLIST_DEL \ -+ __UCLIBC_MUTEX_UNLOCK(_stdio_openlist_del_lock) - --#define __STDIO_THREADLOCK_OPENLIST ((void)0) --#define __STDIO_THREADUNLOCK_OPENLIST ((void)0) -+#define __STDIO_OPENLIST_INC_USE \ -+do { \ -+ __STDIO_THREADLOCK_OPENLIST_DEL; \ -+ ++_stdio_openlist_use_count; \ -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \ -+} while (0) -+ -+extern void _stdio_openlist_dec_use(void); -+ -+#define __STDIO_OPENLIST_DEC_USE \ -+ _stdio_openlist_dec_use() -+ -+#define __STDIO_OPENLIST_INC_DEL_CNT \ -+do { \ -+ __STDIO_THREADLOCK_OPENLIST_DEL; \ -+ ++_stdio_openlist_del_count; \ -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \ -+} while (0) -+ -+#define __STDIO_OPENLIST_DEC_DEL_CNT \ -+do { \ -+ __STDIO_THREADLOCK_OPENLIST_DEL; \ -+ --_stdio_openlist_del_count; \ -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; \ -+} while (0) -+ -+#endif /* __STDIO_BUFFERS */ - -+#ifndef __STDIO_THREADLOCK_OPENLIST_DEL -+#define __STDIO_THREADLOCK_OPENLIST_DEL ((void)0) -+#define __STDIO_THREADUNLOCK_OPENLIST_DEL ((void)0) -+#define __STDIO_OPENLIST_INC_USE ((void)0) -+#define __STDIO_OPENLIST_DEC_USE ((void)0) -+#define __STDIO_OPENLIST_INC_DEL_CNT ((void)0) -+#define __STDIO_OPENLIST_DEC_DEL_CNT ((void)0) - #endif - - #define __UNDEFINED_OR_NONPORTABLE ((void)0) -diff --git a/libc/stdio/fclose.c b/libc/stdio/fclose.c -index 4df2e42..dfababc 100644 ---- a/libc/stdio/fclose.c -+++ b/libc/stdio/fclose.c -@@ -12,30 +12,34 @@ int fclose(register FILE *stream) - int rv = 0; - __STDIO_AUTO_THREADLOCK_VAR; - -- /* First, remove the file from the open file list. */ --#ifdef __STDIO_HAS_OPENLIST -- { -- register FILE *ptr; -- -- __STDIO_THREADLOCK_OPENLIST; -- if ((ptr = _stdio_openlist) == stream) { -- _stdio_openlist = stream->__nextopen; -- } else { -- while (ptr) { -- if (ptr->__nextopen == stream) { -- ptr->__nextopen = stream->__nextopen; -- break; -- } -- ptr = ptr->__nextopen; -- } -- } -- __STDIO_THREADUNLOCK_OPENLIST; -- -- if (!ptr) { /* Did not find stream in the open file list! */ -- return EOF; -- } -- } --#endif -+#warning dead code... but may want to simply check and not remove -+/* #ifdef __STDIO_HAS_OPENLIST */ -+/* #if !defined(__UCLIBC_HAS_THREADS__) || !defined(__STDIO_BUFFERS) */ -+/* /\* First, remove the file from the open file list. *\/ */ -+/* { */ -+/* register FILE *ptr; */ -+ -+/* __STDIO_THREADLOCK_OPENLIST; */ -+/* if ((ptr = _stdio_openlist) == stream) { */ -+/* #warning does a mod!!! */ -+/* _stdio_openlist = stream->__nextopen; */ -+/* } else { */ -+/* while (ptr) { */ -+/* if (ptr->__nextopen == stream) { */ -+/* ptr->__nextopen = stream->__nextopen; */ -+/* break; */ -+/* } */ -+/* ptr = ptr->__nextopen; */ -+/* } */ -+/* } */ -+/* __STDIO_THREADUNLOCK_OPENLIST; */ -+ -+/* if (!ptr) { /\* Did not find stream in the open file list! *\/ */ -+/* return EOF; */ -+/* } */ -+/* } */ -+/* #endif */ -+/* #endif */ - - __STDIO_AUTO_THREADLOCK(stream); - -@@ -80,7 +84,15 @@ int fclose(register FILE *stream) - __STDIO_AUTO_THREADUNLOCK(stream); - - __STDIO_STREAM_FREE_BUFFER(stream); -+#warning... inefficient - locks and unlocks twice and walks whole list -+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) -+ /* inefficient - locks/unlocks twice and walks whole list */ -+ __STDIO_OPENLIST_INC_USE; -+ __STDIO_OPENLIST_INC_DEL_CNT; -+ __STDIO_OPENLIST_DEC_USE; /* This with free the file if necessary. */ -+#else - __STDIO_STREAM_FREE_FILE(stream); -+#endif - - return rv; - } -diff --git a/libc/stdio/fcloseall.c b/libc/stdio/fcloseall.c -index dbb6000..f62281a 100644 ---- a/libc/stdio/fcloseall.c -+++ b/libc/stdio/fcloseall.c -@@ -19,14 +19,34 @@ int fcloseall (void) - #ifdef __STDIO_HAS_OPENLIST - - int retval = 0; -+ FILE *f; - -- __STDIO_THREADLOCK_OPENLIST; -- while (_stdio_openlist) { -- if (fclose(_stdio_openlist)) { -+#warning remove dead code -+/* __STDIO_THREADLOCK_OPENLIST; */ -+/* while (_stdio_openlist) { */ -+/* if (fclose(_stdio_openlist)) { */ -+/* retval = EOF; */ -+/* } */ -+/* } */ -+/* __STDIO_THREADUNLOCK_OPENLIST; */ -+ -+ __STDIO_OPENLIST_INC_USE; -+ -+#warning should probably have a get_head() operation -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ f = _stdio_openlist; -+ __STDIO_THREADUNLOCK_OPENLIST_ADD; -+ -+ while (f) { -+#warning should probably have a get_next() operation -+ FILE *n = f->__nextopen; -+ if (fclose(f)) { - retval = EOF; - } -+ f = n; - } -- __STDIO_THREADUNLOCK_OPENLIST; -+ -+ __STDIO_OPENLIST_DEC_USE; - - return retval; - -diff --git a/libc/stdio/fflush.c b/libc/stdio/fflush.c -index 6baa0ec..66b65cd 100644 ---- a/libc/stdio/fflush.c -+++ b/libc/stdio/fflush.c -@@ -20,23 +20,50 @@ weak_alias(__fflush_unlocked,fflush_unlo - weak_alias(__fflush_unlocked,fflush); - #endif - --#ifdef __UCLIBC_HAS_THREADS__ - /* Even if the stream is set to user-locking, we still need to lock - * when all (lbf) writing streams are flushed. */ --#define MY_STDIO_THREADLOCK(STREAM) \ -- if (_stdio_user_locking != 2) { \ -- __STDIO_ALWAYS_THREADLOCK(STREAM); \ -- } - --#define MY_STDIO_THREADUNLOCK(STREAM) \ -- if (_stdio_user_locking != 2) { \ -- __STDIO_ALWAYS_THREADUNLOCK(STREAM); \ -- } --#else --#define MY_STDIO_THREADLOCK(STREAM) ((void)0) --#define MY_STDIO_THREADUNLOCK(STREAM) ((void)0) --#endif -+#define __MY_STDIO_THREADLOCK(__stream) \ -+ __UCLIBC_MUTEX_CONDITIONAL_LOCK((__stream)->__lock, \ -+ (_stdio_user_locking != 2)) -+ -+#define __MY_STDIO_THREADUNLOCK(__stream) \ -+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK((__stream)->__lock, \ -+ (_stdio_user_locking != 2)) - -+#if defined(__UCLIBC_HAS_THREADS__) && defined(__STDIO_BUFFERS) -+void _stdio_openlist_dec_use(void) -+{ -+ __STDIO_THREADLOCK_OPENLIST_DEL; -+ if ((_stdio_openlist_use_count == 1) && (_stdio_openlist_del_count > 0)) { -+ FILE *p = NULL; -+ FILE *n; -+ FILE *stream; -+ -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ for (stream = _stdio_openlist; stream; stream = n) { -+#warning walk the list and clear out all fclosed()d files -+ n = stream->__nextopen; -+#warning fix for nonatomic -+ if ((stream->__modeflags & (__FLAG_READONLY|__FLAG_WRITEONLY)) -+ == (__FLAG_READONLY|__FLAG_WRITEONLY) -+ ) { /* The file was closed so remove from the list. */ -+ if (!p) { -+ _stdio_openlist = n; -+ } else { -+ p->__nextopen = n; -+ } -+ __STDIO_STREAM_FREE_FILE(stream); -+ } else { -+ p = stream; -+ } -+ } -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; -+ } -+ --_stdio_openlist_use_count; -+ __STDIO_THREADUNLOCK_OPENLIST_DEL; -+} -+#endif - - int __fflush_unlocked(register FILE *stream) - { -@@ -60,23 +87,39 @@ int __fflush_unlocked(register FILE *str - } - - if (!stream) { /* Flush all (lbf) writing streams. */ -- __STDIO_THREADLOCK_OPENLIST; -- for (stream = _stdio_openlist; stream ; stream = stream->__nextopen) { -- MY_STDIO_THREADLOCK(stream); -- if (!(((stream->__modeflags | bufmask) -- ^ (__FLAG_WRITING|__FLAG_LBF) -- ) & (__FLAG_WRITING|__MASK_BUFMODE)) -- ) { -- if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) { -- __STDIO_STREAM_DISABLE_PUTC(stream); -- __STDIO_STREAM_CLEAR_WRITING(stream); -- } else { -- retval = EOF; -+ -+ __STDIO_OPENLIST_INC_USE; -+ -+ __STDIO_THREADLOCK_OPENLIST_ADD; -+ stream = _stdio_openlist; -+ __STDIO_THREADUNLOCK_OPENLIST_ADD; -+ -+ while(stream) { -+ /* We only care about currently writing streams and do not want to -+ * block trying to obtain mutexes on non-writing streams. */ -+#warning fix for nonatomic -+#warning unnecessary check if no threads -+ if (__STDIO_STREAM_IS_WRITING(stream)) { /* ONLY IF ATOMIC!!! */ -+ __MY_STDIO_THREADLOCK(stream); -+ /* Need to check again once we have the lock. */ -+ if (!(((stream->__modeflags | bufmask) -+ ^ (__FLAG_WRITING|__FLAG_LBF) -+ ) & (__FLAG_WRITING|__MASK_BUFMODE)) -+ ) { -+ if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) { -+ __STDIO_STREAM_DISABLE_PUTC(stream); -+ __STDIO_STREAM_CLEAR_WRITING(stream); -+ } else { -+ retval = EOF; -+ } - } -+ __MY_STDIO_THREADUNLOCK(stream); - } -- MY_STDIO_THREADUNLOCK(stream); -+ stream = stream->__nextopen; - } -- __STDIO_THREADUNLOCK_OPENLIST; -+ -+ __STDIO_OPENLIST_DEC_USE; -+ - } else if (__STDIO_STREAM_IS_WRITING(stream)) { - if (!__STDIO_COMMIT_WRITE_BUFFER(stream)) { - __STDIO_STREAM_DISABLE_PUTC(stream); -diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c -index 0dcc7c2..3fad711 100644 ---- a/libc/stdio/flockfile.c -+++ b/libc/stdio/flockfile.c -@@ -11,6 +11,6 @@ void flockfile(FILE *stream) - { - __STDIO_STREAM_VALIDATE(stream); - -- __STDIO_ALWAYS_THREADLOCK(stream); -+ __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(stream); - } - -diff --git a/libc/stdio/freopen.c b/libc/stdio/freopen.c -index 0eccaac..36b8488 100644 ---- a/libc/stdio/freopen.c -+++ b/libc/stdio/freopen.c -@@ -42,6 +42,8 @@ FILE *freopen(const char * __restrict fi - - __STDIO_STREAM_VALIDATE(stream); - -+ __STDIO_OPENLIST_INC_USE; /* Do not remove the file from the list. */ -+ - /* First, flush and close, but don't deallocate, the stream. */ - /* This also removes the stream for the open file list. */ - dynmode = (stream->__modeflags & (__FLAG_FREEBUF|__FLAG_FREEFILE)); -@@ -57,9 +59,16 @@ FILE *freopen(const char * __restrict fi - - fp = _stdio_fopen(((intptr_t) filename), mode, stream, FILEDES_ARG); - -+#warning if fp is NULL, then we do not free file (but beware stdin,stdout,stderr) -+ if (fp) { -+ __STDIO_OPENLIST_DEC_DEL_CNT; -+ } -+ - /* Reset the allocation flags. */ - stream->__modeflags |= dynmode; - -+ __STDIO_OPENLIST_DEC_USE; -+ - __STDIO_AUTO_THREADUNLOCK(stream); - - return fp; -diff --git a/libc/stdio/ftello.c b/libc/stdio/ftello.c -index 7092f34..69385ce 100644 ---- a/libc/stdio/ftello.c -+++ b/libc/stdio/ftello.c -@@ -48,7 +48,10 @@ OFFSET_TYPE FTELL(register FILE *stream) - - __STDIO_STREAM_VALIDATE(stream); - -- if ((__SEEK(stream, &pos, SEEK_CUR) < 0) -+ if ((__SEEK(stream, &pos, -+ ((__STDIO_STREAM_IS_WRITING(stream) -+ && (stream->__modeflags & __FLAG_APPEND)) -+ ? SEEK_END : SEEK_CUR)) < 0) - || (__stdio_adjust_position(stream, &pos) < 0)) { - pos = -1; - } -diff --git a/libc/stdio/ftrylockfile.c b/libc/stdio/ftrylockfile.c -index d85b8ff..0d2e156 100644 ---- a/libc/stdio/ftrylockfile.c -+++ b/libc/stdio/ftrylockfile.c -@@ -15,5 +15,5 @@ int ftrylockfile(FILE *stream) - { - __STDIO_STREAM_VALIDATE(stream); - -- return __STDIO_ALWAYS_THREADTRYLOCK(stream); -+ return __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(stream); - } -diff --git a/libc/stdio/funlockfile.c b/libc/stdio/funlockfile.c -index 048c093..2ddf097 100644 ---- a/libc/stdio/funlockfile.c -+++ b/libc/stdio/funlockfile.c -@@ -11,5 +11,5 @@ void funlockfile(FILE *stream) - { - __STDIO_STREAM_VALIDATE(stream); - -- __STDIO_ALWAYS_THREADUNLOCK(stream); -+ __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(stream); - } -diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c -index c7887ad..ab8d296 100644 ---- a/libc/stdio/popen.c -+++ b/libc/stdio/popen.c -@@ -14,6 +14,7 @@ - * Fix failure exit code for failed execve(). - */ - -+#warning hmm... susv3 says "Pipe streams are byte-oriented." - - #include <stdio.h> - #include <stdlib.h> -@@ -21,6 +22,8 @@ - #include <unistd.h> - #include <sys/wait.h> - -+#include <bits/uClibc_mutex.h> -+ - /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */ - #include <sys/syscall.h> - #if ! defined __NR_vfork -@@ -29,19 +32,11 @@ - # define VFORK_UNLOCK ((void) 0) - #endif - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK ((void) 0) --# define UNLOCK ((void) 0) --#endif -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - #ifndef VFORK_LOCK --# define VFORK_LOCK LOCK --# define VFORK_UNLOCK UNLOCK -+# define VFORK_LOCK __UCLIBC_MUTEX_LOCK(mylock) -+# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock) - #endif - - struct popen_list_item { -@@ -118,10 +113,10 @@ FILE *popen(const char *command, const c - if (pid > 0) { /* Parent of vfork... */ - pi->pid = pid; - pi->f = fp; -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - pi->next = popen_list; - popen_list = pi; -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - return fp; - } -@@ -136,6 +131,8 @@ FILE *popen(const char *command, const c - return NULL; - } - -+#warning is pclose correct wrt the new mutex semantics? -+ - int pclose(FILE *stream) - { - struct popen_list_item *p; -@@ -144,7 +141,7 @@ int pclose(FILE *stream) - - /* First, find the list entry corresponding to stream and remove it - * from the list. Set p to the list item (NULL if not found). */ -- LOCK; -+ __UCLIBC_MUTEX_LOCK(mylock); - if ((p = popen_list) != NULL) { - if (p->f == stream) { - popen_list = p->next; -@@ -163,7 +160,7 @@ int pclose(FILE *stream) - } while (1); - } - } -- UNLOCK; -+ __UCLIBC_MUTEX_UNLOCK(mylock); - - if (p) { - pid = p->pid; /* Save the pid we need */ -diff --git a/libc/stdio/setvbuf.c b/libc/stdio/setvbuf.c -index 3fe62c6..6d53ab1 100644 ---- a/libc/stdio/setvbuf.c -+++ b/libc/stdio/setvbuf.c -@@ -75,8 +75,8 @@ int setvbuf(register FILE * __restrict s - } - - stream->__modeflags |= alloc_flag; -- stream->__bufstart = buf; -- stream->__bufend = buf + size; -+ stream->__bufstart = (unsigned char *) buf; -+ stream->__bufend = (unsigned char *) buf + size; - __STDIO_STREAM_INIT_BUFREAD_BUFPOS(stream); - __STDIO_STREAM_DISABLE_GETC(stream); - __STDIO_STREAM_DISABLE_PUTC(stream); -diff --git a/libc/stdio/vasprintf.c b/libc/stdio/vasprintf.c -index 688ab7c..6d7664d 100644 ---- a/libc/stdio/vasprintf.c -+++ b/libc/stdio/vasprintf.c -@@ -63,6 +63,8 @@ int vasprintf(char **__restrict buf, con - free(*buf); - *buf = NULL; - } -+ } else { -+ rv = -1; - } - } - -diff --git a/libc/stdio/vdprintf.c b/libc/stdio/vdprintf.c -index de8362c..7cb707f 100644 ---- a/libc/stdio/vdprintf.c -+++ b/libc/stdio/vdprintf.c -@@ -15,8 +15,8 @@ int vdprintf(int filedes, const char * _ - #ifdef __STDIO_BUFFERS - char buf[64]; /* TODO: provide _optional_ buffering? */ - -- f.__bufend = buf + sizeof(buf); -- f.__bufstart = buf; -+ f.__bufend = (unsigned char *) buf + sizeof(buf); -+ f.__bufstart = (unsigned char *) buf; - __STDIO_STREAM_DISABLE_GETC(&f); - __STDIO_STREAM_DISABLE_PUTC(&f); - __STDIO_STREAM_INIT_BUFREAD_BUFPOS(&f); -diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c -index 10114f0..9214e3b 100644 ---- a/libc/stdio/vfprintf.c -+++ b/libc/stdio/vfprintf.c -@@ -569,7 +569,7 @@ int _ppfs_init(register ppfs_t *ppfs, co - ppfs->fmtpos = fmt0; /* rewind */ - } - --#ifdef NL_MAX_ARG -+#ifdef NL_ARGMAX - /* If we have positional args, make sure we know all the types. */ - { - register int *p = ppfs->argtype; -@@ -581,7 +581,7 @@ int _ppfs_init(register ppfs_t *ppfs, co - ++p; - } - } --#endif /* NL_MAX_ARG */ -+#endif /* NL_ARGMAX */ - - return 0; - } -@@ -1214,7 +1214,7 @@ static size_t _fp_out_narrow(FILE *fp, i - } - len = buflen; - } -- return r + OUTNSTR(fp, (const char *) buf, len); -+ return r + OUTNSTR(fp, (const unsigned char *) buf, len); - } - - #endif /* __STDIO_PRINTF_FLOAT */ -diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c -index 77c2cdc..9f69918 100644 ---- a/libc/stdlib/abort.c -+++ b/libc/stdlib/abort.c -@@ -70,16 +70,9 @@ extern void _exit __P((int __status)) __ - static int 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; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock) --#else --# define LOCK --# define UNLOCK --#endif -+#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) -@@ -87,7 +80,7 @@ void abort(void) - sigset_t sigset; - - /* 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(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) { -@@ -110,9 +103,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/atexit.c b/libc/stdlib/atexit.c -index 280f42c..b028068 100644 ---- a/libc/stdlib/atexit.c -+++ b/libc/stdlib/atexit.c -@@ -40,17 +40,9 @@ - #include <stdlib.h> - #include <errno.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --extern pthread_mutex_t mylock; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -- -+__UCLIBC_MUTEX_EXTERN(__atexit_lock); - - typedef void (*aefuncp) (void); /* atexit function pointer */ - typedef void (*oefuncp) (int, void *); /* on_exit function pointer */ -@@ -90,8 +82,9 @@ extern struct exit_function __exit_funct - int atexit(aefuncp func) - { - struct exit_function *efp; -+ int rv = -1; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(__atexit_lock); - if (func) { - #ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* If we are out of function table slots, make some more */ -@@ -99,18 +92,16 @@ int atexit(aefuncp func) - efp=realloc(__exit_function_table, - (__exit_slots+20)*sizeof(struct exit_function)); - if (efp==NULL) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - __exit_function_table = efp; - __exit_slots+=20; - } - #else - if (__exit_count >= __UCLIBC_MAX_ATEXIT) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - #endif - __exit_cleanup = __exit_handler; /* enable cleanup */ -@@ -118,8 +109,12 @@ int atexit(aefuncp func) - efp->type = ef_atexit; - efp->funcs.atexit = func; - } -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(__atexit_lock); -+ return rv; - } - #endif - -@@ -133,8 +128,9 @@ int atexit(aefuncp func) - int on_exit(oefuncp func, void *arg) - { - struct exit_function *efp; -+ int rv = -1; - -- LOCK; -+ __UCLIBC_MUTEX_LOCK(__atexit_lock); - if (func) { - #ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* If we are out of function table slots, make some more */ -@@ -142,18 +138,16 @@ int on_exit(oefuncp func, void *arg) - efp=realloc(__exit_function_table, - (__exit_slots+20)*sizeof(struct exit_function)); - if (efp==NULL) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - __exit_function_table=efp; - __exit_slots+=20; - } - #else - if (__exit_count >= __UCLIBC_MAX_ATEXIT) { -- UNLOCK; - __set_errno(ENOMEM); -- return -1; -+ goto DONE; - } - #endif - -@@ -163,8 +157,12 @@ int on_exit(oefuncp func, void *arg) - efp->funcs.on_exit.func = func; - efp->funcs.on_exit.arg = arg; - } -- UNLOCK; -- return 0; -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(__atexit_lock); -+ return rv; - } - #endif - -@@ -214,9 +212,8 @@ void __exit_handler(int status) - #ifdef L_exit - extern void weak_function _stdio_term(void); - 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); - - #ifdef __UCLIBC_CTOR_DTOR__ - extern void (*__app_fini)(void); -@@ -229,11 +226,11 @@ extern void (*__rtld_fini)(void); - 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); - - #ifdef __UCLIBC_CTOR_DTOR__ - if (__app_fini != NULL) -diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c -index ed14c37..519a875 100644 ---- a/libc/stdlib/malloc-simple/alloc.c -+++ b/libc/stdlib/malloc-simple/alloc.c -@@ -108,15 +108,14 @@ 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; --# define LOCK __pthread_mutex_lock(&__malloc_lock) --# define UNLOCK __pthread_mutex_unlock(&__malloc_lock); --#else --# define LOCK --# define UNLOCK --#endif -+ -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_EXTERN(__malloc_lock); -+ -+#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 -@@ -135,7 +134,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 */ -@@ -146,7 +145,7 @@ int __libc_free_aligned(void *ptr) - return 1; - } - } -- UNLOCK; -+ __MALLOC_UNLOCK; - return 0; - } - void * memalign (size_t alignment, size_t size) -@@ -159,10 +158,10 @@ void * memalign (size_t alignment, size_ - return NULL; - - adj = (unsigned long int) ((unsigned long int) ((char *) result - -- (char *) NULL)) % alignment; -+ (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. */ -@@ -171,15 +170,16 @@ void * memalign (size_t alignment, 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 a67dad7..4277954 100644 ---- a/libc/stdlib/malloc-standard/calloc.c -+++ b/libc/stdlib/malloc-standard/calloc.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -31,63 +31,63 @@ void* calloc(size_t n_elements, size_t e - * to fall through and call malloc(0) */ - size = n_elements * elem_size; - if (n_elements && elem_size != (size / n_elements)) { -- __set_errno(ENOMEM); -- return NULL; -+ __set_errno(ENOMEM); -+ return NULL; - } - -- LOCK; -+ __MALLOC_LOCK; - mem = malloc(size); - if (mem != 0) { -- p = mem2chunk(mem); -+ p = mem2chunk(mem); - -- if (!chunk_is_mmapped(p)) -- { -- /* -- Unroll clear of <= 36 bytes (72 if 8byte sizes) -- We know that contents have an odd number of -- size_t-sized words; minimally 3. -- */ -- -- d = (size_t*)mem; -- clearsize = chunksize(p) - (sizeof(size_t)); -- nclears = clearsize / sizeof(size_t); -- assert(nclears >= 3); -- -- if (nclears > 9) -- memset(d, 0, clearsize); -- -- else { -- *(d+0) = 0; -- *(d+1) = 0; -- *(d+2) = 0; -- if (nclears > 4) { -- *(d+3) = 0; -- *(d+4) = 0; -- if (nclears > 6) { -- *(d+5) = 0; -- *(d+6) = 0; -- if (nclears > 8) { -- *(d+7) = 0; -- *(d+8) = 0; -+ if (!chunk_is_mmapped(p)) -+ { -+ /* -+ Unroll clear of <= 36 bytes (72 if 8byte sizes) -+ We know that contents have an odd number of -+ size_t-sized words; minimally 3. -+ */ -+ -+ d = (size_t*)mem; -+ clearsize = chunksize(p) - (sizeof(size_t)); -+ nclears = clearsize / sizeof(size_t); -+ assert(nclears >= 3); -+ -+ if (nclears > 9) -+ memset(d, 0, clearsize); -+ -+ else { -+ *(d+0) = 0; -+ *(d+1) = 0; -+ *(d+2) = 0; -+ if (nclears > 4) { -+ *(d+3) = 0; -+ *(d+4) = 0; -+ if (nclears > 6) { -+ *(d+5) = 0; -+ *(d+6) = 0; -+ if (nclears > 8) { -+ *(d+7) = 0; -+ *(d+8) = 0; -+ } -+ } -+ } -+ } - } -- } -- } -- } -- } - #if 0 -- else -- { -- /* Standard unix mmap using /dev/zero clears memory so calloc -- * doesn't need to actually zero anything.... -- */ -- d = (size_t*)mem; -- /* Note the additional (sizeof(size_t)) */ -- clearsize = chunksize(p) - 2*(sizeof(size_t)); -- memset(d, 0, clearsize); -- } -+ else -+ { -+ /* Standard unix mmap using /dev/zero clears memory so calloc -+ * doesn't need to actually zero anything.... -+ */ -+ d = (size_t*)mem; -+ /* Note the additional (sizeof(size_t)) */ -+ clearsize = chunksize(p) - 2*(sizeof(size_t)); -+ memset(d, 0, clearsize); -+ } - #endif - } -- UNLOCK; -+ __MALLOC_UNLOCK; - return mem; - } - -diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c -index 94e1d65..4e08ef7 100644 ---- a/libc/stdlib/malloc-standard/free.c -+++ b/libc/stdlib/malloc-standard/free.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -42,71 +42,71 @@ static int __malloc_trim(size_t pad, mst - - if (extra > 0) { - -- /* -- Only proceed if end of memory is where we last set it. -- This avoids problems if there were foreign sbrk calls. -- */ -- current_brk = (char*)(MORECORE(0)); -- if (current_brk == (char*)(av->top) + top_size) { -- -- /* -- Attempt to release memory. We ignore MORECORE return value, -- and instead call again to find out where new end of memory is. -- This avoids problems if first call releases less than we asked, -- of if failure somehow altered brk value. (We could still -- encounter problems if it altered brk in some very bad way, -- but the only thing we can do is adjust anyway, which will cause -- some downstream failure.) -- */ -- -- MORECORE(-extra); -- new_brk = (char*)(MORECORE(0)); -- -- if (new_brk != (char*)MORECORE_FAILURE) { -- released = (long)(current_brk - new_brk); -- -- if (released != 0) { -- /* Success. Adjust top. */ -- av->sbrked_mem -= released; -- set_head(av->top, (top_size - released) | PREV_INUSE); -- check_malloc_state(); -- return 1; -+ /* -+ Only proceed if end of memory is where we last set it. -+ This avoids problems if there were foreign sbrk calls. -+ */ -+ current_brk = (char*)(MORECORE(0)); -+ if (current_brk == (char*)(av->top) + top_size) { -+ -+ /* -+ Attempt to release memory. We ignore MORECORE return value, -+ and instead call again to find out where new end of memory is. -+ This avoids problems if first call releases less than we asked, -+ of if failure somehow altered brk value. (We could still -+ encounter problems if it altered brk in some very bad way, -+ but the only thing we can do is adjust anyway, which will cause -+ some downstream failure.) -+ */ -+ -+ MORECORE(-extra); -+ new_brk = (char*)(MORECORE(0)); -+ -+ if (new_brk != (char*)MORECORE_FAILURE) { -+ released = (long)(current_brk - new_brk); -+ -+ if (released != 0) { -+ /* Success. Adjust top. */ -+ av->sbrked_mem -= released; -+ set_head(av->top, (top_size - released) | PREV_INUSE); -+ check_malloc_state(); -+ return 1; -+ } -+ } - } -- } -- } - } - return 0; - } - - /* ------------------------- malloc_trim ------------------------- -- malloc_trim(size_t pad); -+ malloc_trim(size_t pad); - -- If possible, gives memory back to the system (via negative -- arguments to sbrk) if there is unused memory at the `high' end of -- the malloc pool. You can call this after freeing large blocks of -- memory to potentially reduce the system-level memory requirements -- of a program. However, it cannot guarantee to reduce memory. Under -- some allocation patterns, some large free blocks of memory will be -- locked between two used chunks, so they cannot be given back to -- the system. -- -- The `pad' argument to malloc_trim represents the amount of free -- trailing space to leave untrimmed. If this argument is zero, -- only the minimum amount of memory to maintain internal data -- structures will be left (one page or less). Non-zero arguments -- can be supplied to maintain enough trailing space to service -- future expected allocations without having to re-obtain memory -- from the system. -- -- Malloc_trim returns 1 if it actually released any memory, else 0. -- On systems that do not support "negative sbrks", it will always -- return 0. -+ If possible, gives memory back to the system (via negative -+ arguments to sbrk) if there is unused memory at the `high' end of -+ the malloc pool. You can call this after freeing large blocks of -+ memory to potentially reduce the system-level memory requirements -+ of a program. However, it cannot guarantee to reduce memory. Under -+ some allocation patterns, some large free blocks of memory will be -+ locked between two used chunks, so they cannot be given back to -+ the system. -+ -+ The `pad' argument to malloc_trim represents the amount of free -+ trailing space to leave untrimmed. If this argument is zero, -+ only the minimum amount of memory to maintain internal data -+ structures will be left (one page or less). Non-zero arguments -+ can be supplied to maintain enough trailing space to service -+ future expected allocations without having to re-obtain memory -+ from the system. -+ -+ Malloc_trim returns 1 if it actually released any memory, else 0. -+ On systems that do not support "negative sbrks", it will always -+ return 0. - */ - int malloc_trim(size_t pad) - { -- mstate av = get_malloc_state(); -- __malloc_consolidate(av); -- return __malloc_trim(pad, av); -+ mstate av = get_malloc_state(); -+ __malloc_consolidate(av); -+ return __malloc_trim(pad, av); - } - - /* -@@ -125,8 +125,8 @@ static void malloc_init_state(mstate av) - - /* Establish circular links for normal bins */ - for (i = 1; i < NBINS; ++i) { -- bin = bin_at(av,i); -- bin->fd = bin->bk = bin; -+ bin = bin_at(av,i); -+ bin->fd = bin->bk = bin; - } - - av->top_pad = DEFAULT_TOP_PAD; -@@ -157,15 +157,15 @@ static void malloc_init_state(mstate av) - - /* ------------------------- __malloc_consolidate ------------------------- - -- __malloc_consolidate is a specialized version of free() that tears -- down chunks held in fastbins. Free itself cannot be used for this -- purpose since, among other things, it might place chunks back onto -- fastbins. So, instead, we need to use a minor variant of the same -- code. -- -- Also, because this routine needs to be called the first time through -- malloc anyway, it turns out to be the perfect place to trigger -- initialization code. -+__malloc_consolidate is a specialized version of free() that tears -+down chunks held in fastbins. Free itself cannot be used for this -+purpose since, among other things, it might place chunks back onto -+fastbins. So, instead, we need to use a minor variant of the same -+code. -+ -+Also, because this routine needs to be called the first time through -+malloc anyway, it turns out to be the perfect place to trigger -+initialization code. - */ - void __malloc_consolidate(mstate av) - { -@@ -186,78 +186,78 @@ void __malloc_consolidate(mstate av) - mchunkptr fwd; - - /* -- If max_fast is 0, we know that av hasn't -- yet been initialized, in which case do so below -- */ -+ If max_fast is 0, we know that av hasn't -+ yet been initialized, in which case do so below -+ */ - - if (av->max_fast != 0) { -- clear_fastchunks(av); -+ clear_fastchunks(av); - -- unsorted_bin = unsorted_chunks(av); -+ unsorted_bin = unsorted_chunks(av); - -- /* -- Remove each chunk from fast bin and consolidate it, placing it -- then in unsorted bin. Among other reasons for doing this, -- placing in unsorted bin avoids needing to calculate actual bins -- until malloc is sure that chunks aren't immediately going to be -- reused anyway. -- */ -- -- maxfb = &(av->fastbins[fastbin_index(av->max_fast)]); -- fb = &(av->fastbins[0]); -- do { -- if ( (p = *fb) != 0) { -- *fb = 0; -+ /* -+ Remove each chunk from fast bin and consolidate it, placing it -+ then in unsorted bin. Among other reasons for doing this, -+ placing in unsorted bin avoids needing to calculate actual bins -+ until malloc is sure that chunks aren't immediately going to be -+ reused anyway. -+ */ - -+ maxfb = &(av->fastbins[fastbin_index(av->max_fast)]); -+ fb = &(av->fastbins[0]); - do { -- check_inuse_chunk(p); -- nextp = p->fd; -+ if ( (p = *fb) != 0) { -+ *fb = 0; - -- /* Slightly streamlined version of consolidation code in free() */ -- size = p->size & ~PREV_INUSE; -- nextchunk = chunk_at_offset(p, size); -- nextsize = chunksize(nextchunk); -+ do { -+ check_inuse_chunk(p); -+ nextp = p->fd; -+ -+ /* Slightly streamlined version of consolidation code in free() */ -+ size = p->size & ~PREV_INUSE; -+ nextchunk = chunk_at_offset(p, size); -+ nextsize = chunksize(nextchunk); -+ -+ if (!prev_inuse(p)) { -+ prevsize = p->prev_size; -+ size += prevsize; -+ p = chunk_at_offset(p, -((long) prevsize)); -+ unlink(p, bck, fwd); -+ } -+ -+ if (nextchunk != av->top) { -+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -+ set_head(nextchunk, nextsize); -+ -+ if (!nextinuse) { -+ size += nextsize; -+ unlink(nextchunk, bck, fwd); -+ } -+ -+ first_unsorted = unsorted_bin->fd; -+ unsorted_bin->fd = p; -+ first_unsorted->bk = p; -+ -+ set_head(p, size | PREV_INUSE); -+ p->bk = unsorted_bin; -+ p->fd = first_unsorted; -+ set_foot(p, size); -+ } -+ -+ else { -+ size += nextsize; -+ set_head(p, size | PREV_INUSE); -+ av->top = p; -+ } - -- if (!prev_inuse(p)) { -- prevsize = p->prev_size; -- size += prevsize; -- p = chunk_at_offset(p, -((long) prevsize)); -- unlink(p, bck, fwd); -- } -+ } while ( (p = nextp) != 0); - -- if (nextchunk != av->top) { -- nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -- set_head(nextchunk, nextsize); -- -- if (!nextinuse) { -- size += nextsize; -- unlink(nextchunk, bck, fwd); - } -- -- first_unsorted = unsorted_bin->fd; -- unsorted_bin->fd = p; -- first_unsorted->bk = p; -- -- set_head(p, size | PREV_INUSE); -- p->bk = unsorted_bin; -- p->fd = first_unsorted; -- set_foot(p, size); -- } -- -- else { -- size += nextsize; -- set_head(p, size | PREV_INUSE); -- av->top = p; -- } -- -- } while ( (p = nextp) != 0); -- -- } -- } while (fb++ != maxfb); -+ } while (fb++ != maxfb); - } - else { -- malloc_init_state(av); -- check_malloc_state(); -+ malloc_init_state(av); -+ check_malloc_state(); - } - } - -@@ -279,9 +279,9 @@ void free(void* mem) - - /* free(0) has no effect */ - if (mem == NULL) -- return; -+ return; - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - p = mem2chunk(mem); - size = chunksize(p); -@@ -289,9 +289,9 @@ void free(void* mem) - check_inuse_chunk(p); - - /* -- If eligible, place chunk on a fastbin so it can be found -- and used quickly in malloc. -- */ -+ If eligible, place chunk on a fastbin so it can be found -+ and used quickly in malloc. -+ */ - - if ((unsigned long)(size) <= (unsigned long)(av->max_fast) - -@@ -300,114 +300,114 @@ void free(void* mem) - bordering top into fastbins */ - && (chunk_at_offset(p, size) != av->top) - #endif -- ) { -+ ) { - -- set_fastchunks(av); -- fb = &(av->fastbins[fastbin_index(size)]); -- p->fd = *fb; -- *fb = p; -+ set_fastchunks(av); -+ fb = &(av->fastbins[fastbin_index(size)]); -+ p->fd = *fb; -+ *fb = p; - } - - /* -- Consolidate other non-mmapped chunks as they arrive. -- */ -+ Consolidate other non-mmapped chunks as they arrive. -+ */ - - else if (!chunk_is_mmapped(p)) { -- set_anychunks(av); -+ set_anychunks(av); -+ -+ nextchunk = chunk_at_offset(p, size); -+ nextsize = chunksize(nextchunk); -+ -+ /* consolidate backward */ -+ if (!prev_inuse(p)) { -+ prevsize = p->prev_size; -+ size += prevsize; -+ p = chunk_at_offset(p, -((long) prevsize)); -+ unlink(p, bck, fwd); -+ } -+ -+ if (nextchunk != av->top) { -+ /* get and clear inuse bit */ -+ nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -+ set_head(nextchunk, nextsize); -+ -+ /* consolidate forward */ -+ if (!nextinuse) { -+ unlink(nextchunk, bck, fwd); -+ size += nextsize; -+ } -+ -+ /* -+ Place the chunk in unsorted chunk list. Chunks are -+ not placed into regular bins until after they have -+ been given one chance to be used in malloc. -+ */ -+ -+ bck = unsorted_chunks(av); -+ fwd = bck->fd; -+ p->bk = bck; -+ p->fd = fwd; -+ bck->fd = p; -+ fwd->bk = p; - -- nextchunk = chunk_at_offset(p, size); -- nextsize = chunksize(nextchunk); -+ set_head(p, size | PREV_INUSE); -+ set_foot(p, size); -+ -+ check_free_chunk(p); -+ } -+ -+ /* -+ If the chunk borders the current high end of memory, -+ consolidate into top -+ */ - -- /* consolidate backward */ -- if (!prev_inuse(p)) { -- prevsize = p->prev_size; -- size += prevsize; -- p = chunk_at_offset(p, -((long) prevsize)); -- unlink(p, bck, fwd); -- } -- -- if (nextchunk != av->top) { -- /* get and clear inuse bit */ -- nextinuse = inuse_bit_at_offset(nextchunk, nextsize); -- set_head(nextchunk, nextsize); -- -- /* consolidate forward */ -- if (!nextinuse) { -- unlink(nextchunk, bck, fwd); -- size += nextsize; -- } -- -- /* -- Place the chunk in unsorted chunk list. Chunks are -- not placed into regular bins until after they have -- been given one chance to be used in malloc. -- */ -- -- bck = unsorted_chunks(av); -- fwd = bck->fd; -- p->bk = bck; -- p->fd = fwd; -- bck->fd = p; -- fwd->bk = p; -- -- set_head(p, size | PREV_INUSE); -- set_foot(p, size); -- -- check_free_chunk(p); -- } -- -- /* -- If the chunk borders the current high end of memory, -- consolidate into top -- */ -- -- else { -- size += nextsize; -- set_head(p, size | PREV_INUSE); -- av->top = p; -- check_chunk(p); -- } -- -- /* -- If freeing a large space, consolidate possibly-surrounding -- chunks. Then, if the total unused topmost memory exceeds trim -- threshold, ask malloc_trim to reduce top. -- -- Unless max_fast is 0, we don't know if there are fastbins -- bordering top, so we cannot tell for sure whether threshold -- has been reached unless fastbins are consolidated. But we -- don't want to consolidate on each free. As a compromise, -- consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD -- is reached. -- */ -- -- if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) { -- if (have_fastchunks(av)) -- __malloc_consolidate(av); -- -- if ((unsigned long)(chunksize(av->top)) >= -- (unsigned long)(av->trim_threshold)) -- __malloc_trim(av->top_pad, av); -- } -+ else { -+ size += nextsize; -+ set_head(p, size | PREV_INUSE); -+ av->top = p; -+ check_chunk(p); -+ } -+ -+ /* -+ If freeing a large space, consolidate possibly-surrounding -+ chunks. Then, if the total unused topmost memory exceeds trim -+ threshold, ask malloc_trim to reduce top. -+ -+ Unless max_fast is 0, we don't know if there are fastbins -+ bordering top, so we cannot tell for sure whether threshold -+ has been reached unless fastbins are consolidated. But we -+ don't want to consolidate on each free. As a compromise, -+ consolidation is performed if FASTBIN_CONSOLIDATION_THRESHOLD -+ is reached. -+ */ -+ -+ if ((unsigned long)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) { -+ if (have_fastchunks(av)) -+ __malloc_consolidate(av); -+ -+ if ((unsigned long)(chunksize(av->top)) >= -+ (unsigned long)(av->trim_threshold)) -+ __malloc_trim(av->top_pad, av); -+ } - - } - /* -- If the chunk was allocated via mmap, release via munmap() -- Note that if HAVE_MMAP is false but chunk_is_mmapped is -- true, then user must have overwritten memory. There's nothing -- we can do to catch this error unless DEBUG is set, in which case -- check_inuse_chunk (above) will have triggered error. -- */ -+ If the chunk was allocated via mmap, release via munmap() -+ Note that if HAVE_MMAP is false but chunk_is_mmapped is -+ true, then user must have overwritten memory. There's nothing -+ we can do to catch this error unless DEBUG is set, in which case -+ check_inuse_chunk (above) will have triggered error. -+ */ - - else { -- int ret; -- size_t offset = p->prev_size; -- av->n_mmaps--; -- av->mmapped_mem -= (size + offset); -- ret = munmap((char*)p - offset, size + offset); -- /* munmap returns non-zero on failure */ -- assert(ret == 0); -+ int ret; -+ size_t offset = p->prev_size; -+ av->n_mmaps--; -+ av->mmapped_mem -= (size + offset); -+ ret = munmap((char*)p - offset, size + offset); -+ /* munmap returns non-zero on failure */ -+ assert(ret == 0); - } -- UNLOCK; -+ __MALLOC_UNLOCK; - } - -diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c -index 51ac423..1e0875c 100644 ---- a/libc/stdlib/malloc-standard/mallinfo.c -+++ b/libc/stdlib/malloc-standard/mallinfo.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -30,11 +30,11 @@ struct mallinfo mallinfo(void) - int nblocks; - int nfastblocks; - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - /* Ensure initialization */ - if (av->top == 0) { -- __malloc_consolidate(av); -+ __malloc_consolidate(av); - } - - check_malloc_state(); -@@ -48,21 +48,21 @@ struct mallinfo mallinfo(void) - fastavail = 0; - - for (i = 0; i < NFASTBINS; ++i) { -- for (p = av->fastbins[i]; p != 0; p = p->fd) { -- ++nfastblocks; -- fastavail += chunksize(p); -- } -+ for (p = av->fastbins[i]; p != 0; p = p->fd) { -+ ++nfastblocks; -+ fastavail += chunksize(p); -+ } - } - - avail += fastavail; - - /* traverse regular bins */ - for (i = 1; i < NBINS; ++i) { -- b = bin_at(av, i); -- for (p = last(b); p != b; p = p->bk) { -- ++nblocks; -- avail += chunksize(p); -- } -+ b = bin_at(av, i); -+ for (p = last(b); p != b; p = p->bk) { -+ ++nblocks; -+ avail += chunksize(p); -+ } - } - - mi.smblks = nfastblocks; -@@ -75,7 +75,7 @@ struct mallinfo mallinfo(void) - mi.fsmblks = fastavail; - mi.keepcost = chunksize(av->top); - mi.usmblks = av->max_total_mem; -- UNLOCK; -+ __MALLOC_UNLOCK; - return mi; - } - -@@ -84,23 +84,40 @@ void malloc_stats(FILE *file) - struct mallinfo mi; - - if (file==NULL) { -- file = stderr; -+ file = stderr; - } - - 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 7025e83..60494a0 100644 ---- a/libc/stdlib/malloc-standard/malloc.c -+++ b/libc/stdlib/malloc-standard/malloc.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -17,17 +17,14 @@ - #define _GNU_SOURCE - #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. -- If you are adapting this malloc in a way that does NOT use a static -- malloc_state, you MUST explicitly zero-fill it before using. This -- malloc relies on the property that malloc_state is initialized to -- all zeroes (as is true of C statics). -+ There is exactly one instance of this struct in this malloc. -+ If you are adapting this malloc in a way that does NOT use a static -+ malloc_state, you MUST explicitly zero-fill it before using. This -+ malloc relies on the property that malloc_state is initialized to -+ all zeroes (as is true of C statics). - */ - struct malloc_state __malloc_state; /* never directly referenced */ - -@@ -77,30 +74,30 @@ void __do_check_chunk(mchunkptr p) - - if (!chunk_is_mmapped(p)) { - -- /* Has legal address ... */ -- if (p != av->top) { -- if (contiguous(av)) { -- assert(((char*)p) >= min_address); -- assert(((char*)p + sz) <= ((char*)(av->top))); -- } -- } -- else { -- /* top size is always at least MINSIZE */ -- assert((unsigned long)(sz) >= MINSIZE); -- /* top predecessor always marked inuse */ -- assert(prev_inuse(p)); -- } -+ /* Has legal address ... */ -+ if (p != av->top) { -+ if (contiguous(av)) { -+ assert(((char*)p) >= min_address); -+ assert(((char*)p + sz) <= ((char*)(av->top))); -+ } -+ } -+ else { -+ /* top size is always at least MINSIZE */ -+ assert((unsigned long)(sz) >= MINSIZE); -+ /* top predecessor always marked inuse */ -+ assert(prev_inuse(p)); -+ } - - } - else { -- /* address is outside main heap */ -- if (contiguous(av) && av->top != initial_top(av)) { -- assert(((char*)p) < min_address || ((char*)p) > max_address); -- } -- /* chunk is page-aligned */ -- assert(((p->prev_size + sz) & (av->pagesize-1)) == 0); -- /* mem is aligned */ -- assert(aligned_OK(chunk2mem(p))); -+ /* address is outside main heap */ -+ if (contiguous(av) && av->top != initial_top(av)) { -+ assert(((char*)p) < min_address || ((char*)p) > max_address); -+ } -+ /* chunk is page-aligned */ -+ assert(((p->prev_size + sz) & (av->pagesize-1)) == 0); -+ /* mem is aligned */ -+ assert(aligned_OK(chunk2mem(p))); - } - } - -@@ -121,21 +118,21 @@ void __do_check_free_chunk(mchunkptr p) - - /* Unless a special marker, must have OK fields */ - if ((unsigned long)(sz) >= MINSIZE) -- { -- assert((sz & MALLOC_ALIGN_MASK) == 0); -- assert(aligned_OK(chunk2mem(p))); -- /* ... matching footer field */ -- assert(next->prev_size == sz); -- /* ... and is fully consolidated */ -- assert(prev_inuse(p)); -- assert (next == av->top || inuse(next)); -- -- /* ... and has minimally sane links */ -- assert(p->fd->bk == p); -- assert(p->bk->fd == p); -- } -+ { -+ assert((sz & MALLOC_ALIGN_MASK) == 0); -+ assert(aligned_OK(chunk2mem(p))); -+ /* ... matching footer field */ -+ assert(next->prev_size == sz); -+ /* ... and is fully consolidated */ -+ assert(prev_inuse(p)); -+ assert (next == av->top || inuse(next)); -+ -+ /* ... and has minimally sane links */ -+ assert(p->fd->bk == p); -+ assert(p->bk->fd == p); -+ } - else /* markers are always of size (sizeof(size_t)) */ -- assert(sz == (sizeof(size_t))); -+ assert(sz == (sizeof(size_t))); - } - - /* Properties of inuse chunks */ -@@ -146,7 +143,7 @@ void __do_check_inuse_chunk(mchunkptr p) - __do_check_chunk(p); - - if (chunk_is_mmapped(p)) -- return; /* mmapped chunks have no next/prev */ -+ return; /* mmapped chunks have no next/prev */ - - /* Check whether it claims to be in use ... */ - assert(inuse(p)); -@@ -156,20 +153,20 @@ void __do_check_inuse_chunk(mchunkptr p) - /* ... and is surrounded by OK chunks. - Since more things can be checked with free chunks than inuse ones, - if an inuse chunk borders them and debug is on, it's worth doing them. -- */ -+ */ - if (!prev_inuse(p)) { -- /* Note that we cannot even look at prev unless it is not inuse */ -- mchunkptr prv = prev_chunk(p); -- assert(next_chunk(prv) == p); -- __do_check_free_chunk(prv); -+ /* Note that we cannot even look at prev unless it is not inuse */ -+ mchunkptr prv = prev_chunk(p); -+ assert(next_chunk(prv) == p); -+ __do_check_free_chunk(prv); - } - - if (next == av->top) { -- assert(prev_inuse(next)); -- assert(chunksize(next) >= MINSIZE); -+ assert(prev_inuse(next)); -+ assert(chunksize(next) >= MINSIZE); - } - else if (!inuse(next)) -- __do_check_free_chunk(next); -+ __do_check_free_chunk(next); - } - - /* Properties of chunks recycled from fastbins */ -@@ -198,14 +195,14 @@ void __do_check_malloced_chunk(mchunkptr - __do_check_remalloced_chunk(p, s); - - /* -- ... plus, must obey implementation invariant that prev_inuse is -- always true of any allocated chunk; i.e., that each allocated -- chunk borders either a previously allocated and still in-use -- chunk, or the base of its memory arena. This is ensured -- by making all allocations from the the `lowest' part of any found -- chunk. This does not necessarily hold however for chunks -- recycled via fastbins. -- */ -+ ... plus, must obey implementation invariant that prev_inuse is -+ always true of any allocated chunk; i.e., that each allocated -+ chunk borders either a previously allocated and still in-use -+ chunk, or the base of its memory arena. This is ensured -+ by making all allocations from the the `lowest' part of any found -+ chunk. This does not necessarily hold however for chunks -+ recycled via fastbins. -+ */ - - assert(prev_inuse(p)); - } -@@ -243,7 +240,7 @@ void __do_check_malloc_state(void) - - /* cannot run remaining checks until fully initialized */ - if (av->top == 0 || av->top == initial_top(av)) -- return; -+ return; - - /* pagesize is a power of 2 */ - assert((av->pagesize & (av->pagesize-1)) == 0); -@@ -256,64 +253,64 @@ void __do_check_malloc_state(void) - max_fast_bin = fastbin_index(av->max_fast); - - for (i = 0; i < NFASTBINS; ++i) { -- p = av->fastbins[i]; -+ p = av->fastbins[i]; - -- /* all bins past max_fast are empty */ -- if (i > max_fast_bin) -- assert(p == 0); -- -- while (p != 0) { -- /* each chunk claims to be inuse */ -- __do_check_inuse_chunk(p); -- total += chunksize(p); -- /* chunk belongs in this bin */ -- assert(fastbin_index(chunksize(p)) == i); -- p = p->fd; -- } -+ /* all bins past max_fast are empty */ -+ if (i > max_fast_bin) -+ assert(p == 0); -+ -+ while (p != 0) { -+ /* each chunk claims to be inuse */ -+ __do_check_inuse_chunk(p); -+ total += chunksize(p); -+ /* chunk belongs in this bin */ -+ assert(fastbin_index(chunksize(p)) == i); -+ p = p->fd; -+ } - } - - if (total != 0) -- assert(have_fastchunks(av)); -+ assert(have_fastchunks(av)); - else if (!have_fastchunks(av)) -- assert(total == 0); -+ assert(total == 0); - - /* check normal bins */ - for (i = 1; i < NBINS; ++i) { -- b = bin_at(av,i); -+ b = bin_at(av,i); - -- /* binmap is accurate (except for bin 1 == unsorted_chunks) */ -- if (i >= 2) { -- binbit = get_binmap(av,i); -- empty = last(b) == b; -- if (!binbit) -- assert(empty); -- else if (!empty) -- assert(binbit); -- } -- -- for (p = last(b); p != b; p = p->bk) { -- /* each chunk claims to be free */ -- __do_check_free_chunk(p); -- size = chunksize(p); -- total += size; -- if (i >= 2) { -- /* chunk belongs in bin */ -- idx = bin_index(size); -- assert(idx == i); -- /* lists are sorted */ -- if ((unsigned long) size >= (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -- assert(p->bk == b || -- (unsigned long)chunksize(p->bk) >= -- (unsigned long)chunksize(p)); -- } -- } -- /* chunk is followed by a legal chain of inuse chunks */ -- for (q = next_chunk(p); -- (q != av->top && inuse(q) && -- (unsigned long)(chunksize(q)) >= MINSIZE); -- q = next_chunk(q)) -- __do_check_inuse_chunk(q); -- } -+ /* binmap is accurate (except for bin 1 == unsorted_chunks) */ -+ if (i >= 2) { -+ binbit = get_binmap(av,i); -+ empty = last(b) == b; -+ if (!binbit) -+ assert(empty); -+ else if (!empty) -+ assert(binbit); -+ } -+ -+ for (p = last(b); p != b; p = p->bk) { -+ /* each chunk claims to be free */ -+ __do_check_free_chunk(p); -+ size = chunksize(p); -+ total += size; -+ if (i >= 2) { -+ /* chunk belongs in bin */ -+ idx = bin_index(size); -+ assert(idx == i); -+ /* lists are sorted */ -+ if ((unsigned long) size >= (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -+ assert(p->bk == b || -+ (unsigned long)chunksize(p->bk) >= -+ (unsigned long)chunksize(p)); -+ } -+ } -+ /* chunk is followed by a legal chain of inuse chunks */ -+ for (q = next_chunk(p); -+ (q != av->top && inuse(q) && -+ (unsigned long)(chunksize(q)) >= MINSIZE); -+ q = next_chunk(q)) -+ __do_check_inuse_chunk(q); -+ } - } - - /* top chunk is OK */ -@@ -326,13 +323,13 @@ void __do_check_malloc_state(void) - assert(av->n_mmaps <= av->max_n_mmaps); - - assert((unsigned long)(av->sbrked_mem) <= -- (unsigned long)(av->max_sbrked_mem)); -+ (unsigned long)(av->max_sbrked_mem)); - - assert((unsigned long)(av->mmapped_mem) <= -- (unsigned long)(av->max_mmapped_mem)); -+ (unsigned long)(av->max_mmapped_mem)); - - assert((unsigned long)(av->max_total_mem) >= -- (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem)); -+ (unsigned long)(av->mmapped_mem) + (unsigned long)(av->sbrked_mem)); - } - #endif - -@@ -370,84 +367,84 @@ static void* __malloc_alloc(size_t nb, m - size_t pagemask = av->pagesize - 1; - - /* -- If there is space available in fastbins, consolidate and retry -- malloc from scratch rather than getting memory from system. This -- can occur only if nb is in smallbin range so we didn't consolidate -- upon entry to malloc. It is much easier to handle this case here -- than in malloc proper. -- */ -+ If there is space available in fastbins, consolidate and retry -+ malloc from scratch rather than getting memory from system. This -+ can occur only if nb is in smallbin range so we didn't consolidate -+ upon entry to malloc. It is much easier to handle this case here -+ than in malloc proper. -+ */ - - if (have_fastchunks(av)) { -- assert(in_smallbin_range(nb)); -- __malloc_consolidate(av); -- return malloc(nb - MALLOC_ALIGN_MASK); -+ assert(in_smallbin_range(nb)); -+ __malloc_consolidate(av); -+ return malloc(nb - MALLOC_ALIGN_MASK); - } - - - /* -- If have mmap, and the request size meets the mmap threshold, and -- the system supports mmap, and there are few enough currently -- allocated mmapped regions, try to directly map this request -- rather than expanding top. -- */ -+ If have mmap, and the request size meets the mmap threshold, and -+ the system supports mmap, and there are few enough currently -+ allocated mmapped regions, try to directly map this request -+ rather than expanding top. -+ */ - - if ((unsigned long)(nb) >= (unsigned long)(av->mmap_threshold) && - (av->n_mmaps < av->n_mmaps_max)) { - -- char* mm; /* return value from mmap call*/ -- -- /* -- Round up size to nearest page. For mmapped chunks, the overhead -- is one (sizeof(size_t)) unit larger than for normal chunks, because there -- is no following chunk whose prev_size field could be used. -- */ -- size = (nb + (sizeof(size_t)) + MALLOC_ALIGN_MASK + pagemask) & ~pagemask; -- -- /* Don't try if size wraps around 0 */ -- if ((unsigned long)(size) > (unsigned long)(nb)) { -- -- mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -- -- if (mm != (char*)(MORECORE_FAILURE)) { -+ char* mm; /* return value from mmap call*/ - - /* -- The offset to the start of the mmapped region is stored -- in the prev_size field of the chunk. This allows us to adjust -- returned start address to meet alignment requirements here -- and in memalign(), and still be able to compute proper -- address argument for later munmap in free() and realloc(). -- */ -- -- front_misalign = (size_t)chunk2mem(mm) & MALLOC_ALIGN_MASK; -- if (front_misalign > 0) { -- correction = MALLOC_ALIGNMENT - front_misalign; -- p = (mchunkptr)(mm + correction); -- p->prev_size = correction; -- set_head(p, (size - correction) |IS_MMAPPED); -- } -- else { -- p = (mchunkptr)mm; -- p->prev_size = 0; -- set_head(p, size|IS_MMAPPED); -- } -+ Round up size to nearest page. For mmapped chunks, the overhead -+ is one (sizeof(size_t)) unit larger than for normal chunks, because there -+ is no following chunk whose prev_size field could be used. -+ */ -+ size = (nb + (sizeof(size_t)) + MALLOC_ALIGN_MASK + pagemask) & ~pagemask; -+ -+ /* Don't try if size wraps around 0 */ -+ if ((unsigned long)(size) > (unsigned long)(nb)) { -+ -+ mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -+ -+ if (mm != (char*)(MORECORE_FAILURE)) { -+ -+ /* -+ The offset to the start of the mmapped region is stored -+ in the prev_size field of the chunk. This allows us to adjust -+ returned start address to meet alignment requirements here -+ and in memalign(), and still be able to compute proper -+ address argument for later munmap in free() and realloc(). -+ */ -+ -+ front_misalign = (size_t)chunk2mem(mm) & MALLOC_ALIGN_MASK; -+ if (front_misalign > 0) { -+ correction = MALLOC_ALIGNMENT - front_misalign; -+ p = (mchunkptr)(mm + correction); -+ p->prev_size = correction; -+ set_head(p, (size - correction) |IS_MMAPPED); -+ } -+ else { -+ p = (mchunkptr)mm; -+ p->prev_size = 0; -+ set_head(p, size|IS_MMAPPED); -+ } -+ -+ /* update statistics */ -+ -+ if (++av->n_mmaps > av->max_n_mmaps) -+ av->max_n_mmaps = av->n_mmaps; -+ -+ sum = av->mmapped_mem += size; -+ if (sum > (unsigned long)(av->max_mmapped_mem)) -+ av->max_mmapped_mem = sum; -+ sum += av->sbrked_mem; -+ if (sum > (unsigned long)(av->max_total_mem)) -+ av->max_total_mem = sum; - -- /* update statistics */ -+ check_chunk(p); - -- if (++av->n_mmaps > av->max_n_mmaps) -- av->max_n_mmaps = av->n_mmaps; -- -- sum = av->mmapped_mem += size; -- if (sum > (unsigned long)(av->max_mmapped_mem)) -- av->max_mmapped_mem = sum; -- sum += av->sbrked_mem; -- if (sum > (unsigned long)(av->max_total_mem)) -- av->max_total_mem = sum; -- -- check_chunk(p); -- -- return chunk2mem(p); -- } -- } -+ return chunk2mem(p); -+ } -+ } - } - - /* Record incoming configuration of top */ -@@ -462,8 +459,8 @@ static void* __malloc_alloc(size_t nb, m - * be at least MINSIZE and to have prev_inuse set. */ - - assert((old_top == initial_top(av) && old_size == 0) || -- ((unsigned long) (old_size) >= MINSIZE && -- prev_inuse(old_top))); -+ ((unsigned long) (old_size) >= MINSIZE && -+ prev_inuse(old_top))); - - /* Precondition: not enough current space to satisfy nb request */ - assert((unsigned long)(old_size) < (unsigned long)(nb + MINSIZE)); -@@ -477,272 +474,272 @@ static void* __malloc_alloc(size_t nb, m - size = nb + av->top_pad + MINSIZE; - - /* -- If contiguous, we can subtract out existing space that we hope to -- combine with new space. We add it back later only if -- we don't actually get contiguous space. -- */ -+ If contiguous, we can subtract out existing space that we hope to -+ combine with new space. We add it back later only if -+ we don't actually get contiguous space. -+ */ - - if (contiguous(av)) -- size -= old_size; -+ size -= old_size; - - /* -- Round to a multiple of page size. -- If MORECORE is not contiguous, this ensures that we only call it -- with whole-page arguments. And if MORECORE is contiguous and -- this is not first time through, this preserves page-alignment of -- previous calls. Otherwise, we correct to page-align below. -- */ -+ Round to a multiple of page size. -+ If MORECORE is not contiguous, this ensures that we only call it -+ with whole-page arguments. And if MORECORE is contiguous and -+ this is not first time through, this preserves page-alignment of -+ previous calls. Otherwise, we correct to page-align below. -+ */ - - size = (size + pagemask) & ~pagemask; - - /* -- Don't try to call MORECORE if argument is so big as to appear -- negative. Note that since mmap takes size_t arg, it may succeed -- below even if we cannot call MORECORE. -- */ -+ Don't try to call MORECORE if argument is so big as to appear -+ negative. Note that since mmap takes size_t arg, it may succeed -+ below even if we cannot call MORECORE. -+ */ - - if (size > 0) -- brk = (char*)(MORECORE(size)); -+ brk = (char*)(MORECORE(size)); - - /* -- If have mmap, try using it as a backup when MORECORE fails or -- cannot be used. This is worth doing on systems that have "holes" in -- address space, so sbrk cannot extend to give contiguous space, but -- space is available elsewhere. Note that we ignore mmap max count -- and threshold limits, since the space will not be used as a -- segregated mmap region. -- */ -+ If have mmap, try using it as a backup when MORECORE fails or -+ cannot be used. This is worth doing on systems that have "holes" in -+ address space, so sbrk cannot extend to give contiguous space, but -+ space is available elsewhere. Note that we ignore mmap max count -+ and threshold limits, since the space will not be used as a -+ segregated mmap region. -+ */ - - if (brk == (char*)(MORECORE_FAILURE)) { - -- /* Cannot merge with old top, so add its size back in */ -- if (contiguous(av)) -- size = (size + old_size + pagemask) & ~pagemask; -- -- /* If we are relying on mmap as backup, then use larger units */ -- if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE)) -- size = MMAP_AS_MORECORE_SIZE; -- -- /* Don't try if size wraps around 0 */ -- if ((unsigned long)(size) > (unsigned long)(nb)) { -- -- brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -- -- if (brk != (char*)(MORECORE_FAILURE)) { -- -- /* We do not need, and cannot use, another sbrk call to find end */ -- snd_brk = brk + size; -- -- /* Record that we no longer have a contiguous sbrk region. -- After the first time mmap is used as backup, we do not -- ever rely on contiguous space since this could incorrectly -- bridge regions. -- */ -- set_noncontiguous(av); -- } -- } -+ /* Cannot merge with old top, so add its size back in */ -+ if (contiguous(av)) -+ size = (size + old_size + pagemask) & ~pagemask; -+ -+ /* If we are relying on mmap as backup, then use larger units */ -+ if ((unsigned long)(size) < (unsigned long)(MMAP_AS_MORECORE_SIZE)) -+ size = MMAP_AS_MORECORE_SIZE; -+ -+ /* Don't try if size wraps around 0 */ -+ if ((unsigned long)(size) > (unsigned long)(nb)) { -+ -+ brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE)); -+ -+ if (brk != (char*)(MORECORE_FAILURE)) { -+ -+ /* We do not need, and cannot use, another sbrk call to find end */ -+ snd_brk = brk + size; -+ -+ /* Record that we no longer have a contiguous sbrk region. -+ After the first time mmap is used as backup, we do not -+ ever rely on contiguous space since this could incorrectly -+ bridge regions. -+ */ -+ set_noncontiguous(av); -+ } -+ } - } - - if (brk != (char*)(MORECORE_FAILURE)) { -- av->sbrked_mem += size; -+ av->sbrked_mem += size; - -- /* -- If MORECORE extends previous space, we can likewise extend top size. -- */ -- -- if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { -- set_head(old_top, (size + old_size) | PREV_INUSE); -- } -- -- /* -- Otherwise, make adjustments: -- -- * If the first time through or noncontiguous, we need to call sbrk -- just to find out where the end of memory lies. -- -- * We need to ensure that all returned chunks from malloc will meet -- MALLOC_ALIGNMENT -- -- * If there was an intervening foreign sbrk, we need to adjust sbrk -- request size to account for fact that we will not be able to -- combine new space with existing space in old_top. -- -- * Almost all systems internally allocate whole pages at a time, in -- which case we might as well use the whole last page of request. -- So we allocate enough more memory to hit a page boundary now, -- which in turn causes future contiguous calls to page-align. -- */ -- -- else { -- front_misalign = 0; -- end_misalign = 0; -- correction = 0; -- aligned_brk = brk; -- -- /* -- If MORECORE returns an address lower than we have seen before, -- we know it isn't really contiguous. This and some subsequent -- checks help cope with non-conforming MORECORE functions and -- the presence of "foreign" calls to MORECORE from outside of -- 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) { -- set_noncontiguous(av); -- } -- -- /* handle contiguous cases */ -- if (contiguous(av)) { -- -- /* We can tolerate forward non-contiguities here (usually due -- to foreign calls) but treat them as part of our space for -- stats reporting. */ -- if (old_size != 0) -- av->sbrked_mem += brk - old_end; -- -- /* Guarantee alignment of first new chunk made from this space */ -- -- front_misalign = (size_t)chunk2mem(brk) & MALLOC_ALIGN_MASK; -- if (front_misalign > 0) { -- -- /* -- Skip over some bytes to arrive at an aligned position. -- We don't need to specially mark these wasted front bytes. -- They will never be accessed anyway because -- prev_inuse of av->top (and any chunk created from its start) -- is always true after initialization. -- */ -+ /* -+ If MORECORE extends previous space, we can likewise extend top size. -+ */ - -- correction = MALLOC_ALIGNMENT - front_misalign; -- aligned_brk += correction; -+ if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { -+ set_head(old_top, (size + old_size) | PREV_INUSE); - } - - /* -- If this isn't adjacent to existing space, then we will not -- be able to merge with old_top space, so must add to 2nd request. -- */ -- -- correction += old_size; -- -- /* Extend the end address to hit a page boundary */ -- end_misalign = (size_t)(brk + size + correction); -- correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; -- -- assert(correction >= 0); -- snd_brk = (char*)(MORECORE(correction)); -- -- if (snd_brk == (char*)(MORECORE_FAILURE)) { -- /* -- If can't allocate correction, try to at least find out current -- brk. It might be enough to proceed without failing. -- */ -- correction = 0; -- snd_brk = (char*)(MORECORE(0)); -- } -- else if (snd_brk < brk) { -- /* -- If the second call gives noncontiguous space even though -- it says it won't, the only course of action is to ignore -- results of second call, and conservatively estimate where -- the first call left us. Also set noncontiguous, so this -- won't happen again, leaving at most one hole. -- -- Note that this check is intrinsically incomplete. Because -- MORECORE is allowed to give more space than we ask for, -- there is no reliable way to detect a noncontiguity -- producing a forward gap for the second call. -- */ -- snd_brk = brk + size; -- correction = 0; -- set_noncontiguous(av); -- } -- -- } -- -- /* handle non-contiguous cases */ -- else { -- /* MORECORE/mmap must correctly align */ -- assert(aligned_OK(chunk2mem(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; -- } -- } -- -- /* Adjust top based on results of second sbrk */ -- if (snd_brk != (char*)(MORECORE_FAILURE)) { -- av->top = (mchunkptr)aligned_brk; -- set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); -- av->sbrked_mem += correction; -+ Otherwise, make adjustments: - -- /* -- If not the first time through, we either have a -- gap due to foreign sbrk or a non-contiguous region. Insert a -- double fencepost at old_top to prevent consolidation with space -- we don't own. These fenceposts are artificial chunks that are -- marked as inuse and are in any case too small to use. We need -- two to make sizes and alignments work out. -- */ -- -- if (old_size != 0) { -- /* Shrink old_top to insert fenceposts, keeping size a -- multiple of MALLOC_ALIGNMENT. We know there is at least -- enough space in old_top to do this. -- */ -- old_size = (old_size - 3*(sizeof(size_t))) & ~MALLOC_ALIGN_MASK; -- set_head(old_top, old_size | PREV_INUSE); -- -- /* -- Note that the following assignments completely overwrite -- old_top when old_size was previously MINSIZE. This is -- intentional. We need the fencepost, even if old_top otherwise gets -- lost. -- */ -- chunk_at_offset(old_top, old_size )->size = -- (sizeof(size_t))|PREV_INUSE; -- -- chunk_at_offset(old_top, old_size + (sizeof(size_t)))->size = -- (sizeof(size_t))|PREV_INUSE; -- -- /* If possible, release the rest, suppressing trimming. */ -- if (old_size >= MINSIZE) { -- size_t tt = av->trim_threshold; -- av->trim_threshold = (size_t)(-1); -- free(chunk2mem(old_top)); -- av->trim_threshold = tt; -- } -- } -- } -- } -- -- /* Update statistics */ -- sum = av->sbrked_mem; -- if (sum > (unsigned long)(av->max_sbrked_mem)) -- av->max_sbrked_mem = sum; -- -- sum += av->mmapped_mem; -- if (sum > (unsigned long)(av->max_total_mem)) -- av->max_total_mem = sum; -- -- check_malloc_state(); -- -- /* finally, do the allocation */ -- -- p = av->top; -- size = chunksize(p); -- -- /* check that one of the above allocation paths succeeded */ -- if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) { -- remainder_size = size - nb; -- remainder = chunk_at_offset(p, nb); -- av->top = remainder; -- set_head(p, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- check_malloced_chunk(p, nb); -- return chunk2mem(p); -- } -+ * If the first time through or noncontiguous, we need to call sbrk -+ just to find out where the end of memory lies. -+ -+ * We need to ensure that all returned chunks from malloc will meet -+ MALLOC_ALIGNMENT -+ -+ * If there was an intervening foreign sbrk, we need to adjust sbrk -+ request size to account for fact that we will not be able to -+ combine new space with existing space in old_top. -+ -+ * Almost all systems internally allocate whole pages at a time, in -+ which case we might as well use the whole last page of request. -+ So we allocate enough more memory to hit a page boundary now, -+ which in turn causes future contiguous calls to page-align. -+ */ -+ -+ else { -+ front_misalign = 0; -+ end_misalign = 0; -+ correction = 0; -+ aligned_brk = brk; -+ -+ /* -+ If MORECORE returns an address lower than we have seen before, -+ we know it isn't really contiguous. This and some subsequent -+ checks help cope with non-conforming MORECORE functions and -+ the presence of "foreign" calls to MORECORE from outside of -+ 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) { -+ set_noncontiguous(av); -+ } -+ -+ /* handle contiguous cases */ -+ if (contiguous(av)) { -+ -+ /* We can tolerate forward non-contiguities here (usually due -+ to foreign calls) but treat them as part of our space for -+ stats reporting. */ -+ if (old_size != 0) -+ av->sbrked_mem += brk - old_end; -+ -+ /* Guarantee alignment of first new chunk made from this space */ -+ -+ front_misalign = (size_t)chunk2mem(brk) & MALLOC_ALIGN_MASK; -+ if (front_misalign > 0) { -+ -+ /* -+ Skip over some bytes to arrive at an aligned position. -+ We don't need to specially mark these wasted front bytes. -+ They will never be accessed anyway because -+ prev_inuse of av->top (and any chunk created from its start) -+ is always true after initialization. -+ */ -+ -+ correction = MALLOC_ALIGNMENT - front_misalign; -+ aligned_brk += correction; -+ } -+ -+ /* -+ If this isn't adjacent to existing space, then we will not -+ be able to merge with old_top space, so must add to 2nd request. -+ */ -+ -+ correction += old_size; -+ -+ /* Extend the end address to hit a page boundary */ -+ end_misalign = (size_t)(brk + size + correction); -+ correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; -+ -+ assert(correction >= 0); -+ snd_brk = (char*)(MORECORE(correction)); -+ -+ if (snd_brk == (char*)(MORECORE_FAILURE)) { -+ /* -+ If can't allocate correction, try to at least find out current -+ brk. It might be enough to proceed without failing. -+ */ -+ correction = 0; -+ snd_brk = (char*)(MORECORE(0)); -+ } -+ else if (snd_brk < brk) { -+ /* -+ If the second call gives noncontiguous space even though -+ it says it won't, the only course of action is to ignore -+ results of second call, and conservatively estimate where -+ the first call left us. Also set noncontiguous, so this -+ won't happen again, leaving at most one hole. -+ -+ Note that this check is intrinsically incomplete. Because -+ MORECORE is allowed to give more space than we ask for, -+ there is no reliable way to detect a noncontiguity -+ producing a forward gap for the second call. -+ */ -+ snd_brk = brk + size; -+ correction = 0; -+ set_noncontiguous(av); -+ } -+ -+ } -+ -+ /* handle non-contiguous cases */ -+ else { -+ /* MORECORE/mmap must correctly align */ -+ assert(aligned_OK(chunk2mem(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; -+ } -+ } -+ -+ /* Adjust top based on results of second sbrk */ -+ if (snd_brk != (char*)(MORECORE_FAILURE)) { -+ av->top = (mchunkptr)aligned_brk; -+ set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); -+ av->sbrked_mem += correction; -+ -+ /* -+ If not the first time through, we either have a -+ gap due to foreign sbrk or a non-contiguous region. Insert a -+ double fencepost at old_top to prevent consolidation with space -+ we don't own. These fenceposts are artificial chunks that are -+ marked as inuse and are in any case too small to use. We need -+ two to make sizes and alignments work out. -+ */ -+ -+ if (old_size != 0) { -+ /* Shrink old_top to insert fenceposts, keeping size a -+ multiple of MALLOC_ALIGNMENT. We know there is at least -+ enough space in old_top to do this. -+ */ -+ old_size = (old_size - 3*(sizeof(size_t))) & ~MALLOC_ALIGN_MASK; -+ set_head(old_top, old_size | PREV_INUSE); -+ -+ /* -+ Note that the following assignments completely overwrite -+ old_top when old_size was previously MINSIZE. This is -+ intentional. We need the fencepost, even if old_top otherwise gets -+ lost. -+ */ -+ chunk_at_offset(old_top, old_size )->size = -+ (sizeof(size_t))|PREV_INUSE; -+ -+ chunk_at_offset(old_top, old_size + (sizeof(size_t)))->size = -+ (sizeof(size_t))|PREV_INUSE; -+ -+ /* If possible, release the rest, suppressing trimming. */ -+ if (old_size >= MINSIZE) { -+ size_t tt = av->trim_threshold; -+ av->trim_threshold = (size_t)(-1); -+ free(chunk2mem(old_top)); -+ av->trim_threshold = tt; -+ } -+ } -+ } -+ } -+ -+ /* Update statistics */ -+ sum = av->sbrked_mem; -+ if (sum > (unsigned long)(av->max_sbrked_mem)) -+ av->max_sbrked_mem = sum; -+ -+ sum += av->mmapped_mem; -+ if (sum > (unsigned long)(av->max_total_mem)) -+ av->max_total_mem = sum; -+ -+ check_malloc_state(); -+ -+ /* finally, do the allocation */ -+ -+ p = av->top; -+ size = chunksize(p); -+ -+ /* check that one of the above allocation paths succeeded */ -+ if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) { -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(p, nb); -+ av->top = remainder; -+ set_head(p, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ check_malloced_chunk(p, nb); -+ return chunk2mem(p); -+ } - - } - -@@ -767,25 +764,25 @@ static int __malloc_largebin_index(unsig - #if defined(__GNUC__) && defined(i386) - - __asm__("bsrl %1,%0\n\t" -- : "=r" (m) -- : "g" (x)); -+ : "=r" (m) -+ : "g" (x)); - - #else - { -- /* -- Based on branch-free nlz algorithm in chapter 5 of Henry -- S. Warren Jr's book "Hacker's Delight". -- */ -- -- unsigned int n = ((x - 0x100) >> 16) & 8; -- x <<= n; -- m = ((x - 0x1000) >> 16) & 4; -- n += m; -- x <<= m; -- m = ((x - 0x4000) >> 16) & 2; -- n += m; -- x = (x << m) >> 14; -- m = 13 - n + (x & ~(x>>1)); -+ /* -+ Based on branch-free nlz algorithm in chapter 5 of Henry -+ S. Warren Jr's book "Hacker's Delight". -+ */ -+ -+ unsigned int n = ((x - 0x100) >> 16) & 8; -+ x <<= n; -+ m = ((x - 0x1000) >> 16) & 4; -+ n += m; -+ x <<= m; -+ m = ((x - 0x4000) >> 16) & 2; -+ n += m; -+ x = (x << m) >> 14; -+ m = 13 - n + (x & ~(x>>1)); - } - #endif - -@@ -826,69 +823,70 @@ 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) return NULL; - #endif - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - /* -- Convert request size to internal form by adding (sizeof(size_t)) bytes -- overhead plus possibly more to obtain necessary alignment and/or -- to obtain a size of at least MINSIZE, the smallest allocatable -- size. Also, checked_request2size traps (returning 0) request sizes -- that are so large that they wrap around zero when padded and -- aligned. -- */ -+ Convert request size to internal form by adding (sizeof(size_t)) bytes -+ overhead plus possibly more to obtain necessary alignment and/or -+ to obtain a size of at least MINSIZE, the smallest allocatable -+ size. Also, checked_request2size traps (returning 0) request sizes -+ that are so large that they wrap around zero when padded and -+ aligned. -+ */ - - checked_request2size(bytes, nb); - - /* -- Bypass search if no frees yet -- */ -+ Bypass search if no frees yet -+ */ - if (!have_anychunks(av)) { -- if (av->max_fast == 0) /* initialization check */ -- __malloc_consolidate(av); -- goto use_top; -+ if (av->max_fast == 0) /* initialization check */ -+ __malloc_consolidate(av); -+ goto use_top; - } - - /* -- If the size qualifies as a fastbin, first check corresponding bin. -- */ -+ If the size qualifies as a fastbin, first check corresponding bin. -+ */ - - if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) { -- fb = &(av->fastbins[(fastbin_index(nb))]); -- if ( (victim = *fb) != 0) { -- *fb = victim->fd; -- check_remalloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -+ fb = &(av->fastbins[(fastbin_index(nb))]); -+ if ( (victim = *fb) != 0) { -+ *fb = victim->fd; -+ check_remalloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } - } - - /* -- If a small request, check regular bin. Since these "smallbins" -- hold one size each, no searching within bins is necessary. -- (For a large request, we need to wait until unsorted chunks are -- processed to find best fit. But for small ones, fits are exact -- anyway, so we can check now, which is faster.) -- */ -+ If a small request, check regular bin. Since these "smallbins" -+ hold one size each, no searching within bins is necessary. -+ (For a large request, we need to wait until unsorted chunks are -+ processed to find best fit. But for small ones, fits are exact -+ anyway, so we can check now, which is faster.) -+ */ - - if (in_smallbin_range(nb)) { -- idx = smallbin_index(nb); -- bin = bin_at(av,idx); -+ idx = smallbin_index(nb); -+ bin = bin_at(av,idx); - -- if ( (victim = last(bin)) != bin) { -- bck = victim->bk; -- set_inuse_bit_at_offset(victim, nb); -- bin->bk = bck; -- bck->fd = bin; -- -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -+ if ( (victim = last(bin)) != bin) { -+ bck = victim->bk; -+ set_inuse_bit_at_offset(victim, nb); -+ bin->bk = bck; -+ bck->fd = bin; -+ -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } - } - - /* If this is a large request, consolidate fastbins before continuing. -@@ -899,154 +897,154 @@ void* malloc(size_t bytes) - large requests, but less often mixtures, so consolidation is not - invoked all that often in most programs. And the programs that - it is called frequently in otherwise tend to fragment. -- */ -+ */ - - else { -- idx = __malloc_largebin_index(nb); -- if (have_fastchunks(av)) -- __malloc_consolidate(av); -+ idx = __malloc_largebin_index(nb); -+ if (have_fastchunks(av)) -+ __malloc_consolidate(av); - } - - /* -- Process recently freed or remaindered chunks, taking one only if -- it is exact fit, or, if this a small request, the chunk is remainder from -- the most recent non-exact fit. Place other traversed chunks in -- bins. Note that this step is the only place in any routine where -- chunks are placed in bins. -- */ -+ Process recently freed or remaindered chunks, taking one only if -+ it is exact fit, or, if this a small request, the chunk is remainder from -+ the most recent non-exact fit. Place other traversed chunks in -+ bins. Note that this step is the only place in any routine where -+ chunks are placed in bins. -+ */ - - while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) { -- bck = victim->bk; -- size = chunksize(victim); -+ bck = victim->bk; -+ size = chunksize(victim); -+ -+ /* If a small request, try to use last remainder if it is the -+ only chunk in unsorted bin. This helps promote locality for -+ runs of consecutive small requests. This is the only -+ exception to best-fit, and applies only when there is -+ no exact fit for a small chunk. -+ */ -+ -+ if (in_smallbin_range(nb) && -+ bck == unsorted_chunks(av) && -+ victim == av->last_remainder && -+ (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -+ -+ /* split and reattach remainder */ -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(victim, nb); -+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -+ av->last_remainder = remainder; -+ remainder->bk = remainder->fd = unsorted_chunks(av); -+ -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_foot(remainder, remainder_size); -+ -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ -+ /* remove from unsorted list */ -+ unsorted_chunks(av)->bk = bck; -+ bck->fd = unsorted_chunks(av); -+ -+ /* Take now instead of binning if exact fit */ -+ -+ if (size == nb) { -+ set_inuse_bit_at_offset(victim, size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ -+ /* place chunk in bin */ - -- /* If a small request, try to use last remainder if it is the -- only chunk in unsorted bin. This helps promote locality for -- runs of consecutive small requests. This is the only -- exception to best-fit, and applies only when there is -- no exact fit for a small chunk. -- */ -- -- if (in_smallbin_range(nb) && -- bck == unsorted_chunks(av) && -- victim == av->last_remainder && -- (unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -- -- /* split and reattach remainder */ -- remainder_size = size - nb; -- remainder = chunk_at_offset(victim, nb); -- unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -- av->last_remainder = remainder; -- remainder->bk = remainder->fd = unsorted_chunks(av); -- -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_foot(remainder, remainder_size); -- -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- -- /* remove from unsorted list */ -- unsorted_chunks(av)->bk = bck; -- bck->fd = unsorted_chunks(av); -- -- /* Take now instead of binning if exact fit */ -- -- if (size == nb) { -- set_inuse_bit_at_offset(victim, size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- -- /* place chunk in bin */ -- -- if (in_smallbin_range(size)) { -- victim_index = smallbin_index(size); -- bck = bin_at(av, victim_index); -- fwd = bck->fd; -- } -- else { -- victim_index = __malloc_largebin_index(size); -- bck = bin_at(av, victim_index); -- fwd = bck->fd; -- -- if (fwd != bck) { -- /* if smaller than smallest, place first */ -- if ((unsigned long)(size) < (unsigned long)(bck->bk->size)) { -- fwd = bck; -- bck = bck->bk; -- } -- else if ((unsigned long)(size) >= -- (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -- -- /* maintain large bins in sorted order */ -- size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */ -- while ((unsigned long)(size) < (unsigned long)(fwd->size)) -- fwd = fwd->fd; -- bck = fwd->bk; -- } -- } -- } -- -- mark_bin(av, victim_index); -- victim->bk = bck; -- victim->fd = fwd; -- fwd->bk = victim; -- bck->fd = victim; -+ if (in_smallbin_range(size)) { -+ victim_index = smallbin_index(size); -+ bck = bin_at(av, victim_index); -+ fwd = bck->fd; -+ } -+ else { -+ victim_index = __malloc_largebin_index(size); -+ bck = bin_at(av, victim_index); -+ fwd = bck->fd; -+ -+ if (fwd != bck) { -+ /* if smaller than smallest, place first */ -+ if ((unsigned long)(size) < (unsigned long)(bck->bk->size)) { -+ fwd = bck; -+ bck = bck->bk; -+ } -+ else if ((unsigned long)(size) >= -+ (unsigned long)(FIRST_SORTED_BIN_SIZE)) { -+ -+ /* maintain large bins in sorted order */ -+ size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */ -+ while ((unsigned long)(size) < (unsigned long)(fwd->size)) -+ fwd = fwd->fd; -+ bck = fwd->bk; -+ } -+ } -+ } -+ -+ mark_bin(av, victim_index); -+ victim->bk = bck; -+ victim->fd = fwd; -+ fwd->bk = victim; -+ bck->fd = victim; - } - - /* -- If a large request, scan through the chunks of current bin to -- find one that fits. (This will be the smallest that fits unless -- FIRST_SORTED_BIN_SIZE has been changed from default.) This is -- the only step where an unbounded number of chunks might be -- scanned without doing anything useful with them. However the -- lists tend to be short. -- */ -+ If a large request, scan through the chunks of current bin to -+ find one that fits. (This will be the smallest that fits unless -+ FIRST_SORTED_BIN_SIZE has been changed from default.) This is -+ the only step where an unbounded number of chunks might be -+ scanned without doing anything useful with them. However the -+ lists tend to be short. -+ */ - - if (!in_smallbin_range(nb)) { -- bin = bin_at(av, idx); -- -- for (victim = last(bin); victim != bin; victim = victim->bk) { -- size = chunksize(victim); -+ bin = bin_at(av, idx); - -- if ((unsigned long)(size) >= (unsigned long)(nb)) { -- remainder_size = size - nb; -- unlink(victim, bck, fwd); -+ for (victim = last(bin); victim != bin; victim = victim->bk) { -+ size = chunksize(victim); - -- /* Exhaust */ -- if (remainder_size < MINSIZE) { -- set_inuse_bit_at_offset(victim, size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- /* Split */ -- else { -- remainder = chunk_at_offset(victim, nb); -- unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -- remainder->bk = remainder->fd = unsorted_chunks(av); -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_foot(remainder, remainder_size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -+ if ((unsigned long)(size) >= (unsigned long)(nb)) { -+ remainder_size = size - nb; -+ unlink(victim, bck, fwd); -+ -+ /* Exhaust */ -+ if (remainder_size < MINSIZE) { -+ set_inuse_bit_at_offset(victim, size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ /* Split */ -+ else { -+ remainder = chunk_at_offset(victim, nb); -+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -+ remainder->bk = remainder->fd = unsorted_chunks(av); -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_foot(remainder, remainder_size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ } - } -- } -- } - } - - /* -- Search for a chunk by scanning bins, starting with next largest -- bin. This search is strictly by best-fit; i.e., the smallest -- (with ties going to approximately the least recently used) chunk -- that fits is selected. -+ Search for a chunk by scanning bins, starting with next largest -+ bin. This search is strictly by best-fit; i.e., the smallest -+ (with ties going to approximately the least recently used) chunk -+ that fits is selected. - -- The bitmap avoids needing to check that most blocks are nonempty. -- */ -+ The bitmap avoids needing to check that most blocks are nonempty. -+ */ - - ++idx; - bin = bin_at(av,idx); -@@ -1056,109 +1054,111 @@ void* malloc(size_t bytes) - - for (;;) { - -- /* Skip rest of block if there are no more set bits in this block. */ -- if (bit > map || bit == 0) { -- do { -- if (++block >= BINMAPSIZE) /* out of bins */ -- goto use_top; -- } while ( (map = av->binmap[block]) == 0); -- -- bin = bin_at(av, (block << BINMAPSHIFT)); -- bit = 1; -- } -- -- /* Advance to bin with set bit. There must be one. */ -- while ((bit & map) == 0) { -- bin = next_bin(bin); -- bit <<= 1; -- assert(bit != 0); -- } -- -- /* Inspect the bin. It is likely to be non-empty */ -- victim = last(bin); -- -- /* If a false alarm (empty bin), clear the bit. */ -- if (victim == bin) { -- av->binmap[block] = map &= ~bit; /* Write through */ -- bin = next_bin(bin); -- bit <<= 1; -- } -- -- else { -- size = chunksize(victim); -- -- /* We know the first chunk in this bin is big enough to use. */ -- assert((unsigned long)(size) >= (unsigned long)(nb)); -- -- remainder_size = size - nb; -- -- /* unlink */ -- bck = victim->bk; -- bin->bk = bck; -- bck->fd = bin; -- -- /* Exhaust */ -- if (remainder_size < MINSIZE) { -- set_inuse_bit_at_offset(victim, size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -+ /* Skip rest of block if there are no more set bits in this block. */ -+ if (bit > map || bit == 0) { -+ do { -+ if (++block >= BINMAPSIZE) /* out of bins */ -+ goto use_top; -+ } while ( (map = av->binmap[block]) == 0); - -- /* Split */ -- else { -- remainder = chunk_at_offset(victim, nb); -+ bin = bin_at(av, (block << BINMAPSHIFT)); -+ bit = 1; -+ } - -- unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -- remainder->bk = remainder->fd = unsorted_chunks(av); -- /* advertise as last remainder */ -- if (in_smallbin_range(nb)) -- av->last_remainder = remainder; -+ /* Advance to bin with set bit. There must be one. */ -+ while ((bit & map) == 0) { -+ bin = next_bin(bin); -+ bit <<= 1; -+ assert(bit != 0); -+ } - -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_foot(remainder, remainder_size); -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -- } -- } -+ /* Inspect the bin. It is likely to be non-empty */ -+ victim = last(bin); -+ -+ /* If a false alarm (empty bin), clear the bit. */ -+ if (victim == bin) { -+ av->binmap[block] = map &= ~bit; /* Write through */ -+ bin = next_bin(bin); -+ bit <<= 1; -+ } -+ -+ else { -+ size = chunksize(victim); -+ -+ /* We know the first chunk in this bin is big enough to use. */ -+ assert((unsigned long)(size) >= (unsigned long)(nb)); -+ -+ remainder_size = size - nb; -+ -+ /* unlink */ -+ bck = victim->bk; -+ bin->bk = bck; -+ bck->fd = bin; -+ -+ /* Exhaust */ -+ if (remainder_size < MINSIZE) { -+ set_inuse_bit_at_offset(victim, size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ -+ /* Split */ -+ else { -+ remainder = chunk_at_offset(victim, nb); -+ -+ unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; -+ remainder->bk = remainder->fd = unsorted_chunks(av); -+ /* advertise as last remainder */ -+ if (in_smallbin_range(nb)) -+ av->last_remainder = remainder; -+ -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_foot(remainder, remainder_size); -+ check_malloced_chunk(victim, nb); -+ retval = chunk2mem(victim); -+ goto DONE; -+ } -+ } - } - --use_top: -+ use_top: - /* -- If large enough, split off the chunk bordering the end of memory -- (held in av->top). Note that this is in accord with the best-fit -- search rule. In effect, av->top is treated as larger (and thus -- less well fitting) than any other available chunk since it can -- be extended to be as large as necessary (up to system -- limitations). -- -- We require that av->top always exists (i.e., has size >= -- MINSIZE) after initialization, so if it would otherwise be -- exhuasted by current request, it is replenished. (The main -- reason for ensuring it exists is that we may need MINSIZE space -- to put in fenceposts in sysmalloc.) -- */ -+ If large enough, split off the chunk bordering the end of memory -+ (held in av->top). Note that this is in accord with the best-fit -+ search rule. In effect, av->top is treated as larger (and thus -+ less well fitting) than any other available chunk since it can -+ be extended to be as large as necessary (up to system -+ limitations). -+ -+ We require that av->top always exists (i.e., has size >= -+ MINSIZE) after initialization, so if it would otherwise be -+ exhuasted by current request, it is replenished. (The main -+ reason for ensuring it exists is that we may need MINSIZE space -+ to put in fenceposts in sysmalloc.) -+ */ - - victim = av->top; - size = chunksize(victim); - - if ((unsigned long)(size) >= (unsigned long)(nb + MINSIZE)) { -- remainder_size = size - nb; -- remainder = chunk_at_offset(victim, nb); -- av->top = remainder; -- set_head(victim, nb | PREV_INUSE); -- set_head(remainder, remainder_size | PREV_INUSE); -- -- check_malloced_chunk(victim, nb); -- UNLOCK; -- return chunk2mem(victim); -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(victim, nb); -+ av->top = remainder; -+ set_head(victim, nb | PREV_INUSE); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ -+ check_malloced_chunk(victim, nb); -+ 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 fbc1492..14a0dd9 100644 ---- a/libc/stdlib/malloc-standard/malloc.h -+++ b/libc/stdlib/malloc-standard/malloc.h -@@ -22,16 +22,12 @@ - #include <malloc.h> - #include <stdlib.h> - -+#include <bits/uClibc_mutex.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --extern pthread_mutex_t __malloc_lock; --# define LOCK __pthread_mutex_lock(&__malloc_lock) --# define UNLOCK __pthread_mutex_unlock(&__malloc_lock); --#else --# define LOCK --# define UNLOCK --#endif -+__UCLIBC_MUTEX_EXTERN(__malloc_lock); -+ -+#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) -+#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) - - - -diff --git a/libc/stdlib/malloc-standard/mallopt.c b/libc/stdlib/malloc-standard/mallopt.c -index e287920..41aa614 100644 ---- a/libc/stdlib/malloc-standard/mallopt.c -+++ b/libc/stdlib/malloc-standard/mallopt.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -25,40 +25,40 @@ int mallopt(int param_number, int value) - - ret = 0; - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - /* Ensure initialization/consolidation */ - __malloc_consolidate(av); - - switch(param_number) { -- case M_MXFAST: -- if (value >= 0 && value <= MAX_FAST_SIZE) { -- set_max_fast(av, value); -- ret = 1; -- } -- break; -- -- case M_TRIM_THRESHOLD: -- av->trim_threshold = value; -- ret = 1; -- break; -- -- case M_TOP_PAD: -- av->top_pad = value; -- ret = 1; -- break; -- -- case M_MMAP_THRESHOLD: -- av->mmap_threshold = value; -- ret = 1; -- break; -- -- case M_MMAP_MAX: -- av->n_mmaps_max = value; -- ret = 1; -- break; -+ case M_MXFAST: -+ if (value >= 0 && value <= MAX_FAST_SIZE) { -+ set_max_fast(av, value); -+ ret = 1; -+ } -+ break; -+ -+ case M_TRIM_THRESHOLD: -+ av->trim_threshold = value; -+ ret = 1; -+ break; -+ -+ case M_TOP_PAD: -+ av->top_pad = value; -+ ret = 1; -+ break; -+ -+ case M_MMAP_THRESHOLD: -+ av->mmap_threshold = value; -+ ret = 1; -+ break; -+ -+ case M_MMAP_MAX: -+ av->n_mmaps_max = 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 bd95362..e78d752 100644 ---- a/libc/stdlib/malloc-standard/memalign.c -+++ b/libc/stdlib/malloc-standard/memalign.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -35,6 +35,7 @@ void* memalign(size_t alignment, size_t - 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 */ - -@@ -46,12 +47,12 @@ void* memalign(size_t alignment, size_t - - /* Make sure alignment is power of 2 (in case MINSIZE is not). */ - if ((alignment & (alignment - 1)) != 0) { -- size_t a = MALLOC_ALIGNMENT * 2; -- while ((unsigned long)a < (unsigned long)alignment) a <<= 1; -- alignment = a; -+ size_t a = MALLOC_ALIGNMENT * 2; -+ while ((unsigned long)a < (unsigned long)alignment) a <<= 1; -+ alignment = a; - } - -- LOCK; -+ __MALLOC_LOCK; - checked_request2size(bytes, nb); - - /* Strategy: find a spot within that chunk that meets the alignment -@@ -63,64 +64,67 @@ void* memalign(size_t alignment, size_t - m = (char*)(malloc(nb + alignment + MINSIZE)); - - if (m == 0) { -- UNLOCK; -- return 0; /* propagate failure */ -+ retval = 0; /* propagate failure */ -+ goto DONE; - } - - p = mem2chunk(m); - - if ((((unsigned long)(m)) % alignment) != 0) { /* misaligned */ - -- /* -- Find an aligned spot inside chunk. Since we need to give back -- leading space in a chunk of at least MINSIZE, if the first -- calculation places us at a spot with less than MINSIZE leader, -- we can move to the next aligned spot -- we've allocated enough -- total room so that this is always possible. -- */ -- -- brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) & -- -((signed long) alignment))); -- if ((unsigned long)(brk - (char*)(p)) < MINSIZE) -- brk += alignment; -- -- newp = (mchunkptr)brk; -- leadsize = brk - (char*)(p); -- newsize = chunksize(p) - leadsize; -- -- /* For mmapped chunks, just adjust offset */ -- if (chunk_is_mmapped(p)) { -- newp->prev_size = p->prev_size + leadsize; -- set_head(newp, newsize|IS_MMAPPED); -- UNLOCK; -- return chunk2mem(newp); -- } -- -- /* Otherwise, give back leader, use the rest */ -- set_head(newp, newsize | PREV_INUSE); -- set_inuse_bit_at_offset(newp, newsize); -- set_head_size(p, leadsize); -- free(chunk2mem(p)); -- p = newp; -+ /* -+ Find an aligned spot inside chunk. Since we need to give back -+ leading space in a chunk of at least MINSIZE, if the first -+ calculation places us at a spot with less than MINSIZE leader, -+ we can move to the next aligned spot -- we've allocated enough -+ total room so that this is always possible. -+ */ -+ -+ brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) & -+ -((signed long) alignment))); -+ if ((unsigned long)(brk - (char*)(p)) < MINSIZE) -+ brk += alignment; -+ -+ newp = (mchunkptr)brk; -+ leadsize = brk - (char*)(p); -+ newsize = chunksize(p) - leadsize; -+ -+ /* For mmapped chunks, just adjust offset */ -+ if (chunk_is_mmapped(p)) { -+ newp->prev_size = p->prev_size + leadsize; -+ set_head(newp, newsize|IS_MMAPPED); -+ retval = chunk2mem(newp); -+ goto DONE; -+ } -+ -+ /* Otherwise, give back leader, use the rest */ -+ set_head(newp, newsize | PREV_INUSE); -+ set_inuse_bit_at_offset(newp, newsize); -+ set_head_size(p, leadsize); -+ free(chunk2mem(p)); -+ p = newp; - -- assert (newsize >= nb && -- (((unsigned long)(chunk2mem(p))) % alignment) == 0); -+ assert (newsize >= nb && -+ (((unsigned long)(chunk2mem(p))) % alignment) == 0); - } - - /* Also give back spare room at the end */ - if (!chunk_is_mmapped(p)) { -- size = chunksize(p); -- if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -- remainder_size = size - nb; -- remainder = chunk_at_offset(p, nb); -- set_head(remainder, remainder_size | PREV_INUSE); -- set_head_size(p, nb); -- free(chunk2mem(remainder)); -- } -+ size = chunksize(p); -+ if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) { -+ remainder_size = size - nb; -+ remainder = chunk_at_offset(p, nb); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ set_head_size(p, nb); -+ free(chunk2mem(remainder)); -+ } - } - - 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 1950130..9ca4b26 100644 ---- a/libc/stdlib/malloc-standard/realloc.c -+++ b/libc/stdlib/malloc-standard/realloc.c -@@ -8,7 +8,7 @@ - VERSION 2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - - Note: There may be an updated version of this malloc obtainable at -- ftp://gee.cs.oswego.edu/pub/misc/malloc.c -+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - - Hacked up for uClibc by Erik Andersen <andersen@codepoet.org> -@@ -23,14 +23,14 @@ void* realloc(void* oldmem, size_t bytes - { - mstate av; - -- size_t nb; /* padded request size */ -+ size_t nb; /* padded request size */ - - mchunkptr oldp; /* chunk corresponding to oldmem */ -- size_t oldsize; /* its size */ -+ size_t oldsize; /* its size */ - - mchunkptr newp; /* chunk to return */ -- size_t newsize; /* its size */ -- void* newmem; /* corresponding user mem */ -+ size_t newsize; /* its size */ -+ void* newmem; /* corresponding user mem */ - - mchunkptr next; /* next contiguous chunk after oldp */ - -@@ -40,21 +40,23 @@ void* realloc(void* oldmem, size_t bytes - mchunkptr bck; /* misc temp for linking */ - mchunkptr fwd; /* misc temp for linking */ - -- unsigned long copysize; /* bytes to copy */ -+ unsigned long copysize; /* bytes to copy */ - unsigned int ncopies; /* size_t words to copy */ -- size_t* s; /* copy source */ -- size_t* d; /* copy destination */ -+ size_t* s; /* copy source */ -+ size_t* d; /* copy destination */ -+ -+ void *retval; - - - /* Check for special cases. */ - if (! oldmem) -- return malloc(bytes); -+ return malloc(bytes); - if (! bytes) { -- free (oldmem); -- return malloc(bytes); -+ free (oldmem); -+ return malloc(bytes); - } - -- LOCK; -+ __MALLOC_LOCK; - av = get_malloc_state(); - checked_request2size(bytes, nb); - -@@ -65,173 +67,176 @@ void* realloc(void* oldmem, size_t bytes - - if (!chunk_is_mmapped(oldp)) { - -- if ((unsigned long)(oldsize) >= (unsigned long)(nb)) { -- /* already big enough; split below */ -- newp = oldp; -- newsize = oldsize; -- } -- -- else { -- next = chunk_at_offset(oldp, oldsize); -- -- /* Try to expand forward into top */ -- if (next == av->top && -- (unsigned long)(newsize = oldsize + chunksize(next)) >= -- (unsigned long)(nb + MINSIZE)) { -- set_head_size(oldp, nb); -- av->top = chunk_at_offset(oldp, nb); -- set_head(av->top, (newsize - nb) | PREV_INUSE); -- UNLOCK; -- return chunk2mem(oldp); -- } -- -- /* Try to expand forward into next chunk; split off remainder below */ -- else if (next != av->top && -- !inuse(next) && -- (unsigned long)(newsize = oldsize + chunksize(next)) >= -- (unsigned long)(nb)) { -- newp = oldp; -- unlink(next, bck, fwd); -- } -- -- /* allocate, copy, free */ -- else { -- newmem = malloc(nb - MALLOC_ALIGN_MASK); -- if (newmem == 0) { -- UNLOCK; -- return 0; /* propagate failure */ -- } -- -- newp = mem2chunk(newmem); -- newsize = chunksize(newp); -- -- /* -- Avoid copy if newp is next chunk after oldp. -- */ -- if (newp == next) { -- newsize += oldsize; -- newp = oldp; -+ if ((unsigned long)(oldsize) >= (unsigned long)(nb)) { -+ /* already big enough; split below */ -+ newp = oldp; -+ newsize = oldsize; - } -+ - else { -- /* -- Unroll copy of <= 36 bytes (72 if 8byte sizes) -- We know that contents have an odd number of -- size_t-sized words; minimally 3. -- */ -- -- copysize = oldsize - (sizeof(size_t)); -- s = (size_t*)(oldmem); -- d = (size_t*)(newmem); -- ncopies = copysize / sizeof(size_t); -- assert(ncopies >= 3); -- -- if (ncopies > 9) -- memcpy(d, s, copysize); -- -- else { -- *(d+0) = *(s+0); -- *(d+1) = *(s+1); -- *(d+2) = *(s+2); -- if (ncopies > 4) { -- *(d+3) = *(s+3); -- *(d+4) = *(s+4); -- if (ncopies > 6) { -- *(d+5) = *(s+5); -- *(d+6) = *(s+6); -- if (ncopies > 8) { -- *(d+7) = *(s+7); -- *(d+8) = *(s+8); -+ next = chunk_at_offset(oldp, oldsize); -+ -+ /* Try to expand forward into top */ -+ if (next == av->top && -+ (unsigned long)(newsize = oldsize + chunksize(next)) >= -+ (unsigned long)(nb + MINSIZE)) { -+ set_head_size(oldp, nb); -+ av->top = chunk_at_offset(oldp, nb); -+ set_head(av->top, (newsize - nb) | PREV_INUSE); -+ retval = chunk2mem(oldp); -+ goto DONE; -+ } -+ -+ /* Try to expand forward into next chunk; split off remainder below */ -+ else if (next != av->top && -+ !inuse(next) && -+ (unsigned long)(newsize = oldsize + chunksize(next)) >= -+ (unsigned long)(nb)) { -+ newp = oldp; -+ unlink(next, bck, fwd); -+ } -+ -+ /* allocate, copy, free */ -+ else { -+ newmem = malloc(nb - MALLOC_ALIGN_MASK); -+ if (newmem == 0) { -+ retval = 0; /* propagate failure */ -+ goto DONE; -+ } -+ -+ newp = mem2chunk(newmem); -+ newsize = chunksize(newp); -+ -+ /* -+ Avoid copy if newp is next chunk after oldp. -+ */ -+ if (newp == next) { -+ newsize += oldsize; -+ newp = oldp; -+ } -+ else { -+ /* -+ Unroll copy of <= 36 bytes (72 if 8byte sizes) -+ We know that contents have an odd number of -+ size_t-sized words; minimally 3. -+ */ -+ -+ copysize = oldsize - (sizeof(size_t)); -+ s = (size_t*)(oldmem); -+ d = (size_t*)(newmem); -+ ncopies = copysize / sizeof(size_t); -+ assert(ncopies >= 3); -+ -+ if (ncopies > 9) -+ memcpy(d, s, copysize); -+ -+ else { -+ *(d+0) = *(s+0); -+ *(d+1) = *(s+1); -+ *(d+2) = *(s+2); -+ if (ncopies > 4) { -+ *(d+3) = *(s+3); -+ *(d+4) = *(s+4); -+ if (ncopies > 6) { -+ *(d+5) = *(s+5); -+ *(d+6) = *(s+6); -+ if (ncopies > 8) { -+ *(d+7) = *(s+7); -+ *(d+8) = *(s+8); -+ } -+ } -+ } -+ } -+ -+ free(oldmem); -+ check_inuse_chunk(newp); -+ retval = chunk2mem(newp); -+ goto DONE; - } -- } - } -- } -+ } -+ -+ /* If possible, free extra space in old or extended chunk */ -+ -+ assert((unsigned long)(newsize) >= (unsigned long)(nb)); -+ -+ remainder_size = newsize - nb; - -- free(oldmem); -- check_inuse_chunk(newp); -- UNLOCK; -- return chunk2mem(newp); -- } -- } -- } -- -- /* If possible, free extra space in old or extended chunk */ -- -- assert((unsigned long)(newsize) >= (unsigned long)(nb)); -- -- remainder_size = newsize - nb; -- -- if (remainder_size < MINSIZE) { /* not enough extra to split off */ -- set_head_size(newp, newsize); -- set_inuse_bit_at_offset(newp, newsize); -- } -- else { /* split remainder */ -- remainder = chunk_at_offset(newp, nb); -- set_head_size(newp, nb); -- set_head(remainder, remainder_size | PREV_INUSE); -- /* Mark remainder as inuse so free() won't complain */ -- set_inuse_bit_at_offset(remainder, remainder_size); -- free(chunk2mem(remainder)); -- } -- -- check_inuse_chunk(newp); -- UNLOCK; -- return chunk2mem(newp); -+ if (remainder_size < MINSIZE) { /* not enough extra to split off */ -+ set_head_size(newp, newsize); -+ set_inuse_bit_at_offset(newp, newsize); -+ } -+ else { /* split remainder */ -+ remainder = chunk_at_offset(newp, nb); -+ set_head_size(newp, nb); -+ set_head(remainder, remainder_size | PREV_INUSE); -+ /* Mark remainder as inuse so free() won't complain */ -+ set_inuse_bit_at_offset(remainder, remainder_size); -+ free(chunk2mem(remainder)); -+ } -+ -+ check_inuse_chunk(newp); -+ retval = chunk2mem(newp); -+ goto DONE; - } - - /* -- Handle mmap cases -- */ -+ Handle mmap cases -+ */ - - else { -- size_t offset = oldp->prev_size; -- size_t pagemask = av->pagesize - 1; -- char *cp; -- unsigned long sum; -- -- /* Note the extra (sizeof(size_t)) overhead */ -- newsize = (nb + offset + (sizeof(size_t)) + pagemask) & ~pagemask; -- -- /* don't need to remap if still within same page */ -- if (oldsize == newsize - offset) { -- UNLOCK; -- return oldmem; -- } -- -- cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); -- -- if (cp != (char*)MORECORE_FAILURE) { -- -- newp = (mchunkptr)(cp + offset); -- set_head(newp, (newsize - offset)|IS_MMAPPED); -- -- assert(aligned_OK(chunk2mem(newp))); -- assert((newp->prev_size == offset)); -- -- /* update statistics */ -- sum = av->mmapped_mem += newsize - oldsize; -- if (sum > (unsigned long)(av->max_mmapped_mem)) -- av->max_mmapped_mem = sum; -- sum += av->sbrked_mem; -- if (sum > (unsigned long)(av->max_total_mem)) -- av->max_total_mem = sum; -- -- UNLOCK; -- return chunk2mem(newp); -- } -- -- /* Note the extra (sizeof(size_t)) overhead. */ -- if ((unsigned long)(oldsize) >= (unsigned long)(nb + (sizeof(size_t)))) -- newmem = oldmem; /* do nothing */ -- else { -- /* Must alloc, copy, free. */ -- newmem = malloc(nb - MALLOC_ALIGN_MASK); -- if (newmem != 0) { -- memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t))); -- free(oldmem); -- } -- } -- UNLOCK; -- return newmem; -+ size_t offset = oldp->prev_size; -+ size_t pagemask = av->pagesize - 1; -+ char *cp; -+ unsigned long sum; -+ -+ /* Note the extra (sizeof(size_t)) overhead */ -+ newsize = (nb + offset + (sizeof(size_t)) + pagemask) & ~pagemask; -+ -+ /* don't need to remap if still within same page */ -+ if (oldsize == newsize - offset) { -+ retval = oldmem; -+ goto DONE; -+ } -+ -+ cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); -+ -+ if (cp != (char*)MORECORE_FAILURE) { -+ -+ newp = (mchunkptr)(cp + offset); -+ set_head(newp, (newsize - offset)|IS_MMAPPED); -+ -+ assert(aligned_OK(chunk2mem(newp))); -+ assert((newp->prev_size == offset)); -+ -+ /* update statistics */ -+ sum = av->mmapped_mem += newsize - oldsize; -+ if (sum > (unsigned long)(av->max_mmapped_mem)) -+ av->max_mmapped_mem = sum; -+ sum += av->sbrked_mem; -+ if (sum > (unsigned long)(av->max_total_mem)) -+ av->max_total_mem = sum; -+ -+ retval = chunk2mem(newp); -+ goto DONE; -+ } -+ -+ /* Note the extra (sizeof(size_t)) overhead. */ -+ if ((unsigned long)(oldsize) >= (unsigned long)(nb + (sizeof(size_t)))) -+ newmem = oldmem; /* do nothing */ -+ else { -+ /* Must alloc, copy, free. */ -+ newmem = malloc(nb - MALLOC_ALIGN_MASK); -+ if (newmem != 0) { -+ memcpy(newmem, oldmem, oldsize - 2*(sizeof(size_t))); -+ free(oldmem); -+ } -+ } -+ retval = newmem; - } -+ -+ DONE: -+ __MALLOC_UNLOCK; -+ return retval; - } - -diff --git a/libc/stdlib/random.c b/libc/stdlib/random.c -index b0a00e1..1bd63bc 100644 ---- a/libc/stdlib/random.c -+++ b/libc/stdlib/random.c -@@ -27,16 +27,14 @@ - #include <limits.h> - #include <stddef.h> - #include <stdlib.h> --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.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; --#else --#define __pthread_mutex_lock(x) --#define __pthread_mutex_unlock(x) --#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 -@@ -184,9 +182,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); - } - weak_alias (srandom, srand) - -@@ -205,10 +203,10 @@ char * initstate (unsigned int seed, cha - { - 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; - } - -@@ -224,11 +222,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; - } - -@@ -247,9 +245,9 @@ long int random () - { - 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; - } - -diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c -index d0cfe52..2d899cc 100644 ---- a/libc/stdlib/setenv.c -+++ b/libc/stdlib/setenv.c -@@ -17,7 +17,7 @@ - 02111-1307 USA. - - modified for uClibc by Erik Andersen <andersen@codepoet.org> -- */ -+*/ - - #define _GNU_SOURCE - #include <features.h> -@@ -26,16 +26,9 @@ - #include <string.h> - #include <unistd.h> - --#ifdef __UCLIBC_HAS_THREADS__ --#include <pthread.h> --static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; --# define LOCK __pthread_mutex_lock(&mylock) --# define UNLOCK __pthread_mutex_unlock(&mylock); --#else --# define LOCK --# define UNLOCK --#endif -+#include <bits/uClibc_mutex.h> - -+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); - - /* If this variable is not a null pointer we allocated the current - environment. */ -@@ -49,14 +42,15 @@ static char **last_environ; - 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, -- const char *combined, int replace) -+ 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. */ -@@ -64,72 +58,72 @@ int __add_to_environ (const char *name, - - 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; -+ 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 *)); -- } -+ /* 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; -+ new_environ[size + 1] = NULL; -+ last_environ = __environ = new_environ; - } else if (replace) { -- char *np; -+ 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; -- } -- -- UNLOCK; -- return 0; -+ /* 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; -+ } -+ -+ rv = 0; -+ -+ DONE: -+ __UCLIBC_MUTEX_UNLOCK(mylock); -+ return rv; - } - - int setenv (const char *name, const char *value, int replace) -@@ -143,26 +137,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; - } - -@@ -171,15 +165,15 @@ int unsetenv (const char *name) - 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; - } - -@@ -190,10 +184,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/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h -index 40cd5fe..3c6911e 100644 ---- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h -+++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h -@@ -116,9 +116,7 @@ - #endif - - /**********************************************************************/ --#ifdef __UCLIBC_HAS_THREADS__ --/* Need this for pthread_mutex_t. */ --#include <bits/pthreadtypes.h> -+#include <bits/uClibc_mutex.h> - - /* user_locking - * 0 : do auto locking/unlocking -@@ -132,43 +130,37 @@ - * This way, we avoid calling the weak lock/unlock functions. - */ - --#define __STDIO_AUTO_THREADLOCK_VAR int __infunc_user_locking -- --#define __STDIO_AUTO_THREADLOCK(__stream) \ -- if ((__infunc_user_locking = (__stream)->__user_locking) == 0) { \ -- __pthread_mutex_lock(&(__stream)->__lock); \ -- } -- --#define __STDIO_AUTO_THREADUNLOCK(__stream) \ -- if (__infunc_user_locking == 0) { \ -- __pthread_mutex_unlock(&(__stream)->__lock); \ -- } -+#define __STDIO_AUTO_THREADLOCK_VAR \ -+ __UCLIBC_MUTEX_AUTO_LOCK_VAR(__infunc_user_locking) - --#define __STDIO_SET_USER_LOCKING(__stream) ((__stream)->__user_locking = 1) -+#define __STDIO_AUTO_THREADLOCK(__stream) \ -+ __UCLIBC_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking, \ -+ (__stream)->__user_locking) - --#define __STDIO_ALWAYS_THREADLOCK(__stream) \ -- __pthread_mutex_lock(&(__stream)->__lock) -+#define __STDIO_AUTO_THREADUNLOCK(__stream) \ -+ __UCLIBC_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking) - --#define __STDIO_ALWAYS_THREADTRYLOCK(__stream) \ -- __pthread_mutex_trylock(&(__stream)->__lock) -+#define __STDIO_ALWAYS_THREADLOCK(__stream) \ -+ __UCLIBC_MUTEX_LOCK((__stream)->__lock) - --#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ -- __pthread_mutex_unlock(&(__stream)->__lock) -+#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ -+ __UCLIBC_MUTEX_UNLOCK((__stream)->__lock) - --#else /* __UCLIBC_HAS_THREADS__ */ -+#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) \ -+ __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock) - --#define __STDIO_AUTO_THREADLOCK_VAR ((void)0) -+#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) \ -+ __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock) - --#define __STDIO_AUTO_THREADLOCK(__stream) ((void)0) --#define __STDIO_AUTO_THREADUNLOCK(__stream) ((void)0) -+#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream) \ -+ __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE((__stream)->__lock) - -+#ifdef __UCLIBC_HAS_THREADS__ -+#define __STDIO_SET_USER_LOCKING(__stream) ((__stream)->__user_locking = 1) -+#else - #define __STDIO_SET_USER_LOCKING(__stream) ((void)0) -+#endif - --#define __STDIO_ALWAYS_THREADLOCK(__stream) ((void)0) --#define __STDIO_ALWAYS_THREADTRYLOCK(__stream) (0) /* Always succeed. */ --#define __STDIO_ALWAYS_THREADUNLOCK(__stream) ((void)0) -- --#endif /* __UCLIBC_HAS_THREADS__ */ - /**********************************************************************/ - - #define __STDIO_IOFBF 0 /* Fully buffered. */ -@@ -283,7 +275,7 @@ struct __STDIO_FILE_STRUCT { - #endif - #ifdef __UCLIBC_HAS_THREADS__ - int __user_locking; -- pthread_mutex_t __lock; -+ __UCLIBC_MUTEX(__lock); - #endif - /* Everything after this is unimplemented... and may be trashed. */ - #if __STDIO_BUILTIN_BUF_SIZE > 0 -@@ -358,10 +350,14 @@ extern void _stdio_term(void); - extern struct __STDIO_FILE_STRUCT *_stdio_openlist; - - #ifdef __UCLIBC_HAS_THREADS__ --extern pthread_mutex_t _stdio_openlist_lock; --extern int _stdio_openlist_delflag; -+__UCLIBC_MUTEX_EXTERN(_stdio_openlist_add_lock); -+#ifdef __STDIO_BUFFERS -+__UCLIBC_MUTEX_EXTERN(_stdio_openlist_del_lock); -+extern volatile int _stdio_openlist_use_count; /* _stdio_openlist_del_lock */ -+extern int _stdio_openlist_del_count; /* _stdio_openlist_del_lock */ -+#endif - extern int _stdio_user_locking; --extern void __stdio_init_mutex(pthread_mutex_t *m); -+extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m); - #endif - - #endif -diff --git a/libc/sysdeps/linux/common/getdents.c b/libc/sysdeps/linux/common/getdents.c -index ab6a276..23463e5 100644 ---- a/libc/sysdeps/linux/common/getdents.c -+++ b/libc/sysdeps/linux/common/getdents.c -@@ -30,8 +30,6 @@ - #include <sys/syscall.h> - - --#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) -- - struct kernel_dirent - { - long d_ino; -diff --git a/libc/sysdeps/linux/common/sigprocmask.c b/libc/sysdeps/linux/common/sigprocmask.c -index 70ff366..565318d 100644 ---- a/libc/sysdeps/linux/common/sigprocmask.c -+++ b/libc/sysdeps/linux/common/sigprocmask.c -@@ -23,6 +23,8 @@ int sigprocmask(int how, const sigset_t - if (set && - #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2) - (((unsigned int) how) > 2) -+#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3) -+ (((unsigned int)(how-1)) > 2) - #else - #warning "compile time assumption violated.. slow path..." - ((how != SIG_BLOCK) && (how != SIG_UNBLOCK) -@@ -48,6 +50,8 @@ int sigprocmask(int how, const sigset_t - if (set && - #if (SIG_BLOCK == 0) && (SIG_UNBLOCK == 1) && (SIG_SETMASK == 2) - (((unsigned int) how) > 2) -+#elif (SIG_BLOCK == 1) && (SIG_UNBLOCK == 2) && (SIG_SETMASK == 3) -+ (((unsigned int)(how-1)) > 2) - #else - #warning "compile time assumption violated.. slow path..." - ((how != SIG_BLOCK) && (how != SIG_UNBLOCK) -diff --git a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h -index b6f52cc..317e5b3 100644 ---- a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h -+++ b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h -@@ -38,3 +38,6 @@ struct kernel_sigaction { - void (*sa_restorer)(void); - int s_resv[1]; /* reserved */ - }; -+ -+extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *__unbounded, -+ struct kernel_sigaction *__unbounded, size_t); -diff --git a/libc/sysdeps/linux/mips/pipe.S b/libc/sysdeps/linux/mips/pipe.S -index c3afae5..cd88074 100644 ---- a/libc/sysdeps/linux/mips/pipe.S -+++ b/libc/sysdeps/linux/mips/pipe.S -@@ -7,25 +7,36 @@ - #include <asm/unistd.h> - #include <asm/regdef.h> - -- .globl pipe -- .ent pipe, 0 -+ .globl pipe -+ .ent pipe, 0 - pipe: -- addiu sp,sp,-24 -- sw a0,16(sp) -- li v0,__NR_pipe -- syscall -- beqz a3, 1f -- la t3, errno -- sw v0, (t3) -- li v0, -1 -- b 2f -+ .frame sp, 24, sp -+#ifdef __PIC__ -+ .set noreorder -+ .cpload $25 -+ .set reorder -+ addiu sp,sp,-24 -+ .cprestore 16 -+#else -+ addiu sp,sp,-24 -+#endif -+ sw a0,16(sp) -+ li v0,__NR_pipe -+ syscall -+ beqz a3, 1f -+#ifdef __PIC__ -+ la t0, __syscall_error -+ jr t9 -+#else -+ j __syscall_error -+#endif - 1: -- lw a0, 16(sp) -- sw v0, 0(a0) -- sw v1, 4(a0) -- li v0, 0 -+ lw a0, 16(sp) -+ sw v0, 0(a0) -+ sw v1, 4(a0) -+ li v0, 0 - 2: -- addiu sp,sp,24 -- j ra -- .end pipe -- .size pipe,.-pipe -+ addiu sp,sp,24 -+ j ra -+ .end pipe -+ .size pipe,.-pipe -diff --git a/libcrypt/des.c b/libcrypt/des.c -index 3b49a7a..f7a6be1 100644 ---- a/libcrypt/des.c -+++ b/libcrypt/des.c -@@ -504,7 +504,7 @@ do_des( u_int32_t l_in, u_int32_t r_in, - kl = kl1; - kr = kr1; - round = 16; -- while (round--) { -+ do { - /* - * Expand R to 48 bits (simulate the E-box). - */ -@@ -540,7 +540,7 @@ do_des( u_int32_t l_in, u_int32_t r_in, - f ^= l; - l = r; - r = f; -- } -+ } while (--round); - r = l; - l = f; - } -diff --git a/libpthread/linuxthreads/ptfork.c b/libpthread/linuxthreads/ptfork.c -index eb544f3..cfec2b7 100644 ---- a/libpthread/linuxthreads/ptfork.c -+++ b/libpthread/linuxthreads/ptfork.c -@@ -26,6 +26,15 @@ - #include "pthread.h" - #include "internals.h" - -+#warning hack alert... should be sufficent for system(), but what about other libc mutexes? -+#include <bits/uClibc_mutex.h> -+ -+__UCLIBC_MUTEX_EXTERN(__malloc_lock); -+ -+#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) -+#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) -+#warning hack alert block end -+ - struct handler_list { - void (*handler)(void); - struct handler_list * next; -@@ -91,9 +100,18 @@ pid_t __fork(void) - parent = pthread_atfork_parent; - pthread_mutex_unlock(&pthread_atfork_lock); - pthread_call_handlers(prepare); -+ -+#warning hack alert -+ __MALLOC_LOCK; -+ - pid = __libc_fork(); -+ -+#warning hack alert -+ __MALLOC_UNLOCK; -+ - if (pid == 0) { - __pthread_reset_main_thread(); -+#warning need to reconsider __fresetlockfiles! - __fresetlockfiles(); - pthread_call_handlers(child); - } else { -diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h ---- uClibc-0.9.28/libc/sysdeps/linux/common/bits/uClibc_mutex.h 1969-12-31 17:00:00.000000000 -0700 -+++ uClibc-mjn3/libc/sysdeps/linux/common/bits/uClibc_mutex.h 2006-03-08 11:21:58.000000000 -0700 -@@ -0,0 +1,87 @@ -+/* Copyright (C) 2006 Manuel Novoa III <mjn3@codepoet.org> -+ * -+ * GNU Library General Public License (LGPL) version 2 or later. -+ * -+ * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. -+ */ -+ -+#ifndef _UCLIBC_MUTEX_H -+#define _UCLIBC_MUTEX_H -+ -+#include <features.h> -+ -+#ifdef __UCLIBC_HAS_THREADS__ -+ -+#include <pthread.h> -+ -+#define __UCLIBC_MUTEX_TYPE pthread_mutex_t -+ -+#define __UCLIBC_MUTEX(M) pthread_mutex_t M -+#define __UCLIBC_MUTEX_INIT(M,I) pthread_mutex_t M = I -+#define __UCLIBC_MUTEX_STATIC(M,I) static pthread_mutex_t M = I -+#define __UCLIBC_MUTEX_EXTERN(M) extern pthread_mutex_t M -+ -+#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) \ -+ __pthread_mutex_lock(&(M)) -+ -+#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) \ -+ __pthread_mutex_unlock(&(M)) -+ -+#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \ -+ __pthread_mutex_trylock(&(M)) -+ -+#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) \ -+ do { \ -+ struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ -+ if (C) { \ -+ _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ -+ __pthread_mutex_unlock, \ -+ &(M)); \ -+ __pthread_mutex_lock(&(M)); \ -+ } \ -+ ((void)0) -+ -+#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) \ -+ if (C) { \ -+ _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1);\ -+ } \ -+ } while (0) -+ -+#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) int A -+ -+#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) \ -+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,((A=(V)) == 0)) -+ -+#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) \ -+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,(A == 0)) -+ -+#define __UCLIBC_MUTEX_LOCK(M) \ -+ __UCLIBC_MUTEX_CONDITIONAL_LOCK(M, 1) -+ -+#define __UCLIBC_MUTEX_UNLOCK(M) \ -+ __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M, 1) -+ -+#else -+ -+#define __UCLIBC_MUTEX(M) void *__UCLIBC_MUTEX_DUMMY_ ## M -+#define __UCLIBC_MUTEX_INIT(M,I) extern void *__UCLIBC_MUTEX_DUMMY_ ## M -+#define __UCLIBC_MUTEX_STATIC(M) extern void *__UCLIBC_MUTEX_DUMMY_ ## M -+#define __UCLIBC_MUTEX_EXTERN(M) extern void *__UCLIBC_MUTEX_DUMMY_ ## M -+ -+#define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) ((void)0) -+#define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) ((void)0) -+#define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) (0) /* Always succeed? */ -+ -+#define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) ((void)0) -+#define __UCLIBC_MUTEX_CONDITIONAL_UNLOCK(M,C) ((void)0) -+ -+#define __UCLIBC_MUTEX_AUTO_LOCK_VAR(A) ((void)0) -+#define __UCLIBC_MUTEX_AUTO_LOCK(M,A,V) ((void)0) -+#define __UCLIBC_MUTEX_AUTO_UNLOCK(M,A) ((void)0) -+ -+#define __UCLIBC_MUTEX_LOCK(M) ((void)0) -+#define __UCLIBC_MUTEX_UNLOCK(M) ((void)0) -+ -+#endif -+ -+#endif /* _UCLIBC_MUTEX_H */ -diff -urN -x .git uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c ---- uClibc-0.9.28/libc/sysdeps/linux/mips/pipe.c 2005-08-17 16:49:44.000000000 -0600 -+++ uClibc-mjn3/libc/sysdeps/linux/mips/pipe.c 1969-12-31 17:00:00.000000000 -0700 -@@ -1,23 +0,0 @@ --/* pipe system call for Linux/MIPS */ -- --/*see uClibc's sh/pipe.c and glibc-2.2.4's mips/pipe.S */ -- --#include <errno.h> --#include <unistd.h> --#include <syscall.h> -- --int pipe(int *fd) --{ -- register long int res __asm__ ("$2"); // v0 -- register long int res2 __asm__ ("$3"); // v1 -- -- asm ("move\t$4,%2\n\t" // $4 = a0 -- "syscall" /* Perform the system call. */ -- : "=r" (res) -- : "0" (__NR_pipe), "r" (fd) -- : "$4", "$7"); -- -- fd[0] = res; -- fd[1] = res2; -- return(0); --} |