From 1478c2de052374c6356db5513749a144c13791b1 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Thu, 7 Dec 2006 23:24:02 +0000 Subject: Major cleanup of internal mutex locking. Be more consistant in how we do things, and avoid potential deadlocks caused when a thread holding a uClibc internal lock get canceled and terminates without releasing the lock. This change also provides a single place, bits/uClibc_mutex.h, for thread libraries to modify to change all instances of internal locking. --- libc/inet/getnetent.c | 31 +- libc/inet/getproto.c | 44 +- libc/inet/getservice.c | 48 +- libc/inet/resolv.c | 635 +++++++++++++------------- libc/inet/rpc/create_xid.c | 13 +- libc/misc/dirent/closedir.c | 4 +- libc/misc/dirent/dirstream.h | 11 +- libc/misc/dirent/readdir.c | 4 +- libc/misc/dirent/readdir64.c | 4 +- libc/misc/dirent/readdir64_r.c | 4 +- libc/misc/dirent/readdir_r.c | 5 +- libc/misc/dirent/rewinddir.c | 4 +- libc/misc/dirent/seekdir.c | 4 +- libc/misc/mntent/mntent.c | 14 +- libc/misc/pthread/weaks.c | 3 + libc/misc/syslog/syslog.c | 42 +- libc/misc/time/time.c | 99 ++-- libc/misc/ttyent/getttyent.c | 12 +- libc/misc/utmp/utent.c | 77 ++-- libc/pwd_grp/lckpwdf.c | 37 +- libc/pwd_grp/pwd_grp.c | 97 ++-- libc/stdio/popen.c | 33 +- libc/stdlib/_atexit.c | 43 +- libc/stdlib/abort.c | 14 +- libc/stdlib/malloc-simple/alloc.c | 27 +- libc/stdlib/malloc-standard/calloc.c | 4 +- libc/stdlib/malloc-standard/free.c | 4 +- libc/stdlib/malloc-standard/mallinfo.c | 45 +- libc/stdlib/malloc-standard/malloc.c | 51 ++- libc/stdlib/malloc-standard/malloc.h | 11 +- libc/stdlib/malloc-standard/mallopt.c | 4 +- libc/stdlib/malloc-standard/memalign.c | 18 +- libc/stdlib/malloc-standard/realloc.c | 34 +- libc/stdlib/random.c | 23 +- libc/stdlib/setenv.c | 188 ++++---- libc/sysdeps/linux/common/bits/uClibc_mutex.h | 87 ++++ libc/sysdeps/linux/common/bits/uClibc_stdio.h | 213 ++++----- libc/sysdeps/linux/common/sigprocmask.c | 4 + 38 files changed, 997 insertions(+), 998 deletions(-) create mode 100644 libc/sysdeps/linux/common/bits/uClibc_mutex.h (limited to 'libc') diff --git a/libc/inet/getnetent.c b/libc/inet/getnetent.c index d3fdb988a..d5c25034c 100644 --- a/libc/inet/getnetent.c +++ b/libc/inet/getnetent.c @@ -29,12 +29,8 @@ libc_hidden_proto(rewind) libc_hidden_proto(fgets) libc_hidden_proto(abort) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); @@ -50,13 +46,13 @@ int _net_stayopen attribute_hidden; libc_hidden_proto(setnetent) void setnetent(int f) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (netf == NULL) netf = fopen(NETDB, "r" ); else rewind(netf); _net_stayopen |= f; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return; } libc_hidden_def(setnetent) @@ -64,13 +60,13 @@ libc_hidden_def(setnetent) libc_hidden_proto(endnetent) void endnetent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (netf) { fclose(netf); netf = NULL; } _net_stayopen = 0; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(endnetent) @@ -92,11 +88,11 @@ 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: @@ -108,8 +104,7 @@ again: p = fgets(line, BUFSIZ, netf); if (p == NULL) { - UNLOCK; - return (NULL); + goto DONE; } if (*p == '#') goto again; @@ -144,7 +139,9 @@ again: *cp++ = '\0'; } *q = NULL; - UNLOCK; - return (&net); + rv = &net; +DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); + return rv; } libc_hidden_def(getnetent) diff --git a/libc/inet/getproto.c b/libc/inet/getproto.c index a54532ede..7800eecb4 100644 --- a/libc/inet/getproto.c +++ b/libc/inet/getproto.c @@ -70,12 +70,8 @@ libc_hidden_proto(fgets) libc_hidden_proto(fclose) libc_hidden_proto(abort) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); @@ -99,26 +95,26 @@ static void __initbuf(void) libc_hidden_proto(setprotoent) void setprotoent(int f) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (protof == NULL) protof = fopen(_PATH_PROTOCOLS, "r" ); else rewind(protof); proto_stayopen |= f; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(setprotoent) libc_hidden_proto(endprotoent) void endprotoent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (protof) { fclose(protof); protof = NULL; } proto_stayopen = 0; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(endprotoent) @@ -131,6 +127,7 @@ int getprotoent_r(struct protoent *result_buf, register char *cp, **q; char **proto_aliases; char *line; + int rv; *result = NULL; @@ -138,28 +135,27 @@ int getprotoent_r(struct protoent *result_buf, 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: if ((p = fgets(line, BUFSIZ, protof)) == NULL) { - UNLOCK; - return TRY_AGAIN; + rv=TRY_AGAIN; + goto DONE; } if (*p == '#') @@ -196,7 +192,9 @@ again: } *q = NULL; *result=result_buf; - UNLOCK; + rv = 0; +DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); return 0; } libc_hidden_def(getprotoent_r) @@ -220,7 +218,7 @@ int getprotobyname_r(const char *name, 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) @@ -232,7 +230,7 @@ int getprotobyname_r(const char *name, found: if (!proto_stayopen) endprotoent(); - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return *result?0:ret; } libc_hidden_def(getprotobyname_r) @@ -256,14 +254,14 @@ int getprotobynumber_r (int proto_num, { 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 (!proto_stayopen) endprotoent(); - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return *result?0:ret; } libc_hidden_def(getprotobynumber_r) diff --git a/libc/inet/getservice.c b/libc/inet/getservice.c index 7f4939bbd..5a94c9c69 100644 --- a/libc/inet/getservice.c +++ b/libc/inet/getservice.c @@ -72,12 +72,8 @@ libc_hidden_proto(rewind) libc_hidden_proto(fgets) libc_hidden_proto(abort) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); @@ -102,26 +98,26 @@ static void __initbuf(void) libc_hidden_proto(setservent) void setservent(int f) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (servf == NULL) servf = fopen(_PATH_SERVICES, "r" ); else rewind(servf); serv_stayopen |= f; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(setservent) libc_hidden_proto(endservent) void endservent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (servf) { fclose(servf); servf = NULL; } serv_stayopen = 0; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(endservent) @@ -134,6 +130,7 @@ int getservent_r(struct servent * result_buf, register char *cp, **q; char **serv_aliases; char *line; + int rv; *result=NULL; @@ -141,30 +138,27 @@ int getservent_r(struct servent * result_buf, 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: if ((p = fgets(line, BUFSIZ, servf)) == NULL) { - UNLOCK; - errno=EIO; - return errno; + errno=rv=EIO; + goto DONE; } if (*p == '#') goto again; @@ -202,8 +196,10 @@ again: } *q = NULL; *result=result_buf; - UNLOCK; - return 0; + rv = 0; +DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); + return rv; } libc_hidden_def(getservent_r) @@ -224,7 +220,7 @@ int getservbyname_r(const char *name, const char *proto, 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) @@ -239,7 +235,7 @@ gotname: } if (!serv_stayopen) endservent(); - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return *result?0:ret; } libc_hidden_def(getservbyname_r) @@ -261,7 +257,7 @@ int getservbyport_r(int port, const char *proto, { 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) @@ -271,7 +267,7 @@ int getservbyport_r(int port, const char *proto, } if (!serv_stayopen) endservent(); - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return *result?0:ret; } libc_hidden_def(getservbyport_r) diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 26d68d26a..fab534ddf 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,8 @@ #include #include #include +#include + libc_hidden_proto(memcpy) libc_hidden_proto(memset) @@ -207,6 +209,9 @@ libc_hidden_proto(__ctype_b_loc) libc_hidden_proto(__ctype_b) #endif +__UCLIBC_MUTEX_EXTERN(__resolv_lock); + + #define MAX_RECURSE 5 #define REPLY_TIMEOUT 10 #define MAX_RETRIES 3 @@ -216,7 +221,7 @@ libc_hidden_proto(__ctype_b) #define MAX_ALIASES 5 /* 1:ip + 1:full + MAX_ALIASES:aliases + 1:NULL */ -#define ALIAS_DIM (2 + MAX_ALIASES + 1) +#define ALIAS_DIM (2 + MAX_ALIASES + 1) #undef DEBUG /* #define DEBUG */ @@ -235,12 +240,6 @@ extern int __searchdomains attribute_hidden; extern char * __searchdomain[MAX_SEARCH] attribute_hidden; -#ifdef __UCLIBC_HAS_THREADS__ -# include -extern pthread_mutex_t __resolv_lock; -#endif -#define BIGLOCK __pthread_mutex_lock(&__resolv_lock) -#define BIGUNLOCK __pthread_mutex_unlock(&__resolv_lock) @@ -608,11 +607,11 @@ int __encode_packet(struct resolv_header *h, struct resolv_answer **ar, unsigned char *dest, int maxlen) attribute_hidden; 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; @@ -674,7 +673,7 @@ int __decode_packet(unsigned char *data, struct resolv_header *h) #ifdef L_formquery int __form_query(int id, const char *name, int type, unsigned char *packet, int maxlen); 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; @@ -700,16 +699,8 @@ int __form_query(int id, const char *name, int type, unsigned char *packet, } #endif -#if defined(L_dnslookup) || defined(L_gethostent) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) -#endif - #ifdef L_dnslookup +__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, @@ -746,10 +737,10 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char 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) @@ -775,13 +766,13 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char 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; @@ -803,7 +794,7 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); #endif if (fd < 0) { - retries++; + retries++; continue; } @@ -825,11 +816,11 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char #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; } @@ -891,55 +882,55 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char first_answer = 1; for (j=0;jbuf; - 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); @@ -953,48 +944,48 @@ int attribute_hidden __dns_lookup(const char *name, int type, int nscount, char 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) @@ -1004,10 +995,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; } @@ -1019,10 +1010,8 @@ int __nameservers; char * __nameserver[MAX_SERVERS]; int __searchdomains; char * __searchdomain[MAX_SEARCH]; -#ifdef __UCLIBC_HAS_THREADS__ -# include -pthread_mutex_t __resolv_lock = PTHREAD_MUTEX_INITIALIZER; -#endif + +__UCLIBC_MUTEX_STATIC(__resolv_lock, PTHREAD_MUTEX_INITIALIZER); /* * we currently read formats not quite the same as that on normal @@ -1036,60 +1025,63 @@ int attribute_hidden __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) { - - 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'; - } + (fp = fopen("/etc/config/resolv.conf", "r"))) + { - 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]); + while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) { + + 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 @@ -1098,7 +1090,7 @@ int attribute_hidden __open_nameservers() void attribute_hidden __close_nameservers(void) { - BIGLOCK; + __UCLIBC_MUTEX_LOCK(__resolv_lock); while (__nameservers > 0) { free(__nameserver[--__nameservers]); __nameserver[__nameservers] = NULL; @@ -1107,7 +1099,7 @@ void attribute_hidden __close_nameservers(void) free(__searchdomain[--__searchdomains]); __searchdomain[__searchdomains] = NULL; } - BIGUNLOCK; + __UCLIBC_MUTEX_UNLOCK(__resolv_lock); } #endif @@ -1117,8 +1109,8 @@ struct hostent *gethostbyname(const char *name) { 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); @@ -1137,8 +1129,8 @@ struct hostent *gethostbyname2(const char *name, int family) #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); @@ -1174,7 +1166,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++) { @@ -1194,7 +1186,7 @@ int res_init(void) } } rp->nscount = __nameservers; - BIGUNLOCK; + __UCLIBC_MUTEX_UNLOCK(__resolv_lock); return(0); } @@ -1231,10 +1223,10 @@ int res_query(const char *dname, int class, int type, 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) { @@ -1264,10 +1256,10 @@ libc_hidden_def(res_query) * 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; @@ -1313,11 +1305,11 @@ int res_search(name, class, type, answer, anslen) 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); @@ -1340,22 +1332,22 @@ int res_search(name, class, type, answer, anslen) } 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, @@ -1399,10 +1391,10 @@ int res_search(name, class, type, answer, anslen) * 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; @@ -1416,7 +1408,7 @@ int res_querydomain(name, domain, class, type, answer, anslen) #ifdef DEBUG if (_res.options & RES_DEBUG) printf(";; res_querydomain(%s, %s, %d, %d)\n", - name, domain?domain:"", class, type); + name, domain?domain:"", class, type); #endif if (domain == NULL) { /* @@ -1458,11 +1450,11 @@ struct hostent *gethostbyaddr (const void *addr, socklen_t len, int type) 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); @@ -1634,25 +1626,26 @@ int attribute_hidden __read_etc_hosts_r(FILE * fp, const char * name, int type, #ifdef L_gethostent +__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); } - 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, @@ -1660,13 +1653,12 @@ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen, { int ret; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (__gethostent_fp == NULL) { __open_etc_hosts(&__gethostent_fp); if (__gethostent_fp == NULL) { - UNLOCK; *result=NULL; - return 0; + goto DONE; } } @@ -1675,7 +1667,8 @@ int gethostent_r(struct hostent *result_buf, char *buf, size_t buflen, if (__stay_open==0) { fclose(__gethostent_fp); } - UNLOCK; +DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); return(ret); } libc_hidden_def(gethostent_r) @@ -1685,17 +1678,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 @@ -1728,24 +1721,24 @@ int attribute_hidden __get_hosts_byaddr_r(const char * addr, int len, int type, #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 @@ -1757,8 +1750,8 @@ int attribute_hidden __get_hosts_byaddr_r(const char * addr, int len, int type, libc_hidden_proto(getnameinfo) 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; @@ -1949,10 +1942,10 @@ libc_hidden_def(getnameinfo) #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; @@ -1974,7 +1967,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: @@ -2036,60 +2029,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; } } @@ -2103,14 +2096,14 @@ libc_hidden_def(gethostbyname_r) #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; @@ -2138,7 +2131,7 @@ int gethostbyname2_r(const char *name, int family, __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: @@ -2191,10 +2184,10 @@ int gethostbyname2_r(const char *name, int family, 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); @@ -2245,10 +2238,10 @@ libc_hidden_def(gethostbyname2_r) #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; @@ -2290,7 +2283,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type, /* 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: @@ -2356,7 +2349,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type, 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); @@ -2366,9 +2359,9 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type, for (i = len - 1; i >= 0; i--) { qp += sprintf(qp, "%x.%x.", in6->s6_addr[i] & 0xf, - (in6->s6_addr[i] >> 4) & 0xf); - } - strcpy(qp, "ip6.int"); + (in6->s6_addr[i] >> 4) & 0xf); + } + strcpy(qp, "ip6.int"); #endif /* __UCLIBC_HAS_IPV6__ */ } @@ -2379,10 +2372,10 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type, 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) { @@ -2448,7 +2441,7 @@ libc_hidden_def(gethostbyaddr_r) * 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); @@ -2468,7 +2461,7 @@ int __dn_expand(const u_char *msg, const u_char *eom, const u_char *src, */ static int printable(int ch) { - return (ch > 0x20 && ch < 0x7f); + return (ch > 0x20 && ch < 0x7f); } /* @@ -2480,18 +2473,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); + } } /* @@ -2593,7 +2586,7 @@ int ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) { return (-1); } *dn++ = '\0'; - return (dn - dst); + return (dn - dst); } libc_hidden_def(ns_name_ntop) @@ -2623,46 +2616,46 @@ int ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src, 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 3b90d7a48..18b9c6e35 100644 --- a/libc/inet/rpc/create_xid.c +++ b/libc/inet/rpc/create_xid.c @@ -31,12 +31,9 @@ libc_hidden_proto(gettimeofday) /* The RPC code is not threadsafe, but new code should be threadsafe. */ -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t createxid_lock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&createxid_lock) -#define UNLOCK __pthread_mutex_unlock(&createxid_lock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); + static int is_initialized; static struct drand48_data __rpc_lrand48_data; @@ -46,7 +43,7 @@ u_long _create_xid (void) { unsigned long res; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (!is_initialized) { @@ -59,7 +56,7 @@ u_long _create_xid (void) lrand48_r (&__rpc_lrand48_data, &res); - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return res; } diff --git a/libc/misc/dirent/closedir.c b/libc/misc/dirent/closedir.c index f58857b82..3dc0bd17a 100644 --- a/libc/misc/dirent/closedir.c +++ b/libc/misc/dirent/closedir.c @@ -27,10 +27,10 @@ int closedir(DIR * dir) __set_errno(EBADF); return -1; } - __pthread_mutex_lock(&(dir->dd_lock)); + __UCLIBC_MUTEX_LOCK(dir->dd_lock); fd = dir->dd_fd; dir->dd_fd = -1; - __pthread_mutex_unlock(&(dir->dd_lock)); + __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 a90ca6312..761111b9e 100644 --- a/libc/misc/dirent/dirstream.h +++ b/libc/misc/dirent/dirstream.h @@ -26,9 +26,8 @@ Cambridge, MA 02139, USA. */ #include #include -#ifdef __UCLIBC_HAS_THREADS__ -#include -#endif + +#include /* 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 6fb1146eb..2fb7a7246 100644 --- a/libc/misc/dirent/readdir.c +++ b/libc/misc/dirent/readdir.c @@ -25,7 +25,7 @@ struct dirent *readdir(DIR * dir) return NULL; } - __pthread_mutex_lock(&(dir->dd_lock)); + __UCLIBC_MUTEX_LOCK(dir->dd_lock); do { if (dir->dd_size <= dir->dd_nextloc) { @@ -51,7 +51,7 @@ struct dirent *readdir(DIR * dir) } while (de->d_ino == 0); all_done: - __pthread_mutex_unlock(&(dir->dd_lock)); + __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); return de; } libc_hidden_def(readdir) diff --git a/libc/misc/dirent/readdir64.c b/libc/misc/dirent/readdir64.c index 5386ee17e..36dc35379 100644 --- a/libc/misc/dirent/readdir64.c +++ b/libc/misc/dirent/readdir64.c @@ -25,7 +25,7 @@ struct dirent64 *readdir64(DIR * dir) return NULL; } - __pthread_mutex_lock(&(dir->dd_lock)); + __UCLIBC_MUTEX_LOCK(dir->dd_lock); do { if (dir->dd_size <= dir->dd_nextloc) { @@ -51,7 +51,7 @@ struct dirent64 *readdir64(DIR * dir) } while (de->d_ino == 0); all_done: - __pthread_mutex_unlock(&(dir->dd_lock)); + __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 b42351702..23fd8f6d9 100644 --- a/libc/misc/dirent/readdir64_r.c +++ b/libc/misc/dirent/readdir64_r.c @@ -29,7 +29,7 @@ int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result) } de = NULL; - __pthread_mutex_lock(&(dir->dd_lock)); + __UCLIBC_MUTEX_LOCK(dir->dd_lock); do { if (dir->dd_size <= dir->dd_nextloc) { @@ -63,7 +63,7 @@ int readdir64_r(DIR *dir, struct dirent64 *entry, struct dirent64 **result) all_done: - __pthread_mutex_unlock(&(dir->dd_lock)); + __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); return((de != NULL)? 0 : ret); } libc_hidden_def(readdir64_r) diff --git a/libc/misc/dirent/readdir_r.c b/libc/misc/dirent/readdir_r.c index a1d8b9a77..9493ecc0d 100644 --- a/libc/misc/dirent/readdir_r.c +++ b/libc/misc/dirent/readdir_r.c @@ -26,7 +26,7 @@ int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) } de = NULL; - __pthread_mutex_lock(&(dir->dd_lock)); + __UCLIBC_MUTEX_LOCK(dir->dd_lock); do { if (dir->dd_size <= dir->dd_nextloc) { @@ -60,8 +60,7 @@ int readdir_r(DIR *dir, struct dirent *entry, struct dirent **result) all_done: - __pthread_mutex_unlock(&(dir->dd_lock)); - + __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); return((de != NULL)? 0 : ret); } libc_hidden_def(readdir_r) diff --git a/libc/misc/dirent/rewinddir.c b/libc/misc/dirent/rewinddir.c index 516700183..1bbda0809 100644 --- a/libc/misc/dirent/rewinddir.c +++ b/libc/misc/dirent/rewinddir.c @@ -18,8 +18,8 @@ void rewinddir(DIR * dir) __set_errno(EBADF); return; } - __pthread_mutex_lock(&(dir->dd_lock)); + __UCLIBC_MUTEX_LOCK(dir->dd_lock); lseek(dir->dd_fd, 0, SEEK_SET); dir->dd_nextoff = dir->dd_nextloc = dir->dd_size = 0; - __pthread_mutex_unlock(&(dir->dd_lock)); + __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); } diff --git a/libc/misc/dirent/seekdir.c b/libc/misc/dirent/seekdir.c index ba25ffd40..c41844856 100644 --- a/libc/misc/dirent/seekdir.c +++ b/libc/misc/dirent/seekdir.c @@ -17,8 +17,8 @@ void seekdir(DIR * dir, long int offset) __set_errno(EBADF); return; } - __pthread_mutex_lock(&(dir->dd_lock)); + __UCLIBC_MUTEX_LOCK(dir->dd_lock); dir->dd_nextoff = lseek(dir->dd_fd, offset, SEEK_SET); dir->dd_size = dir->dd_nextloc = 0; - __pthread_mutex_unlock(&(dir->dd_lock)); + __UCLIBC_MUTEX_UNLOCK(dir->dd_lock); } diff --git a/libc/misc/mntent/mntent.c b/libc/misc/mntent/mntent.c index 3164f6634..a5db799dc 100644 --- a/libc/misc/mntent/mntent.c +++ b/libc/misc/mntent/mntent.c @@ -8,6 +8,9 @@ #include #include #include +#include + +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); libc_hidden_proto(getmntent_r) libc_hidden_proto(setmntent) @@ -23,13 +26,6 @@ libc_hidden_proto(fgets) libc_hidden_proto(abort) libc_hidden_proto(fprintf) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) - /* Reentrant version of getmntent. */ struct mntent *getmntent_r (FILE *filep, struct mntent *mnt, char *buff, int bufsize) @@ -85,7 +81,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); @@ -94,7 +90,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 68b603cc5..1566846ca 100644 --- a/libc/misc/pthread/weaks.c +++ b/libc/misc/pthread/weaks.c @@ -30,11 +30,14 @@ static int __pthread_return_0 (void); static int __pthread_return_0 (void) { return 0; } +static void __pthread_return_void (void) { return; } weak_alias (__pthread_return_0, __pthread_mutex_init) weak_alias (__pthread_return_0, __pthread_mutex_lock) 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) #ifdef __UCLIBC_HAS_THREADS_NATIVE__ weak_alias (__pthread_return_0, __pthread_mutexattr_init) weak_alias (__pthread_return_0, __pthread_mutexattr_destroy) diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c index 10b8e6e58..0a5c48f86 100644 --- a/libc/misc/syslog/syslog.c +++ b/libc/misc/syslog/syslog.c @@ -104,12 +104,8 @@ libc_hidden_proto(sprintf) libc_hidden_proto(vsnprintf) libc_hidden_proto(time) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); static int LogFile = -1; /* fd for log */ @@ -120,10 +116,10 @@ static int LogFacility = LOG_USER; /* default facility code */ static int LogMask = 0xff; /* mask of priorities to be logged */ static struct sockaddr SyslogAddr; /* AF_UNIX address of local logger */ -static void +static void closelog_intern(int to_default) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (LogFile != -1) { (void) close(LogFile); } @@ -136,7 +132,7 @@ closelog_intern(int to_default) LogFacility = LOG_USER; LogMask = 0xff; } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } static void @@ -153,7 +149,7 @@ openlog( const char *ident, int logstat, int logfac ) { int logType = SOCK_DGRAM; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (ident != NULL) LogTag = ident; @@ -166,16 +162,15 @@ openlog( const char *ident, int logstat, int logfac ) sizeof(SyslogAddr.sa_data)); retry: if (LogStat & LOG_NDELAY) { - if ((LogFile = socket(AF_UNIX, logType, 0)) == -1){ - UNLOCK; - return; + 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) - + if (connect(LogFile, &SyslogAddr, sizeof(SyslogAddr) - sizeof(SyslogAddr.sa_data) + strlen(SyslogAddr.sa_data)) != -1) { connected = 1; @@ -194,7 +189,8 @@ retry: } } - UNLOCK; +DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); } libc_hidden_def(openlog) @@ -221,7 +217,7 @@ vsyslog( int pri, const char *fmt, va_list ap ) 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))) @@ -264,7 +260,7 @@ vsyslog( int pri, const char *fmt, va_list ap ) 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) { @@ -299,7 +295,7 @@ vsyslog( int pri, const char *fmt, va_list ap ) } p+=rc; } while (p <= last_chr); - if (rc >= 0) + if (rc >= 0) goto getout; /* @@ -318,10 +314,10 @@ vsyslog( int pri, const char *fmt, va_list ap ) } getout: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); if (sigpipe == 0) sigaction (SIGPIPE, &oldaction, - (struct sigaction *) NULL); + (struct sigaction *) NULL); } libc_hidden_def(vsyslog) @@ -352,10 +348,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 b73fe2cce..91b4097ff 100644 --- a/libc/misc/time/time.c +++ b/libc/misc/time/time.c @@ -86,7 +86,7 @@ * NOTE: uClibc mktime behavior is different than glibc's when * the struct tm has tm_isdst == -1 and also had fields outside of * the normal ranges. - * + * * Apparently, glibc examines (at least) tm_sec and guesses the app's * intention of assuming increasing or decreasing time when entering an * ambiguous time period at the dst<->st boundaries. @@ -145,6 +145,8 @@ #include #include #include +#include + #ifdef __UCLIBC_HAS_WCHAR__ #include @@ -246,12 +248,7 @@ typedef struct { char tzname[TZNAME_MAX+1]; } rule_struct; -#ifdef __UCLIBC_HAS_THREADS__ -# include -extern pthread_mutex_t _time_tzlock attribute_hidden; -#endif -#define TZLOCK __pthread_mutex_lock(&_time_tzlock) -#define TZUNLOCK __pthread_mutex_unlock(&_time_tzlock) +__UCLIBC_MUTEX_EXTERN(_time_tzlock); extern rule_struct _time_tzinfo[2] attribute_hidden; @@ -292,16 +289,16 @@ libc_hidden_def(asctime) * }; * static char mon_name[12][3] = { * "Jan", "Feb", "Mar", "Apr", "May", "Jun", - * "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + * "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" * }; * static char result[26]; - * + * * sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", - * wday_name[timeptr->tm_wday], + * wday_name[timeptr->tm_wday], * mon_name[timeptr->tm_mon], * timeptr->tm_mday, timeptr->tm_hour, - * timeptr->tm_min, timeptr->tm_sec, - * 1900 + timeptr->tm_year); + * timeptr->tm_min, timeptr->tm_sec, + * 1900 + timeptr->tm_year); * return result; * } * @@ -327,10 +324,10 @@ static const unsigned char at_data[] = { 'J', 'a', 'n', 'F', 'e', 'b', 'M', 'a', 'r', 'A', 'p', 'r', 'M', 'a', 'y', 'J', 'u', 'n', 'J', 'u', 'l', 'A', 'u', 'g', - 'S', 'e', 'p', 'O', 'c', 't', 'N', 'o', 'v', 'D', 'e', 'c', + 'S', 'e', 'p', 'O', 'c', 't', 'N', 'o', 'v', 'D', 'e', 'c', #ifdef SAFE_ASCTIME_R - '?', '?', '?', + '?', '?', '?', #endif ' ', '?', '?', '?', ' ', '0', @@ -605,13 +602,13 @@ libc_hidden_def(localtime) struct tm *localtime_r(register const time_t *__restrict timer, register struct tm *__restrict result) { - TZLOCK; + __UCLIBC_MUTEX_LOCK(_time_tzlock); _time_tzset(*timer < new_rule_starts); __time_localtime_tzi(timer, result, _time_tzinfo); - TZUNLOCK; + __UCLIBC_MUTEX_UNLOCK(_time_tzlock); return result; } @@ -666,7 +663,7 @@ static const char *lookup_tzname(const char *key) static const unsigned char day_cor[] = { /* non-leap */ 31, 31, 34, 34, 35, 35, 36, 36, 36, 37, 37, 38, 38 -/* 0, 0, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7 */ +/* 0, 0, 3, 3, 4, 4, 5, 5, 5, 6, 6, 7, 7 */ /* 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 */ }; @@ -1052,7 +1049,7 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, p = format; count = maxsize; - LOOP: +LOOP: if (!count) { return 0; } @@ -1115,7 +1112,7 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, goto LOOP; } - o = spec + 26; /* set to "????" */ + o = ((const char *) spec) + 26; /* set to "????" */ if ((code & MASK_SPEC) == CALC_SPEC) { if (*p == 's') { @@ -1151,7 +1148,6 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, #ifdef __UCLIBC_HAS_TM_EXTENSIONS__ -#define RSP_TZUNLOCK ((void) 0) # ifdef __USE_BSD # define RSP_TZNAME timeptr->tm_zone # define RSP_GMT_OFFSET (-timeptr->tm_gmtoff) @@ -1162,11 +1158,10 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, #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) { @@ -1197,24 +1192,30 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, } #endif o_count = SIZE_MAX; - RSP_TZUNLOCK; +#ifdef __UCLIBC_HAS_TM_EXTENSIONS__ goto OUTPUT; +#endif } else { /* z */ *s = '+'; if ((tzo = -RSP_GMT_OFFSET) < 0) { tzo = -tzo; *s = '-'; } - RSP_TZUNLOCK; ++s; --count; i = tzo / 60; field_val = ((i / 60) * 100) + (i % 60); - + 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++) { @@ -1286,7 +1287,7 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, field_val += 7; } } - + if ((code & MASK_SPEC) == STRING_SPEC) { o_count = SIZE_MAX; field_val += spec[STRINGS_NL_ITEM_START + (code & 0xf)]; @@ -1304,7 +1305,7 @@ size_t __XL_NPP(strftime)(char *__restrict s, size_t maxsize, } } - OUTPUT: +OUTPUT: ++p; while (o_count && count && *o) { *s++ = *o++; @@ -1506,7 +1507,7 @@ char *__XL_NPP(strptime)(const char *__restrict buf, const char *__restrict form lvl = 0; p = format; - LOOP: +LOOP: if (!*p) { if (lvl == 0) { /* Done. */ if (fields[6] == 7) { /* Cleanup for %u here since just once. */ @@ -1752,9 +1753,7 @@ int daylight = 0; long timezone = 0; char *tzname[2] = { (char *) UTC, (char *) (UTC-1) }; -#ifdef __UCLIBC_HAS_THREADS__ -attribute_hidden 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]; @@ -1827,7 +1826,7 @@ static const char *getnumber(register const char *e, int *pn) #ifdef __UCLIBC_HAS_TZ_FILE__ #ifndef __UCLIBC_HAS_TZ_FILE_READ_MANY__ -static int TZ_file_read; /* Let BSS initialization set this to 0. */ +static int TZ_file_read; /* Let BSS initialization set this to 0. */ #endif /* __UCLIBC_HAS_TZ_FILE_READ_MANY__ */ static char *read_TZ_file(char *buf) @@ -1858,7 +1857,7 @@ static char *read_TZ_file(char *buf) ++TZ_file_read; #endif /* __UCLIBC_HAS_TZ_FILE_READ_MANY__ */ } else { - ERROR: +ERROR: p = NULL; } close(fd); @@ -1893,7 +1892,7 @@ void _time_tzset(int use_old_rules) 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. */ @@ -1918,7 +1917,7 @@ void _time_tzset(int use_old_rules) && !(e = read_TZ_file(buf)) /* and no file or invalid file */ #endif /* __UCLIBC_HAS_TZ_FILE__ */ ) || !*e) { /* or set to empty string. */ - ILLEGAL: /* TODO: Clean up the following... */ +ILLEGAL: /* TODO: Clean up the following... */ #ifdef __UCLIBC_HAS_TZ_CACHING__ *oldval = 0; /* Set oldval to an empty string. */ #endif /* __UCLIBC_HAS_TZ_CACHING__ */ @@ -1940,10 +1939,10 @@ void _time_tzset(int use_old_rules) * to the empty string anyway. */ strncpy(oldval, e, TZ_BUFLEN); #endif /* __UCLIBC_HAS_TZ_CACHING__ */ - + count = 0; new_rules[1].tzname[0] = 0; - LOOP: +LOOP: /* Get std or dst name. */ c = 0; if (*e == '<') { @@ -1989,7 +1988,7 @@ void _time_tzset(int use_old_rules) if (*s == '-') { off = -off; /* Save off in case needed for dst default. */ } - SKIP_OFFSET: +SKIP_OFFSET: new_rules[count].gmt_offset = off; if (!count) { @@ -2002,7 +2001,7 @@ void _time_tzset(int use_old_rules) count = 0; if (!*e) { /* No rules so default to US rules. */ e = use_old_rules ? DEFAULT_RULES : DEFAULT_2007_RULES; -#ifdef DEBUG_TZSET +#ifdef DEBUG_TZSET if (e == DEFAULT_RULES) printf("tzset: Using old rules.\n"); else if (e == DEFAULT_2007_RULES) @@ -2061,16 +2060,16 @@ void _time_tzset(int use_old_rules) } memcpy(_time_tzinfo, new_rules, sizeof(new_rules)); - DONE: +DONE: tzname[0] = _time_tzinfo[0].tzname; tzname[1] = _time_tzinfo[1].tzname; daylight = !!_time_tzinfo[1].tzname[0]; timezone = _time_tzinfo[0].gmt_offset; #if defined(__UCLIBC_HAS_TZ_FILE__) || defined(__UCLIBC_HAS_TZ_CACHING__) - FAST_DONE: +FAST_DONE: #endif - TZUNLOCK; + __UCLIBC_MUTEX_UNLOCK(_time_tzlock); } libc_hidden_def(tzset) #endif @@ -2171,7 +2170,7 @@ struct tm attribute_hidden *_time_t2tm(const time_t *__restrict timer, ++v; /* Change to days since 1/1/1601 so that for 32 bit time_t * values, we'll have t >= 0. This should be changed for - * archs with larger time_t types. + * archs with larger time_t types. * Also, correct for offset since a multiple of 7. */ /* TODO: Does this still work on archs with time_t > 32 bits? */ @@ -2277,13 +2276,13 @@ time_t attribute_hidden _time_mktime(struct tm *timeptr, int store_on_success) { 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; } @@ -2336,7 +2335,7 @@ time_t attribute_hidden _time_mktime_tzi(struct tm *timeptr, int store_on_succes if (__isleap(d)) { s += 11; } - + p[7] = 0; d = p[4]; while (d) { @@ -2355,7 +2354,7 @@ time_t attribute_hidden _time_mktime_tzi(struct tm *timeptr, int store_on_succes days = -719163L + ((long)d)*365 + ((d/4) - (d/100) + (d/400) + p[3] + p[7]); secs = p[0] + 60*( p[1] + 60*((long)(p[2])) ) + tzi[default_dst].gmt_offset; - DST_CORRECT: +DST_CORRECT: if (secs < 0) { secs += 120009600L; days -= 1389; @@ -2375,7 +2374,7 @@ time_t attribute_hidden _time_mktime_tzi(struct tm *timeptr, int store_on_succes + 24*(((146073L * ((long long)(p[6])) + d) + p[3]) + p[7]))); - DST_CORRECT: +DST_CORRECT: if (((unsigned long long)(secs - LONG_MIN)) > (((unsigned long long)LONG_MAX) - LONG_MIN) ) { @@ -2408,7 +2407,7 @@ time_t attribute_hidden _time_mktime_tzi(struct tm *timeptr, int store_on_succes } - DONE: +DONE: return t; } diff --git a/libc/misc/ttyent/getttyent.c b/libc/misc/ttyent/getttyent.c index 89c39876f..c9c68f1cc 100644 --- a/libc/misc/ttyent/getttyent.c +++ b/libc/misc/ttyent/getttyent.c @@ -126,6 +126,7 @@ struct ttyent * getttyent(void) register int c; register char *p; static char *line = NULL; + struct ttyent *retval = NULL; if (!tf && !setttyent()) return (NULL); @@ -140,8 +141,7 @@ struct ttyent * getttyent(void) for (;;) { if (!fgets_unlocked(p = line, BUFSIZ, tf)) { - __STDIO_ALWAYS_THREADUNLOCK(tf); - return (NULL); + goto DONE; } /* skip lines that are too big */ if (!strchr(p, '\n')) { @@ -184,8 +184,6 @@ struct ttyent * getttyent(void) 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') @@ -195,7 +193,11 @@ struct ttyent * getttyent(void) tty.ty_comment = 0; if ((p = strchr(p, '\n'))) *p = '\0'; - return (&tty); + retval = &tty; + + DONE: + __STDIO_ALWAYS_THREADUNLOCK(tf); + return retval; } libc_hidden_def(getttyent) diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c index 57719ba68..daa68d24e 100644 --- a/libc/misc/utmp/utent.c +++ b/libc/misc/utmp/utent.c @@ -5,7 +5,7 @@ Note that because of the way this stupid stupid standard works, you have to call endutent() to close the file even if you've not called - setutent -- getutid and family use the same file descriptor. + setutent -- getutid and family use the same file descriptor. Modified by Erik Andersen for uClibc... */ @@ -30,12 +30,8 @@ libc_hidden_proto(fcntl) libc_hidden_proto(close) libc_hidden_proto(lseek) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t utmplock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&utmplock) -#define UNLOCK __pthread_mutex_unlock(&utmplock) +#include +__UCLIBC_MUTEX_STATIC(utmplock, PTHREAD_MUTEX_INITIALIZER); @@ -75,9 +71,9 @@ bummer: libc_hidden_proto(setutent) void setutent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(utmplock); __setutent(); - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(utmplock); } libc_hidden_def(setutent) @@ -93,7 +89,7 @@ static struct utmp *__getutent(int utmp_fd) return NULL; } - if (read(utmp_fd, (char *) &static_utmp, sizeof(struct utmp)) == sizeof(struct utmp)) + if (read(utmp_fd, (char *) &static_utmp, sizeof(struct utmp)) == sizeof(struct utmp)) { ret = &static_utmp; } @@ -103,21 +99,20 @@ static struct utmp *__getutent(int utmp_fd) void endutent(void) { - LOCK; + __UCLIBC_MUTEX_LOCK(utmplock); if (static_fd != -1) close(static_fd); static_fd = -1; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(utmplock); } struct utmp *getutent(void) { struct utmp *ret = NULL; - LOCK; + __UCLIBC_MUTEX_LOCK(utmplock); ret = __getutent(static_fd); - UNLOCK; - + __UCLIBC_MUTEX_UNLOCK(utmplock); return ret; } @@ -127,22 +122,22 @@ static struct utmp *__getutid(const struct utmp *utmp_entry) 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; @@ -153,10 +148,9 @@ struct utmp *getutid(const struct utmp *utmp_entry) { struct utmp *ret = NULL; - LOCK; + __UCLIBC_MUTEX_LOCK(utmplock); ret = __getutid(utmp_entry); - UNLOCK; - + __UCLIBC_MUTEX_UNLOCK(utmplock); return ret; } libc_hidden_def(getutid) @@ -165,21 +159,20 @@ struct utmp *getutline(const struct utmp *utmp_entry) { struct utmp *lutmp = NULL; - LOCK; + __UCLIBC_MUTEX_LOCK(utmplock); 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)) { break; } } - UNLOCK; - + __UCLIBC_MUTEX_UNLOCK(utmplock); return lutmp; } 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); @@ -191,19 +184,19 @@ struct utmp *pututline (const struct utmp *utmp_entry) if (write(static_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp)) utmp_entry = 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 + /* We should probably whine about out-of-memory * errors here... Instead just reset to the default */ static_ut_name = default_file_name; } @@ -212,6 +205,6 @@ int utmpname (const char *new_ut_name) if (static_fd != -1) close(static_fd); static_fd = -1; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(utmplock); return 0; } diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c index 2d38e89f9..f241cdffc 100644 --- a/libc/pwd_grp/lckpwdf.c +++ b/libc/pwd_grp/lckpwdf.c @@ -48,12 +48,8 @@ libc_hidden_proto(alarm) static int lock_fd = -1; /* Prevent problems in multithreaded program by using mutex. */ -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); /* Prototypes for local functions. */ @@ -70,19 +66,19 @@ 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; /* Prevent problems caused by multiple threads. */ - 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. */ @@ -91,16 +87,14 @@ 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 @@ -121,8 +115,7 @@ 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. */ @@ -132,8 +125,7 @@ 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 @@ -160,11 +152,12 @@ lckpwdf (void) if (result < 0) { close(lock_fd); lock_fd = -1; - UNLOCK; - return -1; + goto DONE; } + rv = 0; - UNLOCK; +DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); return 0; } @@ -180,7 +173,7 @@ ulckpwdf (void) else { /* Prevent problems caused by multiple threads. */ - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); result = close (lock_fd); @@ -188,7 +181,7 @@ ulckpwdf (void) lock_fd = -1; /* Clear mutex. */ - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); } return result; diff --git a/libc/pwd_grp/pwd_grp.c b/libc/pwd_grp/pwd_grp.c index 2a9d4519a..d223a9e36 100644 --- a/libc/pwd_grp/pwd_grp.c +++ b/libc/pwd_grp/pwd_grp.c @@ -34,9 +34,7 @@ #ifdef __UCLIBC_HAS_SHADOW__ #include #endif -#ifdef __UCLIBC_HAS_THREADS__ -#include -#endif +#include libc_hidden_proto(strchr) libc_hidden_proto(strcmp) @@ -253,7 +251,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getpwnam_r #define GETXXKEY_R_FUNC getpwnam_r -#define GETXXKEY_R_PARSER __parsepwent +#define GETXXKEY_R_PARSER __parsepwent #define GETXXKEY_R_ENTTYPE struct passwd #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->pw_name, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict @@ -263,7 +261,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getgrnam_r #define GETXXKEY_R_FUNC getgrnam_r -#define GETXXKEY_R_PARSER __parsegrent +#define GETXXKEY_R_PARSER __parsegrent #define GETXXKEY_R_ENTTYPE struct group #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->gr_name, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict @@ -273,7 +271,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getspnam_r #define GETXXKEY_R_FUNC getspnam_r -#define GETXXKEY_R_PARSER __parsespent +#define GETXXKEY_R_PARSER __parsespent #define GETXXKEY_R_ENTTYPE struct spwd #define GETXXKEY_R_TEST(ENT) (!strcmp((ENT)->sp_namp, key)) #define DO_GETXXKEY_R_KEYTYPE const char *__restrict @@ -283,7 +281,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getpwuid_r #define GETXXKEY_R_FUNC getpwuid_r -#define GETXXKEY_R_PARSER __parsepwent +#define GETXXKEY_R_PARSER __parsepwent #define GETXXKEY_R_ENTTYPE struct passwd #define GETXXKEY_R_TEST(ENT) ((ENT)->pw_uid == key) #define DO_GETXXKEY_R_KEYTYPE uid_t @@ -293,7 +291,7 @@ libc_hidden_def(sgetspent_r) #ifdef L_getgrgid_r #define GETXXKEY_R_FUNC getgrgid_r -#define GETXXKEY_R_PARSER __parsegrent +#define GETXXKEY_R_PARSER __parsegrent #define GETXXKEY_R_ENTTYPE struct group #define GETXXKEY_R_TEST(ENT) ((ENT)->gr_gid == key) #define DO_GETXXKEY_R_KEYTYPE gid_t @@ -458,47 +456,40 @@ int getpw(uid_t uid, char *buf) #endif /**********************************************************************/ -#if defined(L_getpwent_r) || defined(L_getgrent_r) || defined(L_getspent_r) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) -#endif #ifdef L_getpwent_r +__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); } libc_hidden_proto(getpwent_r) -int getpwent_r(struct passwd *__restrict resultbuf, +int getpwent_r(struct passwd *__restrict resultbuf, char *__restrict buffer, size_t buflen, struct passwd **__restrict result) { int rv; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); *result = NULL; /* In case of error... */ @@ -516,7 +507,7 @@ int getpwent_r(struct passwd *__restrict resultbuf, } ERR: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return rv; } @@ -525,26 +516,27 @@ libc_hidden_def(getpwent_r) #endif /**********************************************************************/ #ifdef L_getgrent_r +__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); } libc_hidden_proto(getgrent_r) @@ -554,7 +546,7 @@ int getgrent_r(struct group *__restrict resultbuf, { int rv; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); *result = NULL; /* In case of error... */ @@ -572,7 +564,7 @@ int getgrent_r(struct group *__restrict resultbuf, } ERR: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return rv; } @@ -581,35 +573,36 @@ libc_hidden_def(getgrent_r) #endif /**********************************************************************/ #ifdef L_getspent_r +__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); } libc_hidden_proto(getspent_r) -int getspent_r(struct spwd *resultbuf, char *buffer, +int getspent_r(struct spwd *resultbuf, char *buffer, size_t buflen, struct spwd **result) { int rv; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); *result = NULL; /* In case of error... */ @@ -627,7 +620,7 @@ int getspent_r(struct spwd *resultbuf, char *buffer, } ERR: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return rv; } @@ -842,11 +835,11 @@ int putgrent(const struct group *__restrict p, FILE *__restrict f) static const unsigned char _sp_off[] = { offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ - offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ + offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ - offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ - offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ - offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ + offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ + offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ + offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ }; int putspent(const struct spwd *p, FILE *stream) @@ -899,13 +892,13 @@ int putspent(const struct spwd *p, FILE *stream) #ifdef L___parsepwent static const unsigned char pw_off[] = { - offsetof(struct passwd, pw_name), /* 0 */ + offsetof(struct passwd, pw_name), /* 0 */ offsetof(struct passwd, pw_passwd), /* 1 */ offsetof(struct passwd, pw_uid), /* 2 - not a char ptr */ - offsetof(struct passwd, pw_gid), /* 3 - not a char ptr */ + offsetof(struct passwd, pw_gid), /* 3 - not a char ptr */ offsetof(struct passwd, pw_gecos), /* 4 */ - offsetof(struct passwd, pw_dir), /* 5 */ - offsetof(struct passwd, pw_shell) /* 6 */ + offsetof(struct passwd, pw_dir), /* 5 */ + offsetof(struct passwd, pw_shell) /* 6 */ }; int attribute_hidden __parsepwent(void *data, char *line) @@ -918,7 +911,7 @@ int attribute_hidden __parsepwent(void *data, char *line) do { p = ((char *) ((struct passwd *) data)) + pw_off[i]; - if ((i & 6) ^ 2) { /* i!=2 and i!=3 */ + if ((i & 6) ^ 2) { /* i!=2 and i!=3 */ *((char **) p) = line; if (i==6) { return 0; @@ -958,7 +951,7 @@ int attribute_hidden __parsepwent(void *data, char *line) #ifdef L___parsegrent static const unsigned char gr_off[] = { - offsetof(struct group, gr_name), /* 0 */ + offsetof(struct group, gr_name), /* 0 */ offsetof(struct group, gr_passwd), /* 1 */ offsetof(struct group, gr_gid) /* 2 - not a char ptr */ }; @@ -1040,7 +1033,7 @@ int attribute_hidden __parsegrent(void *data, char *line) if (!--i) break; while (*++p) {} } while (1); - } + } *members = NULL; return 0; @@ -1059,12 +1052,12 @@ static const unsigned char sp_off[] = { offsetof(struct spwd, sp_namp), /* 0 */ offsetof(struct spwd, sp_pwdp), /* 1 */ offsetof(struct spwd, sp_lstchg), /* 2 - not a char ptr */ - offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ + offsetof(struct spwd, sp_min), /* 3 - not a char ptr */ offsetof(struct spwd, sp_max), /* 4 - not a char ptr */ - offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ - offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ - offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ - offsetof(struct spwd, sp_flag) /* 8 - not a char ptr */ + offsetof(struct spwd, sp_warn), /* 5 - not a char ptr */ + offsetof(struct spwd, sp_inact), /* 6 - not a char ptr */ + offsetof(struct spwd, sp_expire), /* 7 - not a char ptr */ + offsetof(struct spwd, sp_flag) /* 8 - not a char ptr */ }; int attribute_hidden __parsespent(void *data, char * line) diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c index 2163d7f8c..43d07fa0f 100644 --- a/libc/stdio/popen.c +++ b/libc/stdio/popen.c @@ -20,6 +20,11 @@ #include #include #include +#include + +#ifdef __UCLIBC_MJN3_ONLY__ +#warning "hmm... susv3 says Pipe streams are byte-oriented." +#endif /* __UCLIBC_MJN3_ONLY__ */ libc_hidden_proto(close) libc_hidden_proto(_exit) @@ -34,22 +39,16 @@ libc_hidden_proto(fclose) /* uClinux-2.0 has vfork, but Linux 2.0 doesn't */ #include #if ! defined __NR_vfork -# define vfork fork +# define vfork fork # define VFORK_LOCK ((void) 0) -# define VFORK_UNLOCK ((void) 0) +# define VFORK_UNLOCK ((void) 0) libc_hidden_proto(fork) #endif -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) - #ifndef VFORK_LOCK -# define VFORK_LOCK LOCK -# define VFORK_UNLOCK UNLOCK +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); +# define VFORK_LOCK __UCLIBC_MUTEX_LOCK(mylock) +# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock) #endif struct popen_list_item { @@ -126,11 +125,11 @@ FILE *popen(const char *command, const char *modes) if (pid > 0) { /* Parent of vfork... */ pi->pid = pid; pi->f = fp; - LOCK; + VFORK_LOCK; pi->next = popen_list; popen_list = pi; - UNLOCK; - + VFORK_UNLOCK; + return fp; } @@ -144,6 +143,8 @@ FILE *popen(const char *command, const char *modes) return NULL; } +#warning is pclose correct wrt the new mutex semantics? + int pclose(FILE *stream) { struct popen_list_item *p; @@ -152,7 +153,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; + VFORK_LOCK; if ((p = popen_list) != NULL) { if (p->f == stream) { popen_list = p->next; @@ -171,7 +172,7 @@ int pclose(FILE *stream) } while (1); } } - UNLOCK; + VFORK_UNLOCK; if (p) { pid = p->pid; /* Save the pid we need */ diff --git a/libc/stdlib/_atexit.c b/libc/stdlib/_atexit.c index 236156001..5b290c928 100644 --- a/libc/stdlib/_atexit.c +++ b/libc/stdlib/_atexit.c @@ -20,7 +20,7 @@ * _stdio_term. * * Jul 2001 Steve Thayer - * + * * Added an on_exit implementation (that now matches gnu libc definition.) * Pulled atexit_handler out of the atexit object since it is now required by * on_exit as well. Renamed it to __exit_handler. @@ -43,16 +43,12 @@ #include #include +#include +__UCLIBC_MUTEX_EXTERN(__atexit_lock); + libc_hidden_proto(exit) libc_hidden_proto(_exit) -#ifdef __UCLIBC_HAS_THREADS__ -# include -extern pthread_mutex_t mylock; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) - typedef void (*aefuncp) (void); /* atexit function pointer */ typedef void (*oefuncp) (int, void *); /* on_exit function pointer */ @@ -137,7 +133,7 @@ weak_alias(old_atexit,atexit) int on_exit(oefuncp func, void *arg) { struct exit_function *efp; - + if (func == NULL) { return 0; } @@ -161,7 +157,7 @@ libc_hidden_proto(__cxa_atexit) int __cxa_atexit (cxaefuncp func, void *arg, void *dso_handle) { struct exit_function *efp; - + if (func == NULL) { return 0; } @@ -243,26 +239,25 @@ struct exit_function attribute_hidden *__new_exitfn(void) { struct exit_function *efp; - LOCK; + __UCLIBC_MUTEX_LOCK(__atexit_lock); #ifdef __UCLIBC_DYNAMIC_ATEXIT__ /* If we are out of function table slots, make some more */ if (__exit_slots < __exit_count+1) { - efp=realloc(__exit_function_table, + efp=realloc(__exit_function_table, (__exit_slots+20)*sizeof(struct exit_function)); if (efp == NULL) { - UNLOCK; __set_errno(ENOMEM); - return 0; + goto DONE; } __exit_function_table = efp; __exit_slots += 20; } #else if (__exit_count >= __UCLIBC_MAX_ATEXIT) { - UNLOCK; __set_errno(ENOMEM); - return 0; + efp = NULL; + goto DONE; } #endif @@ -270,8 +265,8 @@ struct exit_function attribute_hidden *__new_exitfn(void) efp = &__exit_function_table[__exit_count++]; efp->type = ef_in_use; - UNLOCK; - +DONE: + __UCLIBC_MUTEX_UNLOCK(__atexit_lock); return efp; } @@ -302,7 +297,7 @@ void __exit_handler(int status) } } #ifdef __UCLIBC_DYNAMIC_ATEXIT__ - /* Free up memory used by the __exit_function_table structure */ + /* Free up memory used by the __exit_function_table structure */ if (__exit_function_table) free(__exit_function_table); #endif @@ -312,9 +307,7 @@ void __exit_handler(int status) #ifdef L_exit extern void weak_function _stdio_term(void) attribute_hidden; attribute_hidden void (*__exit_cleanup) (int) = 0; -#ifdef __UCLIBC_HAS_THREADS__ -pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif +__UCLIBC_MUTEX_INIT(__atexit_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); extern void __uClibc_fini(void); libc_hidden_proto(__uClibc_fini) @@ -325,11 +318,11 @@ libc_hidden_proto(__uClibc_fini) void exit(int rv) { /* Perform exit-specific cleanup (atexit and on_exit) */ - LOCK; + __UCLIBC_MUTEX_LOCK(__atexit_lock); if (__exit_cleanup) { __exit_cleanup(rv); } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(__atexit_lock); __uClibc_fini(); @@ -337,7 +330,7 @@ void exit(int rv) * this will attempt to commit all buffered writes. It may also * unbuffer all writable files, or close them outright. * Check the stdio routines for details. */ - if (_stdio_term) + if (_stdio_term) _stdio_term(); _exit(rv); diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c index a940768c0..6e1806eae 100644 --- a/libc/stdlib/abort.c +++ b/libc/stdlib/abort.c @@ -49,12 +49,8 @@ extern void weak_function _stdio_term(void) attribute_hidden; static int been_there_done_that = 0; /* Be prepared in case multiple threads try to abort() */ -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); /* Cause an abnormal program termination with core-dump */ void abort(void) @@ -62,7 +58,7 @@ void abort(void) sigset_t sigs; /* Make sure we acquire the lock before proceeding */ - LOCK; + __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock); /* Unmask SIGABRT to be sure we can get it */ if (__sigemptyset(&sigs) == 0 && __sigaddset(&sigs, SIGABRT) == 0) { @@ -85,9 +81,9 @@ void abort(void) #endif abort_it: - UNLOCK; + __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(mylock); raise(SIGABRT); - LOCK; + __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(mylock); } /* Still here? Try to remove any signal handlers */ diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c index e382cee55..0b842076d 100644 --- a/libc/stdlib/malloc-simple/alloc.c +++ b/libc/stdlib/malloc-simple/alloc.c @@ -113,12 +113,11 @@ void free(void *ptr) #endif #ifdef L_memalign -#ifdef __UCLIBC_HAS_THREADS__ -# include -pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif -#define LOCK __pthread_mutex_lock(&__malloc_lock) -#define UNLOCK __pthread_mutex_unlock(&__malloc_lock) + +#include +__UCLIBC_MUTEX_STATIC(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); +#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) +#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) /* List of blocks allocated with memalign or valloc */ struct alignlist @@ -137,7 +136,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 */ @@ -148,7 +147,7 @@ int __libc_free_aligned(void *ptr) return 1; } } - UNLOCK; + __MALLOC_UNLOCK; return 0; } void * memalign (size_t alignment, size_t size) @@ -160,11 +159,10 @@ void * memalign (size_t alignment, size_t size) if (result == NULL) return NULL; - adj = (unsigned long int) ((unsigned long int) ((char *) result - - (char *) NULL)) % alignment; + adj = (unsigned long int) ((unsigned long int) ((char *) result - (char *) NULL)) % alignment; if (adj != 0) { struct alignlist *l; - LOCK; + __MALLOC_LOCK; for (l = _aligned_blocks; l != NULL; l = l->next) if (l->aligned == NULL) /* This slot is free. Use it. */ @@ -173,15 +171,16 @@ void * memalign (size_t alignment, size_t size) l = (struct alignlist *) malloc (sizeof (struct alignlist)); if (l == NULL) { free(result); - UNLOCK; - return NULL; + result = NULL; + goto DONE; } l->next = _aligned_blocks; _aligned_blocks = l; } l->exact = result; result = l->aligned = (char *) result + alignment - adj; - UNLOCK; +DONE: + __MALLOC_UNLOCK; } return result; diff --git a/libc/stdlib/malloc-standard/calloc.c b/libc/stdlib/malloc-standard/calloc.c index 99e8884ad..b94fb372b 100644 --- a/libc/stdlib/malloc-standard/calloc.c +++ b/libc/stdlib/malloc-standard/calloc.c @@ -36,7 +36,7 @@ void* calloc(size_t n_elements, size_t elem_size) return NULL; } - LOCK; + __MALLOC_LOCK; mem = malloc(size); if (mem != 0) { p = mem2chunk(mem); @@ -88,7 +88,7 @@ void* calloc(size_t n_elements, size_t elem_size) } #endif } - UNLOCK; + __MALLOC_UNLOCK; return mem; } diff --git a/libc/stdlib/malloc-standard/free.c b/libc/stdlib/malloc-standard/free.c index e0c6ef061..4d24697be 100644 --- a/libc/stdlib/malloc-standard/free.c +++ b/libc/stdlib/malloc-standard/free.c @@ -282,7 +282,7 @@ void free(void* mem) if (mem == NULL) return; - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); p = mem2chunk(mem); size = chunksize(p); @@ -406,6 +406,6 @@ void free(void* mem) av->mmapped_mem -= (size + offset); munmap((char*)p - offset, size + offset); } - UNLOCK; + __MALLOC_UNLOCK; } diff --git a/libc/stdlib/malloc-standard/mallinfo.c b/libc/stdlib/malloc-standard/mallinfo.c index 4f274ed32..18331010a 100644 --- a/libc/stdlib/malloc-standard/mallinfo.c +++ b/libc/stdlib/malloc-standard/mallinfo.c @@ -32,7 +32,7 @@ struct mallinfo mallinfo(void) int nblocks; int nfastblocks; - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); /* Ensure initialization */ if (av->top == 0) { @@ -77,7 +77,7 @@ struct mallinfo mallinfo(void) mi.fsmblks = fastavail; mi.keepcost = chunksize(av->top); mi.usmblks = av->max_total_mem; - UNLOCK; + __MALLOC_UNLOCK; return mi; } libc_hidden_def(mallinfo) @@ -91,19 +91,36 @@ void malloc_stats(FILE *file) } mi = mallinfo(); - fprintf(file, "total bytes allocated = %10u\n", (unsigned int)(mi.arena + mi.hblkhd)); - fprintf(file, "total bytes in use bytes = %10u\n", (unsigned int)(mi.uordblks + mi.hblkhd)); - fprintf(file, "total non-mmapped bytes allocated = %10d\n", mi.arena); - fprintf(file, "number of mmapped regions = %10d\n", mi.hblks); - fprintf(file, "total allocated mmap space = %10d\n", mi.hblkhd); - fprintf(file, "total allocated sbrk space = %10d\n", mi.uordblks); + fprintf(file, + "total bytes allocated = %10u\n" + "total bytes in use bytes = %10u\n" + "total non-mmapped bytes allocated = %10d\n" + "number of mmapped regions = %10d\n" + "total allocated mmap space = %10d\n" + "total allocated sbrk space = %10d\n" #if 0 - fprintf(file, "number of free chunks = %10d\n", mi.ordblks); - fprintf(file, "number of fastbin blocks = %10d\n", mi.smblks); - fprintf(file, "space in freed fastbin blocks = %10d\n", mi.fsmblks); + "number of free chunks = %10d\n" + "number of fastbin blocks = %10d\n" + "space in freed fastbin blocks = %10d\n" #endif - fprintf(file, "maximum total allocated space = %10d\n", mi.usmblks); - fprintf(file, "total free space = %10d\n", mi.fordblks); - fprintf(file, "memory releasable via malloc_trim = %10d\n", mi.keepcost); + "maximum total allocated space = %10d\n" + "total free space = %10d\n" + "memory releasable via malloc_trim = %10d\n", + + (unsigned int)(mi.arena + mi.hblkhd), + (unsigned int)(mi.uordblks + mi.hblkhd), + mi.arena, + mi.hblks, + mi.hblkhd, + mi.uordblks, +#if 0 + mi.ordblks, + mi.smblks, + mi.fsmblks, +#endif + mi.usmblks, + mi.fordblks, + mi.keepcost + ); } diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c index 7a87ffd36..8c06fdf1f 100644 --- a/libc/stdlib/malloc-standard/malloc.c +++ b/libc/stdlib/malloc-standard/malloc.c @@ -17,9 +17,7 @@ #include "malloc.h" -#ifdef __UCLIBC_HAS_THREADS__ -pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif +__UCLIBC_MUTEX_INIT(__malloc_lock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP); /* There is exactly one instance of this struct in this malloc. @@ -825,12 +823,13 @@ 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 @@ -861,8 +860,8 @@ void* malloc(size_t bytes) if ( (victim = *fb) != 0) { *fb = victim->fd; check_remalloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } @@ -885,8 +884,8 @@ void* malloc(size_t bytes) bck->fd = bin; check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } @@ -902,7 +901,7 @@ void* malloc(size_t bytes) else { idx = __malloc_largebin_index(nb); - if (have_fastchunks(av)) + if (have_fastchunks(av)) __malloc_consolidate(av); } @@ -942,8 +941,8 @@ void* malloc(size_t bytes) set_foot(remainder, remainder_size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* remove from unsorted list */ @@ -955,8 +954,8 @@ void* malloc(size_t bytes) if (size == nb) { set_inuse_bit_at_offset(victim, size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* place chunk in bin */ @@ -1019,8 +1018,8 @@ void* malloc(size_t bytes) if (remainder_size < MINSIZE) { set_inuse_bit_at_offset(victim, size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* Split */ else { @@ -1031,8 +1030,8 @@ void* malloc(size_t bytes) set_head(remainder, remainder_size | PREV_INUSE); set_foot(remainder, remainder_size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } } @@ -1100,8 +1099,8 @@ void* malloc(size_t bytes) if (remainder_size < MINSIZE) { set_inuse_bit_at_offset(victim, size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* Split */ @@ -1118,8 +1117,8 @@ void* malloc(size_t bytes) set_head(remainder, remainder_size | PREV_INUSE); set_foot(remainder, remainder_size); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } } } @@ -1151,13 +1150,15 @@ use_top: set_head(remainder, remainder_size | PREV_INUSE); check_malloced_chunk(victim, nb); - UNLOCK; - return chunk2mem(victim); + retval = chunk2mem(victim); + goto DONE; } /* If no space in top, relay to handle system-dependent cases */ sysmem = __malloc_alloc(nb, av); - UNLOCK; - return sysmem; + retval = sysmem; +DONE: + __MALLOC_UNLOCK; + return retval; } diff --git a/libc/stdlib/malloc-standard/malloc.h b/libc/stdlib/malloc-standard/malloc.h index 556aef4d7..389f1f7d4 100644 --- a/libc/stdlib/malloc-standard/malloc.h +++ b/libc/stdlib/malloc-standard/malloc.h @@ -22,18 +22,17 @@ #include #include #include +#include libc_hidden_proto(mmap) libc_hidden_proto(sysconf) libc_hidden_proto(sbrk) libc_hidden_proto(abort) -#ifdef __UCLIBC_HAS_THREADS__ -# include -extern pthread_mutex_t __malloc_lock; -#endif -#define LOCK __pthread_mutex_lock(&__malloc_lock) -#define UNLOCK __pthread_mutex_unlock(&__malloc_lock) + +__UCLIBC_MUTEX_EXTERN(__malloc_lock); +#define __MALLOC_LOCK __UCLIBC_MUTEX_LOCK(__malloc_lock) +#define __MALLOC_UNLOCK __UCLIBC_MUTEX_UNLOCK(__malloc_lock) diff --git a/libc/stdlib/malloc-standard/mallopt.c b/libc/stdlib/malloc-standard/mallopt.c index e28792099..053242dbe 100644 --- a/libc/stdlib/malloc-standard/mallopt.c +++ b/libc/stdlib/malloc-standard/mallopt.c @@ -25,7 +25,7 @@ int mallopt(int param_number, int value) ret = 0; - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); /* Ensure initialization/consolidation */ __malloc_consolidate(av); @@ -58,7 +58,7 @@ int mallopt(int param_number, int value) ret = 1; break; } - UNLOCK; + __MALLOC_UNLOCK; return ret; } diff --git a/libc/stdlib/malloc-standard/memalign.c b/libc/stdlib/malloc-standard/memalign.c index 27502893d..7e0674be5 100644 --- a/libc/stdlib/malloc-standard/memalign.c +++ b/libc/stdlib/malloc-standard/memalign.c @@ -35,6 +35,7 @@ void* memalign(size_t alignment, size_t bytes) mchunkptr remainder; /* spare room at end to split off */ unsigned long remainder_size; /* its size */ size_t size; + void *retval; /* If need less alignment than we give anyway, just relay to malloc */ @@ -51,7 +52,7 @@ void* memalign(size_t alignment, size_t bytes) alignment = a; } - LOCK; + __MALLOC_LOCK; checked_request2size(bytes, nb); /* Strategy: find a spot within that chunk that meets the alignment @@ -63,8 +64,8 @@ void* memalign(size_t alignment, size_t bytes) m = (char*)(malloc(nb + alignment + MINSIZE)); if (m == 0) { - UNLOCK; - return 0; /* propagate failure */ + retval = 0; /* propagate failure */ + goto DONE; } p = mem2chunk(m); @@ -92,8 +93,8 @@ void* memalign(size_t alignment, size_t bytes) if (chunk_is_mmapped(p)) { newp->prev_size = p->prev_size + leadsize; set_head(newp, newsize|IS_MMAPPED); - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } /* Otherwise, give back leader, use the rest */ @@ -120,7 +121,10 @@ void* memalign(size_t alignment, size_t bytes) } check_inuse_chunk(p); - UNLOCK; - return chunk2mem(p); + retval = chunk2mem(p); + + DONE: + __MALLOC_UNLOCK; + return retval; } diff --git a/libc/stdlib/malloc-standard/realloc.c b/libc/stdlib/malloc-standard/realloc.c index f25d6d989..ef436da0d 100644 --- a/libc/stdlib/malloc-standard/realloc.c +++ b/libc/stdlib/malloc-standard/realloc.c @@ -46,6 +46,7 @@ void* realloc(void* oldmem, size_t bytes) size_t* s; /* copy source */ size_t* d; /* copy destination */ + void *retval; /* Check for special cases. */ if (! oldmem) @@ -55,7 +56,7 @@ void* realloc(void* oldmem, size_t bytes) return NULL; } - LOCK; + __MALLOC_LOCK; av = get_malloc_state(); checked_request2size(bytes, nb); @@ -82,8 +83,8 @@ void* realloc(void* oldmem, size_t bytes) set_head_size(oldp, nb); av->top = chunk_at_offset(oldp, nb); set_head(av->top, (newsize - nb) | PREV_INUSE); - UNLOCK; - return chunk2mem(oldp); + retval = chunk2mem(oldp); + goto DONE; } /* Try to expand forward into next chunk; split off remainder below */ @@ -99,8 +100,8 @@ void* realloc(void* oldmem, size_t bytes) else { newmem = malloc(nb - MALLOC_ALIGN_MASK); if (newmem == 0) { - UNLOCK; - return 0; /* propagate failure */ + retval = 0; /* propagate failure */ + goto DONE; } newp = mem2chunk(newmem); @@ -149,8 +150,8 @@ void* realloc(void* oldmem, size_t bytes) free(oldmem); check_inuse_chunk(newp); - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } } } @@ -175,8 +176,8 @@ void* realloc(void* oldmem, size_t bytes) } check_inuse_chunk(newp); - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } /* @@ -194,8 +195,8 @@ void* realloc(void* oldmem, size_t bytes) /* don't need to remap if still within same page */ if (oldsize == newsize - offset) { - UNLOCK; - return oldmem; + retval = oldmem; + goto DONE; } cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); @@ -216,8 +217,8 @@ void* realloc(void* oldmem, size_t bytes) if (sum > (unsigned long)(av->max_total_mem)) av->max_total_mem = sum; - UNLOCK; - return chunk2mem(newp); + retval = chunk2mem(newp); + goto DONE; } /* Note the extra (sizeof(size_t)) overhead. */ @@ -231,8 +232,11 @@ void* realloc(void* oldmem, size_t bytes) free(oldmem); } } - UNLOCK; - return newmem; + retval = newmem; } + + DONE: + __MALLOC_UNLOCK; + return retval; } diff --git a/libc/stdlib/random.c b/libc/stdlib/random.c index 9f1977ee3..3eb8aed8a 100644 --- a/libc/stdlib/random.c +++ b/libc/stdlib/random.c @@ -32,13 +32,12 @@ libc_hidden_proto(srandom_r) libc_hidden_proto(setstate_r) libc_hidden_proto(initstate_r) -#ifdef __UCLIBC_HAS_THREADS__ -# include /* POSIX.1c requires that there is mutual exclusion for the `rand' and `srand' functions to prevent concurrent calls from modifying common data. */ -static pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; -#endif +#include +__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 @@ -186,9 +185,9 @@ static struct random_data unsafe_state = for default usage relies on values produced by this routine. */ void srandom (unsigned int x) { - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); srandom_r (x, &unsafe_state); - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); } strong_alias(srandom,srand) @@ -207,10 +206,10 @@ char * initstate (unsigned int seed, char *arg_state, size_t n) { int32_t *ostate; - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); ostate = &unsafe_state.state[-1]; initstate_r (seed, arg_state, n, &unsafe_state); - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); return (char *) ostate; } @@ -226,11 +225,11 @@ char * setstate (char *arg_state) { int32_t *ostate; - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); ostate = &unsafe_state.state[-1]; if (setstate_r (arg_state, &unsafe_state) < 0) ostate = NULL; - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); return (char *) ostate; } @@ -250,9 +249,9 @@ long int random (void) { int32_t retval; - __pthread_mutex_lock(&lock); + __UCLIBC_MUTEX_LOCK(mylock); random_r (&unsafe_state, &retval); - __pthread_mutex_unlock(&lock); + __UCLIBC_MUTEX_UNLOCK(mylock); return retval; } libc_hidden_def(random) diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c index fa61675fb..896cf7fc2 100644 --- a/libc/stdlib/setenv.c +++ b/libc/stdlib/setenv.c @@ -14,10 +14,10 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. - + 02111-1307 USA. + modified for uClibc by Erik Andersen - */ +*/ #include #include @@ -32,12 +32,8 @@ libc_hidden_proto(strncmp) libc_hidden_proto(strndup) libc_hidden_proto(unsetenv) -#ifdef __UCLIBC_HAS_THREADS__ -# include -static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; -#endif -#define LOCK __pthread_mutex_lock(&mylock) -#define UNLOCK __pthread_mutex_unlock(&mylock) +#include +__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER); /* If this variable is not a null pointer we allocated the current @@ -51,17 +47,18 @@ static char **last_environ; must be used directly. This is all complicated by the fact that we try to reuse values once generated for a `setenv' call since we can never free the strings. */ -int __add_to_environ (const char *name, const char *value, +int __add_to_environ (const char *name, const char *value, const char *combined, int replace) attribute_hidden; -int __add_to_environ (const char *name, const char *value, - const char *combined, int replace) +int __add_to_environ (const char *name, const char *value, + const char *combined, int replace) { register char **ep; register size_t size; const size_t namelen = strlen (name); const size_t vallen = value != NULL ? strlen (value) + 1 : 0; + int rv = -1; - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); /* We have to get the pointer now that we have the lock and not earlier since another thread might have created a new environment. */ @@ -69,72 +66,71 @@ int __add_to_environ (const char *name, const char *value, size = 0; if (ep != NULL) { - for (; *ep != NULL; ++ep) { - if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') - break; - else - ++size; - } + for (; *ep != NULL; ++ep) { + if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') + break; + else + ++size; + } } if (ep == NULL || *ep == NULL) { - char **new_environ; - - /* We allocated this space; we can extend it. */ - new_environ = (char **) realloc (last_environ, - (size + 2) * sizeof (char *)); - if (new_environ == NULL) { - UNLOCK; - return -1; - } - - /* If the whole entry is given add it. */ - if (combined != NULL) { - /* We must not add the string to the search tree since it belongs - to the user. */ - new_environ[size] = (char *) combined; - } else { - /* See whether the value is already known. */ - new_environ[size] = (char *) malloc (namelen + 1 + vallen); - if (new_environ[size] == NULL) { - __set_errno (ENOMEM); - UNLOCK; - return -1; - } - - memcpy (new_environ[size], name, namelen); - new_environ[size][namelen] = '='; - memcpy (&new_environ[size][namelen + 1], value, vallen); - } - - if (__environ != last_environ) { - memcpy ((char *) new_environ, (char *) __environ, - size * sizeof (char *)); - } - - new_environ[size + 1] = NULL; - last_environ = __environ = new_environ; + char **new_environ; + + /* We allocated this space; we can extend it. */ + new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *)); + if (new_environ == NULL) { + goto DONE; + } + + /* If the whole entry is given add it. */ + if (combined != NULL) { + /* We must not add the string to the search tree since it belongs + to the user. */ + new_environ[size] = (char *) combined; + } else { + /* See whether the value is already known. */ + new_environ[size] = (char *) malloc (namelen + 1 + vallen); + if (new_environ[size] == NULL) { + __set_errno (ENOMEM); + goto DONE; + } + + memcpy (new_environ[size], name, namelen); + new_environ[size][namelen] = '='; + memcpy (&new_environ[size][namelen + 1], value, vallen); + } + + if (__environ != last_environ) { + memcpy ((char *) new_environ, (char *) __environ, + size * sizeof (char *)); + } + + new_environ[size + 1] = NULL; + last_environ = __environ = new_environ; } else if (replace) { - char *np; - - /* Use the user string if given. */ - if (combined != NULL) { - np = (char *) combined; - } else { - np = malloc (namelen + 1 + vallen); - if (np == NULL) { - UNLOCK; - return -1; - } - memcpy (np, name, namelen); - np[namelen] = '='; - memcpy (&np[namelen + 1], value, vallen); - } - *ep = np; + char *np; + + /* Use the user string if given. */ + if (combined != NULL) { + np = (char *) combined; + } else { + np = malloc (namelen + 1 + vallen); + if (np == NULL) { + goto DONE; + } + memcpy (np, name, namelen); + np[namelen] = '='; + memcpy (&np[namelen + 1], value, vallen); + } + *ep = np; } - UNLOCK; - return 0; + rv = 0; + + DONE: + __UCLIBC_MUTEX_UNLOCK(mylock); + return rv; } libc_hidden_proto(setenv) @@ -151,26 +147,26 @@ int unsetenv (const char *name) char **ep; if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) { - __set_errno (EINVAL); - return -1; + __set_errno (EINVAL); + return -1; } len = strlen (name); - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); ep = __environ; while (*ep != NULL) { - if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { - /* Found it. Remove this pointer by moving later ones back. */ - char **dp = ep; - do { - dp[0] = dp[1]; - } while (*dp++); - /* Continue the loop in case NAME appears again. */ - } else { - ++ep; - } + if (!strncmp (*ep, name, len) && (*ep)[len] == '=') { + /* Found it. Remove this pointer by moving later ones back. */ + char **dp = ep; + do { + dp[0] = dp[1]; + } while (*dp++); + /* Continue the loop in case NAME appears again. */ + } else { + ++ep; + } } - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return 0; } libc_hidden_def(unsetenv) @@ -180,15 +176,15 @@ libc_hidden_def(unsetenv) for Fortran 77) requires this function. */ int clearenv (void) { - LOCK; + __UCLIBC_MUTEX_LOCK(mylock); if (__environ == last_environ && __environ != NULL) { - /* We allocated this environment so we can free it. */ - free (__environ); - last_environ = NULL; + /* We allocated this environment so we can free it. */ + free (__environ); + last_environ = NULL; } /* Clear the environment pointer removes the whole environment. */ __environ = NULL; - UNLOCK; + __UCLIBC_MUTEX_UNLOCK(mylock); return 0; } @@ -199,10 +195,10 @@ int putenv (char *string) const char *const name_end = strchr (string, '='); if (name_end != NULL) { - char *name = strndup(string, name_end - string); - result = __add_to_environ (name, NULL, string, 1); - free(name); - return(result); + char *name = strndup(string, name_end - string); + result = __add_to_environ (name, NULL, string, 1); + free(name); + return(result); } unsetenv (string); return 0; diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux/common/bits/uClibc_mutex.h new file mode 100644 index 000000000..5464c2285 --- /dev/null +++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h @@ -0,0 +1,87 @@ +/* Copyright (C) 2006 Manuel Novoa III + * + * 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 + +#ifdef __UCLIBC_HAS_THREADS__ + +#include + +#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 --git a/libc/sysdeps/linux/common/bits/uClibc_stdio.h b/libc/sysdeps/linux/common/bits/uClibc_stdio.h index bd584692e..5865ce564 100644 --- a/libc/sysdeps/linux/common/bits/uClibc_stdio.h +++ b/libc/sysdeps/linux/common/bits/uClibc_stdio.h @@ -1,21 +1,8 @@ /* Copyright (C) 2002-2004 Manuel Novoa III * - * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * The GNU C Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. + * GNU Library General Public License (LGPL) version 2 or later. * - * You should have received a copy of the GNU Lesser General Public - * License along with the GNU C Library; if not, write to the Free - * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA. + * Dedicated to Toni. See uClibc/DEDICATION.mjn3 for details. */ #ifndef _STDIO_H @@ -68,7 +55,7 @@ /**********************************************************************/ /* Make sure defines related to large files are consistent. */ -#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc) +#ifdef _LIBC #ifdef __UCLIBC_HAS_LFS__ #undef __USE_LARGEFILE @@ -129,9 +116,7 @@ #endif /**********************************************************************/ -#ifdef __UCLIBC_HAS_THREADS__ -/* Need this for pthread_mutex_t. */ -#include +#include /* user_locking * 0 : do auto locking/unlocking @@ -145,70 +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) \ - do { \ - struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ - if ((__infunc_user_locking = (__stream)->__user_locking) == 0) { \ - _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ - __pthread_mutex_unlock, \ - &(__stream)->__lock); \ - __pthread_mutex_lock(&(__stream)->__lock); \ - } \ - ((void)0) - -#define __STDIO_AUTO_THREADUNLOCK(__stream) \ - if (__infunc_user_locking == 0) { \ - _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1);\ - } \ - } while (0) +#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_ALWAYS_THREADLOCK(__stream) \ - do { \ - struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ - _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ - __pthread_mutex_unlock, \ - &(__stream)->__lock); \ - __pthread_mutex_lock(&(__stream)->__lock); \ - ((void)0) - -/* #define __STDIO_ALWAYS_THREADTRYLOCK(__stream) \ */ -/* __pthread_mutex_trylock(&(__stream)->__lock) */ +#define __STDIO_AUTO_THREADLOCK(__stream) \ + __UCLIBC_MUTEX_AUTO_LOCK((__stream)->__lock, __infunc_user_locking, \ + (__stream)->__user_locking) -#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ - _pthread_cleanup_pop_restore(&__infunc_pthread_cleanup_buffer,1); \ - } while (0) +#define __STDIO_AUTO_THREADUNLOCK(__stream) \ + __UCLIBC_MUTEX_AUTO_UNLOCK((__stream)->__lock, __infunc_user_locking) -#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) \ - __pthread_mutex_lock(&(__stream)->__lock) +#define __STDIO_ALWAYS_THREADLOCK(__stream) \ + __UCLIBC_MUTEX_LOCK((__stream)->__lock) -#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) \ - __pthread_mutex_trylock(&(__stream)->__lock) +#define __STDIO_ALWAYS_THREADUNLOCK(__stream) \ + __UCLIBC_MUTEX_UNLOCK((__stream)->__lock) -#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream) \ - __pthread_mutex_unlock(&(__stream)->__lock) +#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) \ + __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE((__stream)->__lock) -#else /* __UCLIBC_HAS_THREADS__ */ +#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) \ + __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE((__stream)->__lock) -#define __STDIO_AUTO_THREADLOCK_VAR ((void)0) - -#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) - -#define __STDIO_ALWAYS_THREADLOCK_CANCEL_UNSAFE(__stream) ((void)0) -#define __STDIO_ALWAYS_THREADTRYLOCK_CANCEL_UNSAFE(__stream) (0) /* Ok? */ -#define __STDIO_ALWAYS_THREADUNLOCK_CANCEL_UNSAFE(__stream) ((void)0) - -#endif /* __UCLIBC_HAS_THREADS__ */ /**********************************************************************/ #define __STDIO_IOFBF 0 /* Fully buffered. */ @@ -239,7 +191,7 @@ typedef struct { /**********************************************************************/ #ifdef __UCLIBC_HAS_LFS__ -typedef __off64_t __offmax_t; /* TODO -- rename this? */ +typedef __off64_t __offmax_t; /* TODO -- rename this? */ #else typedef __off_t __offmax_t; /* TODO -- rename this? */ #endif @@ -249,7 +201,7 @@ typedef __off_t __offmax_t; /* TODO -- rename this? */ typedef __ssize_t __io_read_fn(void *__cookie, char *__buf, size_t __bufsize); typedef __ssize_t __io_write_fn(void *__cookie, - __const char *__buf, size_t __bufsize); + __const char *__buf, size_t __bufsize); /* NOTE: GLIBC difference!!! -- fopencookie seek function * For glibc, the type of pos is always (__off64_t *) but in our case * it is type (__off_t *) when the lib is built without large file support. @@ -264,7 +216,7 @@ typedef struct { __io_close_fn *close; } _IO_cookie_io_functions_t; -#ifdef __USE_GNU +#if defined(_LIBC) || defined(_GNU_SOURCE) typedef __io_read_fn cookie_read_function_t; typedef __io_write_fn cookie_write_function_t; @@ -323,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 @@ -352,25 +304,24 @@ struct __STDIO_FILE_STRUCT { #define __MASK_READING 0x0003U /* (0x0001 | 0x0002) */ #define __FLAG_READING 0x0001U -#define __FLAG_UNGOT 0x0002U -#define __FLAG_EOF 0x0004U +#define __FLAG_UNGOT 0x0002U +#define __FLAG_EOF 0x0004U #define __FLAG_ERROR 0x0008U -#define __FLAG_WRITEONLY 0x0010U -#define __FLAG_READONLY 0x0020U /* (__FLAG_WRITEONLY << 1) */ +#define __FLAG_WRITEONLY 0x0010U +#define __FLAG_READONLY 0x0020U /* (__FLAG_WRITEONLY << 1) */ #define __FLAG_WRITING 0x0040U -#define __FLAG_NARROW 0x0080U - -#define __FLAG_FBF 0x0000U /* must be 0 */ -#define __FLAG_LBF 0x0100U -#define __FLAG_NBF 0x0200U /* (__FLAG_LBF << 1) */ -#define __MASK_BUFMODE 0x0300U /* (__FLAG_LBF|__FLAG_NBF) */ -#define __FLAG_APPEND 0x0400U /* fixed! == O_APPEND for linux */ -#define __FLAG_WIDE 0x0800U -/* available slot 0x1000U */ +#define __FLAG_NARROW 0x0080U + +#define __FLAG_FBF 0x0000U /* must be 0 */ +#define __FLAG_LBF 0x0100U +#define __FLAG_NBF 0x0200U /* (__FLAG_LBF << 1) */ +#define __MASK_BUFMODE 0x0300U /* (__FLAG_LBF|__FLAG_NBF) */ +#define __FLAG_APPEND 0x0400U /* fixed! == O_APPEND for linux */ +#define __FLAG_WIDE 0x0800U +/* available slot 0x1000U */ #define __FLAG_FREEFILE 0x2000U #define __FLAG_FREEBUF 0x4000U -#define __FLAG_LARGEFILE 0x8000U /* fixed! == 0_LARGEFILE for linux */ -#define __FLAG_FAILED_FREOPEN __FLAG_LARGEFILE +#define __FLAG_LARGEFILE 0x8000U /* fixed! == 0_LARGEFILE for linux */ /* Note: In no-buffer mode, it would be possible to pack the necessary * flags into one byte. Since we wouldn't be buffering and there would @@ -389,7 +340,7 @@ struct __STDIO_FILE_STRUCT { /********************************************************************** * PROTOTYPES OF INTERNAL FUNCTIONS **********************************************************************/ -#if defined _LIBC && (defined IS_IN_libc || defined NOT_IN_libc) +#ifdef _LIBC extern void _stdio_init(void) attribute_hidden; extern void _stdio_term(void) attribute_hidden; @@ -399,16 +350,14 @@ extern void _stdio_term(void) attribute_hidden; extern struct __STDIO_FILE_STRUCT *_stdio_openlist; #ifdef __UCLIBC_HAS_THREADS__ -extern pthread_mutex_t _stdio_openlist_add_lock; +__UCLIBC_MUTEX_EXTERN(_stdio_openlist_add_lock); #ifdef __STDIO_BUFFERS -extern pthread_mutex_t _stdio_openlist_del_lock; +__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; -/* #ifdef _LIBC */ -extern void __stdio_init_mutex(pthread_mutex_t *m) attribute_hidden; -/* #endif */ +extern void __stdio_init_mutex(__UCLIBC_MUTEX_TYPE *m) attribute_hidden; #endif #endif @@ -416,17 +365,17 @@ extern void __stdio_init_mutex(pthread_mutex_t *m) attribute_hidden; #endif /**********************************************************************/ -#define __CLEARERR_UNLOCKED(__stream) \ +#define __CLEARERR_UNLOCKED(__stream) \ ((void)((__stream)->__modeflags &= ~(__FLAG_EOF|__FLAG_ERROR))) #define __FEOF_UNLOCKED(__stream) ((__stream)->__modeflags & __FLAG_EOF) #define __FERROR_UNLOCKED(__stream) ((__stream)->__modeflags & __FLAG_ERROR) #ifdef __UCLIBC_HAS_THREADS__ -# define __CLEARERR(__stream) (clearerr)(__stream) +# define __CLEARERR(__stream) (clearerr)(__stream) # define __FERROR(__stream) (ferror)(__stream) # define __FEOF(__stream) (feof)(__stream) #else -# define __CLEARERR(__stream) __CLEARERR_UNLOCKED(__stream) +# define __CLEARERR(__stream) __CLEARERR_UNLOCKED(__stream) # define __FERROR(__stream) __FERROR_UNLOCKED(__stream) # define __FEOF(__stream) __FEOF_UNLOCKED(__stream) #endif @@ -434,17 +383,17 @@ extern void __stdio_init_mutex(pthread_mutex_t *m) attribute_hidden; extern int __fgetc_unlocked(FILE *__stream); extern int __fputc_unlocked(int __c, FILE *__stream); -/* First define the default definitions. They will be overwritten below as necessary. */ +/* First define the default definitions. They overriden below as necessary. */ #define __FGETC_UNLOCKED(__stream) (__fgetc_unlocked)((__stream)) -#define __FGETC(__stream) (fgetc)((__stream)) -#define __GETC_UNLOCKED_MACRO(__stream) (__fgetc_unlocked)((__stream)) +#define __FGETC(__stream) (fgetc)((__stream)) +#define __GETC_UNLOCKED_MACRO(__stream) (__fgetc_unlocked)((__stream)) #define __GETC_UNLOCKED(__stream) (__fgetc_unlocked)((__stream)) -#define __GETC(__stream) (fgetc)((__stream)) +#define __GETC(__stream) (fgetc)((__stream)) -#define __FPUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) +#define __FPUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) #define __FPUTC(__c, __stream) (fputc)((__c),(__stream)) -#define __PUTC_UNLOCKED_MACRO(__c, __stream) (__fputc_unlocked)((__c),(__stream)) -#define __PUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) +#define __PUTC_UNLOCKED_MACRO(__c, __stream) (__fputc_unlocked)((__c),(__stream)) +#define __PUTC_UNLOCKED(__c, __stream) (__fputc_unlocked)((__c),(__stream)) #define __PUTC(__c, __stream) (fputc)((__c),(__stream)) @@ -453,9 +402,9 @@ extern int __fputc_unlocked(int __c, FILE *__stream); extern FILE *__stdin; /* For getchar() macro. */ # undef __GETC_UNLOCKED_MACRO -# define __GETC_UNLOCKED_MACRO(__stream) \ +# define __GETC_UNLOCKED_MACRO(__stream) \ ( ((__stream)->__bufpos < (__stream)->__bufgetc_u) \ - ? (*(__stream)->__bufpos++) \ + ? (*(__stream)->__bufpos++) \ : __fgetc_unlocked(__stream) ) # if 0 @@ -470,10 +419,10 @@ extern FILE *__stdin; /* For getchar() macro. */ # else /* Using gcc extension for safety and additional inlining. */ # undef __FGETC_UNLOCKED -# define __FGETC_UNLOCKED(__stream) \ +# define __FGETC_UNLOCKED(__stream) \ (__extension__ ({ \ - FILE *__S = (__stream); \ - __GETC_UNLOCKED_MACRO(__S); \ + FILE *__S = (__stream); \ + __GETC_UNLOCKED_MACRO(__S); \ }) ) # undef __GETC_UNLOCKED @@ -481,23 +430,23 @@ extern FILE *__stdin; /* For getchar() macro. */ # ifdef __UCLIBC_HAS_THREADS__ # undef __FGETC -# define __FGETC(__stream) \ +# define __FGETC(__stream) \ (__extension__ ({ \ - FILE *__S = (__stream); \ - ((__S->__user_locking ) \ - ? __GETC_UNLOCKED_MACRO(__S) \ + FILE *__S = (__stream); \ + ((__S->__user_locking ) \ + ? __GETC_UNLOCKED_MACRO(__S) \ : (fgetc)(__S)); \ }) ) # undef __GETC -# define __GETC(__stream) __FGETC((__stream)) +# define __GETC(__stream) __FGETC((__stream)) -# else +# else # undef __FGETC # define __FGETC(__stream) __FGETC_UNLOCKED((__stream)) # undef __GETC -# define __GETC(__stream) __FGETC_UNLOCKED((__stream)) +# define __GETC(__stream) __FGETC_UNLOCKED((__stream)) # endif # endif @@ -512,16 +461,16 @@ extern FILE *__stdin; /* For getchar() macro. */ extern FILE *__stdout; /* For putchar() macro. */ # undef __PUTC_UNLOCKED_MACRO -# define __PUTC_UNLOCKED_MACRO(__c, __stream) \ +# define __PUTC_UNLOCKED_MACRO(__c, __stream) \ ( ((__stream)->__bufpos < (__stream)->__bufputc_u) \ - ? (*(__stream)->__bufpos++) = (__c) \ + ? (*(__stream)->__bufpos++) = (__c) \ : __fputc_unlocked((__c),(__stream)) ) # if 0 /* Classic macro approach. putc{_unlocked} can have side effects.*/ # undef __PUTC_UNLOCKED -# define __PUTC_UNLOCKED(__c, __stream) \ - __PUTC_UNLOCKED_MACRO((__c), (__stream)) +# define __PUTC_UNLOCKED(__c, __stream) \ + __PUTC_UNLOCKED_MACRO((__c), (__stream)) # ifndef __UCLIBC_HAS_THREADS__ # undef __PUTC # define __PUTC(__c, __stream) __PUTC_UNLOCKED_MACRO((__c), (__stream)) @@ -531,10 +480,10 @@ extern FILE *__stdout; /* For putchar() macro. */ /* Using gcc extension for safety and additional inlining. */ # undef __FPUTC_UNLOCKED -# define __FPUTC_UNLOCKED(__c, __stream) \ - (__extension__ ({ \ +# define __FPUTC_UNLOCKED(__c, __stream) \ + (__extension__ ({ \ FILE *__S = (__stream); \ - __PUTC_UNLOCKED_MACRO((__c),__S); \ + __PUTC_UNLOCKED_MACRO((__c),__S); \ }) ) # undef __PUTC_UNLOCKED @@ -542,11 +491,11 @@ extern FILE *__stdout; /* For putchar() macro. */ # ifdef __UCLIBC_HAS_THREADS__ # undef __FPUTC -# define __FPUTC(__c, __stream) \ - (__extension__ ({ \ +# define __FPUTC(__c, __stream) \ + (__extension__ ({ \ FILE *__S = (__stream); \ ((__S->__user_locking) \ - ? __PUTC_UNLOCKED_MACRO((__c),__S) \ + ? __PUTC_UNLOCKED_MACRO((__c),__S) \ : (fputc)((__c),__S)); \ }) ) @@ -556,9 +505,9 @@ extern FILE *__stdout; /* For putchar() macro. */ # else # undef __FPUTC -# define __FPUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) +# define __FPUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) # undef __PUTC -# define __PUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) +# define __PUTC(__c, __stream) __FPUTC_UNLOCKED((__c),(__stream)) # endif # endif diff --git a/libc/sysdeps/linux/common/sigprocmask.c b/libc/sysdeps/linux/common/sigprocmask.c index cbaea0f62..b90e19f03 100644 --- a/libc/sysdeps/linux/common/sigprocmask.c +++ b/libc/sysdeps/linux/common/sigprocmask.c @@ -26,6 +26,8 @@ int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) 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) @@ -51,6 +53,8 @@ int sigprocmask(int how, const sigset_t * set, sigset_t * oldset) 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) -- cgit v1.2.3