diff options
Diffstat (limited to 'libc')
-rw-r--r-- | libc/SYSCALLS.TXT | 1 | ||||
-rw-r--r-- | libc/arch-arm/syscalls.mk | 1 | ||||
-rw-r--r-- | libc/arch-arm/syscalls/personality.S | 14 | ||||
-rw-r--r-- | libc/arch-sh/syscalls/personality.S | 32 | ||||
-rw-r--r-- | libc/arch-x86/syscalls.mk | 1 | ||||
-rw-r--r-- | libc/arch-x86/syscalls/personality.S | 23 | ||||
-rw-r--r-- | libc/include/sys/linux-syscalls.h | 1 | ||||
-rw-r--r-- | libc/include/sys/linux-unistd.h | 1 | ||||
-rw-r--r-- | libc/include/sys/personality.h | 86 | ||||
-rw-r--r-- | libc/netbsd/resolv/res_send.c | 194 | ||||
-rw-r--r-- | libc/zoneinfo/zoneinfo.dat | bin | 480654 -> 484401 bytes | |||
-rw-r--r-- | libc/zoneinfo/zoneinfo.idx | bin | 29900 -> 29900 bytes | |||
-rw-r--r-- | libc/zoneinfo/zoneinfo.version | 2 |
13 files changed, 329 insertions, 27 deletions
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 21961c89c..2da38b70b 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -262,6 +262,7 @@ int init_module(void *, unsigned long, const char *) 128 int delete_module(const char*, unsigned int) 129 int klogctl:syslog(int, char *, int) 103 int sysinfo(struct sysinfo *) 116 +int personality(unsigned long) 136 # futex int futex(void *, int, int, void *, void *, int) 240 diff --git a/libc/arch-arm/syscalls.mk b/libc/arch-arm/syscalls.mk index 3fce36d08..b19fb68e8 100644 --- a/libc/arch-arm/syscalls.mk +++ b/libc/arch-arm/syscalls.mk @@ -182,6 +182,7 @@ syscall_src += arch-arm/syscalls/init_module.S syscall_src += arch-arm/syscalls/delete_module.S syscall_src += arch-arm/syscalls/klogctl.S syscall_src += arch-arm/syscalls/sysinfo.S +syscall_src += arch-arm/syscalls/personality.S syscall_src += arch-arm/syscalls/futex.S syscall_src += arch-arm/syscalls/epoll_create.S syscall_src += arch-arm/syscalls/epoll_ctl.S diff --git a/libc/arch-arm/syscalls/personality.S b/libc/arch-arm/syscalls/personality.S new file mode 100644 index 000000000..17ac68661 --- /dev/null +++ b/libc/arch-arm/syscalls/personality.S @@ -0,0 +1,14 @@ +/* autogenerated by gensyscalls.py */ +#include <machine/asm.h> +#include <sys/linux-syscalls.h> + +ENTRY(personality) + .save {r4, r7} + stmfd sp!, {r4, r7} + ldr r7, =__NR_personality + swi #0 + ldmfd sp!, {r4, r7} + movs r0, r0 + bxpl lr + b __set_syscall_errno +END(personality) diff --git a/libc/arch-sh/syscalls/personality.S b/libc/arch-sh/syscalls/personality.S new file mode 100644 index 000000000..efc2ea380 --- /dev/null +++ b/libc/arch-sh/syscalls/personality.S @@ -0,0 +1,32 @@ +/* autogenerated by gensyscalls.py */ +#include <sys/linux-syscalls.h> + + .text + .type personality, @function + .globl personality + .align 4 + +personality: + + /* invoke trap */ + mov.l 0f, r3 /* trap num */ + trapa #(1 + 0x10) + + /* check return value */ + cmp/pz r0 + bt __NR_personality_end + + /* keep error number */ + sts.l pr, @-r15 + mov.l 1f, r1 + jsr @r1 + mov r0, r4 + lds.l @r15+, pr + +__NR_personality_end: + rts + nop + + .align 2 +0: .long __NR_personality +1: .long __set_syscall_errno diff --git a/libc/arch-x86/syscalls.mk b/libc/arch-x86/syscalls.mk index 2f8cc4964..7d3d937c8 100644 --- a/libc/arch-x86/syscalls.mk +++ b/libc/arch-x86/syscalls.mk @@ -185,6 +185,7 @@ syscall_src += arch-x86/syscalls/init_module.S syscall_src += arch-x86/syscalls/delete_module.S syscall_src += arch-x86/syscalls/klogctl.S syscall_src += arch-x86/syscalls/sysinfo.S +syscall_src += arch-x86/syscalls/personality.S syscall_src += arch-x86/syscalls/futex.S syscall_src += arch-x86/syscalls/epoll_create.S syscall_src += arch-x86/syscalls/epoll_ctl.S diff --git a/libc/arch-x86/syscalls/personality.S b/libc/arch-x86/syscalls/personality.S new file mode 100644 index 000000000..af4f9120f --- /dev/null +++ b/libc/arch-x86/syscalls/personality.S @@ -0,0 +1,23 @@ +/* autogenerated by gensyscalls.py */ +#include <sys/linux-syscalls.h> + + .text + .type personality, @function + .globl personality + .align 4 + +personality: + pushl %ebx + mov 8(%esp), %ebx + movl $__NR_personality, %eax + int $0x80 + cmpl $-129, %eax + jb 1f + negl %eax + pushl %eax + call __set_errno + addl $4, %esp + orl $-1, %eax +1: + popl %ebx + ret diff --git a/libc/include/sys/linux-syscalls.h b/libc/include/sys/linux-syscalls.h index 49fdf99bc..0cb310064 100644 --- a/libc/include/sys/linux-syscalls.h +++ b/libc/include/sys/linux-syscalls.h @@ -145,6 +145,7 @@ #define __NR_delete_module (__NR_SYSCALL_BASE + 129) #define __NR_syslog (__NR_SYSCALL_BASE + 103) #define __NR_sysinfo (__NR_SYSCALL_BASE + 116) +#define __NR_personality (__NR_SYSCALL_BASE + 136) #define __NR_futex (__NR_SYSCALL_BASE + 240) #define __NR_poll (__NR_SYSCALL_BASE + 168) diff --git a/libc/include/sys/linux-unistd.h b/libc/include/sys/linux-unistd.h index f4660e2b3..d945d87b4 100644 --- a/libc/include/sys/linux-unistd.h +++ b/libc/include/sys/linux-unistd.h @@ -211,6 +211,7 @@ int init_module (void *, unsigned long, const char *); int delete_module (const char*, unsigned int); int klogctl (int, char *, int); int sysinfo (struct sysinfo *); +int personality (unsigned long); int futex (void *, int, int, void *, void *, int); int epoll_create (int size); int epoll_ctl (int epfd, int op, int fd, struct epoll_event *event); diff --git a/libc/include/sys/personality.h b/libc/include/sys/personality.h new file mode 100644 index 000000000..2199fa74a --- /dev/null +++ b/libc/include/sys/personality.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_PERSONALITY_H_ +#define _SYS_PERSONALITY_H_ + +__BEGIN_DECLS + +/* constants taken from linux-3.0.4/include/linux/personality.h */ + +enum { + UNAME26 = 0x0020000, + ADDR_NO_RANDOMIZE = 0x0040000, + FDPIC_FUNCPTRS = 0x0080000, + MMAP_PAGE_ZERO = 0x0100000, + ADDR_COMPAT_LAYOUT = 0x0200000, + READ_IMPLIES_EXEC = 0x0400000, + ADDR_LIMIT_32BIT = 0x0800000, + SHORT_INODE = 0x1000000, + WHOLE_SECONDS = 0x2000000, + STICKY_TIMEOUTS = 0x4000000, + ADDR_LIMIT_3GB = 0x8000000, +}; + +#define PER_CLEAR_ON_SETID (READ_IMPLIES_EXEC | \ + ADDR_NO_RANDOMIZE | \ + ADDR_COMPAT_LAYOUT | \ + MMAP_PAGE_ZERO) + +enum { + PER_LINUX = 0x0000, + PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT, + PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS, + PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, + PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE, + PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | + WHOLE_SECONDS | SHORT_INODE, + PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS, + PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE, + PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS, + PER_BSD = 0x0006, + PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, + PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, + PER_LINUX32 = 0x0008, + PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, + PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS, + PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS, + PER_IRIX64 = 0x000b | STICKY_TIMEOUTS, + PER_RISCOS = 0x000c, + PER_SOLARIS = 0x000d | STICKY_TIMEOUTS, + PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, + PER_OSF4 = 0x000f, + PER_HPUX = 0x0010, + PER_MASK = 0x00ff, +}; + +extern int personality (unsigned long persona); + +__END_DECLS + +#endif /* _SYS_PERSONALITY_H_ */ diff --git a/libc/netbsd/resolv/res_send.c b/libc/netbsd/resolv/res_send.c index 1a28d9e7b..dbad6dda0 100644 --- a/libc/netbsd/resolv/res_send.c +++ b/libc/netbsd/resolv/res_send.c @@ -99,6 +99,7 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $"); #include <arpa/inet.h> #include <errno.h> +#include <fcntl.h> #include <netdb.h> #ifdef ANDROID_CHANGES #include "resolv_private.h" @@ -109,6 +110,7 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $"); #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <time.h> #include <unistd.h> #include <isc/eventlib.h> @@ -117,6 +119,8 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $"); # include <resolv_cache.h> #endif +#include "logd.h" + #ifndef DE_CONST #define DE_CONST(c,v) v = ((c) ? \ strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL) @@ -130,6 +134,7 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $"); #include "res_private.h" #define EXT(res) ((res)->_u._ext) +#define DBG 0 static const int highestFD = FD_SETSIZE - 1; @@ -152,7 +157,10 @@ static int pselect(int, void *, void *, void *, const sigset_t *); #endif void res_pquery(const res_state, const u_char *, int, FILE *); - +static int connect_with_timeout(int sock, const struct sockaddr *nsap, + socklen_t salen, int sec); +static int retrying_select(const int sock, fd_set *readset, fd_set *writeset, + const struct timespec *finish); /* BIONIC-BEGIN: implement source port randomization */ typedef union { @@ -521,16 +529,23 @@ res_nsend(res_state statp, Dprint(((statp->options & RES_DEBUG) && getnameinfo(nsap, (socklen_t)nsaplen, abuf, sizeof(abuf), - NULL, 0, niflags) == 0), - (stdout, ";; Querying server (# %d) address = %s\n", - ns + 1, abuf)); + NULL, 0, niflags) == 0), + (stdout, ";; Querying server (# %d) address = %s\n", + ns + 1, abuf)); if (v_circuit) { /* Use VC; at most one attempt per server. */ try = statp->retry; + n = send_vc(statp, buf, buflen, ans, anssiz, &terrno, ns); + + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + "used send_vc %d\n", n); + } + if (n < 0) goto fail; if (n == 0) @@ -538,12 +553,26 @@ res_nsend(res_state statp, resplen = n; } else { /* Use datagrams. */ + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + "using send_dg\n"); + } + n = send_dg(statp, buf, buflen, ans, anssiz, &terrno, ns, &v_circuit, &gotsomewhere); + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + "used send_dg %d\n",n); + } + if (n < 0) goto fail; if (n == 0) goto next_ns; + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + "time=%d, %d\n",time(NULL), time(NULL)%2); + } if (v_circuit) goto same_ns; resplen = n; @@ -668,6 +697,23 @@ get_nsaddr(statp, n) } } +static int get_timeout(const res_state statp, const int ns) +{ + int timeout = (statp->retrans << ns); + if (ns > 0) { + timeout /= statp->nscount; + } + if (timeout <= 0) { + timeout = 1; + } + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + "using timeout of %d sec\n", timeout); + } + + return timeout; +} + static int send_vc(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz, @@ -683,6 +729,10 @@ send_vc(res_state statp, u_char *cp; void *tmp; + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", "using send_vc\n"); + } + nsap = get_nsaddr(statp, (size_t)ns); nsaplen = get_salen(nsap); @@ -735,7 +785,8 @@ send_vc(res_state statp, res_nclose(statp); return (0); } - if (connect(statp->_vcsock, nsap, (socklen_t)nsaplen) < 0) { + if (connect_with_timeout(statp->_vcsock, nsap, (socklen_t)nsaplen, + get_timeout(statp, ns)) < 0) { *terrno = errno; Aerror(statp, stderr, "connect/vc", errno, nsap, nsaplen); @@ -859,6 +910,111 @@ send_vc(res_state statp, return (resplen); } +/* return -1 on error (errno set), 0 on success */ +static int +connect_with_timeout(int sock, const struct sockaddr *nsap, socklen_t salen, int sec) +{ + int res, origflags; + fd_set rset, wset; + struct timespec now, timeout, finish; + + origflags = fcntl(sock, F_GETFL, 0); + fcntl(sock, F_SETFL, origflags | O_NONBLOCK); + + res = connect(sock, nsap, salen); + if (res < 0 && errno != EINPROGRESS) { + res = -1; + goto done; + } + if (res != 0) { + now = evNowTime(); + timeout = evConsTime((long)sec, 0L); + finish = evAddTime(now, timeout); + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + " %d send_vc\n", sock); + } + + res = retrying_select(sock, &rset, &wset, &finish); + if (res <= 0) { + res = -1; + } + } +done: + fcntl(sock, F_SETFL, origflags); + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + " %d connect_with_timeout returning %s\n", sock, res); + } + return res; +} + +static int +retrying_select(const int sock, fd_set *readset, fd_set *writeset, const struct timespec *finish) +{ + struct timespec now, timeout; + int n, error; + socklen_t len; + + +retry: + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", " %d retying_select\n", sock); + } + + now = evNowTime(); + if (readset) { + FD_ZERO(readset); + FD_SET(sock, readset); + } + if (writeset) { + FD_ZERO(writeset); + FD_SET(sock, writeset); + } + if (evCmpTime(*finish, now) > 0) + timeout = evSubTime(*finish, now); + else + timeout = evConsTime(0L, 0L); + + n = pselect(sock + 1, readset, writeset, NULL, &timeout, NULL); + if (n == 0) { + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, " libc", + " %d retrying_select timeout\n", sock); + } + errno = ETIMEDOUT; + return 0; + } + if (n < 0) { + if (errno == EINTR) + goto retry; + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + " %d retrying_select got error %d\n",sock, n); + } + return n; + } + if ((readset && FD_ISSET(sock, readset)) || (writeset && FD_ISSET(sock, writeset))) { + len = sizeof(error); + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &error, &len) < 0 || error) { + errno = error; + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + " %d retrying_select dot error2 %d\n", sock, errno); + } + + return -1; + } + } + if (DBG) { + __libc_android_log_print(ANDROID_LOG_DEBUG, "libc", + " %d retrying_select returning %d for %d\n",sock, n); + } + + return n; +} + + static int send_dg(res_state statp, const u_char *buf, int buflen, u_char *ans, int anssiz, @@ -944,33 +1100,19 @@ send_dg(res_state statp, /* * Wait for reply. */ - seconds = (statp->retrans << ns); - if (ns > 0) - seconds /= statp->nscount; - if (seconds <= 0) - seconds = 1; + seconds = get_timeout(statp, ns); now = evNowTime(); timeout = evConsTime((long)seconds, 0L); finish = evAddTime(now, timeout); - goto nonow; - wait: - now = evNowTime(); - nonow: - FD_ZERO(&dsmask); - FD_SET(s, &dsmask); - if (evCmpTime(finish, now) > 0) - timeout = evSubTime(finish, now); - else - timeout = evConsTime(0L, 0L); - n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL); +retry: + n = retrying_select(s, &dsmask, NULL, &finish); + if (n == 0) { Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n")); *gotsomewhere = 1; return (0); } if (n < 0) { - if (errno == EINTR) - goto wait; Perror(statp, stderr, "select", errno); res_nclose(statp); return (0); @@ -1006,7 +1148,7 @@ send_dg(res_state statp, (statp->pfcode & RES_PRF_REPLY), (stdout, ";; old answer:\n"), ans, (resplen > anssiz) ? anssiz : resplen); - goto wait; + goto retry; } if (!(statp->options & RES_INSECURE1) && !res_ourserver_p(statp, (struct sockaddr *)(void *)&from)) { @@ -1019,7 +1161,7 @@ send_dg(res_state statp, (statp->pfcode & RES_PRF_REPLY), (stdout, ";; not our server:\n"), ans, (resplen > anssiz) ? anssiz : resplen); - goto wait; + goto retry; } #ifdef RES_USE_EDNS0 if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0U) { @@ -1049,7 +1191,7 @@ send_dg(res_state statp, (statp->pfcode & RES_PRF_REPLY), (stdout, ";; wrong query name:\n"), ans, (resplen > anssiz) ? anssiz : resplen); - goto wait; + goto retry;; } if (anhp->rcode == SERVFAIL || anhp->rcode == NOTIMP || diff --git a/libc/zoneinfo/zoneinfo.dat b/libc/zoneinfo/zoneinfo.dat Binary files differindex e41422e50..49b99ecd3 100644 --- a/libc/zoneinfo/zoneinfo.dat +++ b/libc/zoneinfo/zoneinfo.dat diff --git a/libc/zoneinfo/zoneinfo.idx b/libc/zoneinfo/zoneinfo.idx Binary files differindex eb02e80ad..c9eefc64f 100644 --- a/libc/zoneinfo/zoneinfo.idx +++ b/libc/zoneinfo/zoneinfo.idx diff --git a/libc/zoneinfo/zoneinfo.version b/libc/zoneinfo/zoneinfo.version index 6140b761a..c4f49224b 100644 --- a/libc/zoneinfo/zoneinfo.version +++ b/libc/zoneinfo/zoneinfo.version @@ -1 +1 @@ -2011l +2011n |