Merge "Use __unused instead of UNUSED in linker.cpp"
diff --git a/libc/Android.mk b/libc/Android.mk
index 8cb85b7..3faa47f 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -771,6 +771,10 @@
LOCAL_ADDITIONAL_DEPENDENCIES := $(libc_common_additional_dependencies)
LOCAL_REQUIRED_MODULES := tzdata
+# Leave the symbols in the shared library so that stack unwinders can produce
+# meaningful name resolution.
+LOCAL_STRIP_MODULE := keep_symbols
+
# WARNING: The only library libc.so should depend on is libdl.so! If you add other libraries,
# make sure to add -Wl,--exclude-libs=libgcc.a to the LOCAL_LDFLAGS for those libraries. This
# ensures that symbols that are pulled into those new libraries from libgcc.a are not declared
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 8d4b258..e597b2f 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -238,6 +238,7 @@
int connect(int, struct sockaddr*, socklen_t) arm,arm64,mips,mips64,x86_64
int listen(int, int) arm,arm64,mips,mips64,x86_64
int accept(int, struct sockaddr*, socklen_t*) arm,arm64,mips,mips64,x86_64
+int accept4(int, struct sockaddr*, socklen_t*, int) arm,arm64,mips,mips64,x86_64
int getsockname(int, struct sockaddr*, socklen_t*) arm,arm64,mips,mips64,x86_64
int getpeername(int, struct sockaddr*, socklen_t*) arm,arm64,mips,mips64,x86_64
int sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t) arm,arm64,mips,mips64,x86_64
@@ -266,6 +267,7 @@
int getsockopt:socketcall:15(int, int, int, void*, socklen_t*) x86
int sendmsg:socketcall:16(int, const struct msghdr*, unsigned int) x86
int recvmsg:socketcall:17(int, struct msghdr*, unsigned int) x86
+int accept4:socketcall:18(int, struct sockaddr*, socklen_t*, int) x86
int recvmmsg:socketcall:19(int, struct mmsghdr*, unsigned int, int, const struct timespec*) x86
int sendmmsg:socketcall:20(int, struct mmsghdr*, unsigned int, int) x86
diff --git a/libc/arch-arm/syscalls/accept4.S b/libc/arch-arm/syscalls/accept4.S
new file mode 100644
index 0000000..6d14e79
--- /dev/null
+++ b/libc/arch-arm/syscalls/accept4.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+ mov ip, r7
+ ldr r7, =__NR_accept4
+ swi #0
+ mov r7, ip
+ cmn r0, #(MAX_ERRNO + 1)
+ bxls lr
+ neg r0, r0
+ b __set_errno
+END(accept4)
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 88da1f3..7b6b1c3 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -14,6 +14,11 @@
upstream-freebsd/lib/libc/string/wcslen.c \
upstream-freebsd/lib/libc/string/wcsrchr.c \
upstream-freebsd/lib/libc/string/wmemcmp.c \
+ upstream-openbsd/lib/libc/locale/_def_numeric.c \
+ upstream-openbsd/lib/libc/locale/_def_messages.c \
+ upstream-openbsd/lib/libc/locale/_def_monetary.c \
+ upstream-openbsd/lib/libc/locale/_def_time.c \
+ upstream-openbsd/lib/libc/locale/localeconv.c \
upstream-openbsd/lib/libc/string/bcopy.c \
upstream-openbsd/lib/libc/string/strcat.c \
upstream-openbsd/lib/libc/string/strcpy.c \
diff --git a/libc/arch-arm64/syscalls/accept4.S b/libc/arch-arm64/syscalls/accept4.S
new file mode 100644
index 0000000..3c9227f
--- /dev/null
+++ b/libc/arch-arm64/syscalls/accept4.S
@@ -0,0 +1,21 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ str x8, [sp, #-16]!
+
+ mov x8, __NR_accept4
+ svc #0
+
+ ldr x8, [sp], #16
+ ldp x29, x30, [sp], #16
+
+ cmn x0, #(MAX_ERRNO + 1)
+ cneg x0, x0, hi
+ b.hi __set_errno
+
+ ret
+END(accept4)
diff --git a/libc/arch-mips/syscalls/accept4.S b/libc/arch-mips/syscalls/accept4.S
new file mode 100644
index 0000000..ea1dc60
--- /dev/null
+++ b/libc/arch-mips/syscalls/accept4.S
@@ -0,0 +1,19 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+ .set noreorder
+ .cpload t9
+ li v0, __NR_accept4
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ la t9,__set_errno
+ j t9
+ nop
+ .set reorder
+END(accept4)
diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk
index 28806e1..9b29f0d 100644
--- a/libc/arch-mips64/mips64.mk
+++ b/libc/arch-mips64/mips64.mk
@@ -16,6 +16,11 @@
upstream-freebsd/lib/libc/string/wcslen.c \
upstream-freebsd/lib/libc/string/wcsrchr.c \
upstream-freebsd/lib/libc/string/wmemcmp.c \
+ upstream-openbsd/lib/libc/locale/_def_numeric.c \
+ upstream-openbsd/lib/libc/locale/_def_messages.c \
+ upstream-openbsd/lib/libc/locale/_def_monetary.c \
+ upstream-openbsd/lib/libc/locale/_def_time.c \
+ upstream-openbsd/lib/libc/locale/localeconv.c \
upstream-openbsd/lib/libc/string/bcopy.c \
upstream-openbsd/lib/libc/string/strcat.c \
upstream-openbsd/lib/libc/string/strcmp.c \
diff --git a/libc/arch-mips64/syscalls/accept4.S b/libc/arch-mips64/syscalls/accept4.S
new file mode 100644
index 0000000..8b5cadb
--- /dev/null
+++ b/libc/arch-mips64/syscalls/accept4.S
@@ -0,0 +1,25 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+ .set push
+ .set noreorder
+ li v0, __NR_accept4
+ syscall
+ bnez a3, 1f
+ move a0, v0
+ j ra
+ nop
+1:
+ move t0, ra
+ bal 2f
+ nop
+2:
+ .cpsetup ra, t1, 2b
+ LA t9,__set_errno
+ .cpreturn
+ j t9
+ move ra, t0
+ .set pop
+END(accept4)
diff --git a/libc/arch-x86/syscalls/accept4.S b/libc/arch-x86/syscalls/accept4.S
new file mode 100644
index 0000000..dc3c1f5
--- /dev/null
+++ b/libc/arch-x86/syscalls/accept4.S
@@ -0,0 +1,27 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+ pushl %ebx
+ pushl %ecx
+ .cfi_def_cfa_offset 8
+ .cfi_rel_offset ebx, 0
+ .cfi_rel_offset ecx, 4
+ mov $18, %ebx
+ mov %esp, %ecx
+ addl $12, %ecx
+ movl $__NR_socketcall, %eax
+ int $0x80
+ cmpl $-MAX_ERRNO, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+ addl $4, %esp
+ orl $-1, %eax
+1:
+ popl %ecx
+ popl %ebx
+ ret
+END(accept4)
diff --git a/libc/arch-x86_64/syscalls/accept4.S b/libc/arch-x86_64/syscalls/accept4.S
new file mode 100644
index 0000000..d66d952
--- /dev/null
+++ b/libc/arch-x86_64/syscalls/accept4.S
@@ -0,0 +1,17 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(accept4)
+ movq %rcx, %r10
+ movl $__NR_accept4, %eax
+ syscall
+ cmpq $-MAX_ERRNO, %rax
+ jb 1f
+ negl %eax
+ movl %eax, %edi
+ call __set_errno
+ orq $-1, %rax
+1:
+ ret
+END(accept4)
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
index 9bce065..a3adaa4 100644
--- a/libc/arch-x86_64/x86_64.mk
+++ b/libc/arch-x86_64/x86_64.mk
@@ -18,6 +18,11 @@
upstream-freebsd/lib/libc/string/wcslen.c \
upstream-freebsd/lib/libc/string/wcsrchr.c \
upstream-freebsd/lib/libc/string/wmemcmp.c \
+ upstream-openbsd/lib/libc/locale/_def_numeric.c \
+ upstream-openbsd/lib/libc/locale/_def_messages.c \
+ upstream-openbsd/lib/libc/locale/_def_monetary.c \
+ upstream-openbsd/lib/libc/locale/_def_time.c \
+ upstream-openbsd/lib/libc/locale/localeconv.c \
upstream-openbsd/lib/libc/string/bcopy.c \
upstream-openbsd/lib/libc/string/strcat.c \
upstream-openbsd/lib/libc/string/strcmp.c \
diff --git a/libc/bionic/strtotimeval.c b/libc/bionic/strtotimeval.c
index 1c132ec..195381b 100644
--- a/libc/bionic/strtotimeval.c
+++ b/libc/bionic/strtotimeval.c
@@ -30,34 +30,29 @@
#include <stdlib.h>
#include <sys/time.h>
-char * strtotimeval (const char *str, struct timeval *ts)
-{
- int n;
- char *s, *s0;
- long fs; /* Fractional seconds */
+char * strtotimeval(const char *str, struct timeval *ts) {
+ char *s;
+ long fs = 0; /* fractional seconds */
- ts->tv_sec = strtoumax(str, &s, 10);
- fs = 0;
+ ts->tv_sec = strtoumax(str, &s, 10);
- if ( *s == '.' ) {
- int count;
+ if (*s == '.') {
+ s++;
+ int count = 0;
- s0 = s+1;
-
- /* read up to 6 digits */
- fs = 0;
- count = 0;
- while ( *s && isdigit(*s) )
- {
- if ( ++count < 7 )
- fs = fs*10 + (*s - '0');
- s++;
- }
-
- for ( ; count < 6; count++ )
- fs *= 10;
+ /* read up to 6 digits (microseconds) */
+ while (*s && isdigit(*s)) {
+ if (++count < 7) {
+ fs = fs*10 + (*s - '0');
+ }
+ s++;
}
- ts->tv_usec = fs;
- return s;
+ for (; count < 6; count++) {
+ fs *= 10;
+ }
+ }
+
+ ts->tv_usec = fs;
+ return s;
}
diff --git a/libc/include/locale.h b/libc/include/locale.h
index b6dbfdb..4efc564 100644
--- a/libc/include/locale.h
+++ b/libc/include/locale.h
@@ -51,12 +51,41 @@
extern char* setlocale(int, const char*);
-#if !defined(__LP64__)
-// TODO: LP32 had these bogus declarations but LP64 should have a real struct lconv and localeconv(3).
+#if defined(__LP64__)
+struct lconv {
+ char* decimal_point;
+ char* thousands_sep;
+ char* grouping;
+ char* int_curr_symbol;
+ char* currency_symbol;
+ char* mon_decimal_point;
+ char* mon_thousands_sep;
+ char* mon_grouping;
+ char* positive_sign;
+ char* negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+ /* ISO-C99 */
+ char int_p_cs_precedes;
+ char int_p_sep_by_space;
+ char int_n_cs_precedes;
+ char int_n_sep_by_space;
+ char int_p_sign_posn;
+ char int_n_sign_posn;
+};
+#else
+// Keep old declaration for ILP32 for compatibility
struct lconv { };
-struct lconv* localeconv(void);
#endif
+struct lconv* localeconv(void);
+
__END_DECLS
#endif /* _LOCALE_H_ */
diff --git a/libc/include/sys/localedef.h b/libc/include/sys/localedef.h
new file mode 100644
index 0000000..b6b5eb1
--- /dev/null
+++ b/libc/include/sys/localedef.h
@@ -0,0 +1,101 @@
+/* $OpenBSD: localedef.h,v 1.3 1996/04/21 22:31:47 deraadt Exp $ */
+/* $NetBSD: localedef.h,v 1.4 1996/04/09 20:55:31 cgd Exp $ */
+
+/*
+ * Copyright (c) 1994 Winning Strategies, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Winning Strategies, Inc.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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_LOCALEDEF_H_
+#define _SYS_LOCALEDEF_H_
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+typedef struct
+{
+ char *yesexpr;
+ char *noexpr;
+ char *yesstr;
+ char *nostr;
+} _MessagesLocale;
+
+extern const _MessagesLocale *_CurrentMessagesLocale;
+extern const _MessagesLocale _DefaultMessagesLocale;
+
+
+typedef struct
+{
+ char *int_curr_symbol;
+ char *currency_symbol;
+ char *mon_decimal_point;
+ char *mon_thousands_sep;
+ char *mon_grouping;
+ char *positive_sign;
+ char *negative_sign;
+ char int_frac_digits;
+ char frac_digits;
+ char p_cs_precedes;
+ char p_sep_by_space;
+ char n_cs_precedes;
+ char n_sep_by_space;
+ char p_sign_posn;
+ char n_sign_posn;
+} _MonetaryLocale;
+
+extern const _MonetaryLocale *_CurrentMonetaryLocale;
+extern const _MonetaryLocale _DefaultMonetaryLocale;
+
+
+typedef struct
+{
+ const char *decimal_point;
+ const char *thousands_sep;
+ const char *grouping;
+} _NumericLocale;
+
+extern const _NumericLocale *_CurrentNumericLocale;
+extern const _NumericLocale _DefaultNumericLocale;
+
+
+typedef struct {
+ const char *abday[7];
+ const char *day[7];
+ const char *abmon[12];
+ const char *mon[12];
+ const char *am_pm[2];
+ const char *d_t_fmt;
+ const char *d_fmt;
+ const char *t_fmt;
+ const char *t_fmt_ampm;
+} _TimeLocale;
+
+extern const _TimeLocale *_CurrentTimeLocale;
+extern const _TimeLocale _DefaultTimeLocale;
+
+#endif /* !_SYS_LOCALEDEF_H_ */
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 62a5300..5001b2e 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -107,14 +107,14 @@
int cmsg_type;
};
-#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg))
-#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
+#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr((mhdr)->msg_control, (mhdr)->msg_controllen, (cmsg))
#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
#define CMSG_DATA(cmsg) ((void*)((char*)(cmsg) + CMSG_ALIGN(sizeof(struct cmsghdr))))
#define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + CMSG_ALIGN(len))
#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len))
-#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? (struct cmsghdr*)(ctl) : (struct cmsghdr*)NULL)
-#define CMSG_FIRSTHDR(msg) __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG_FIRSTHDR(msg) \
+ ((msg)->msg_controllen >= sizeof(struct cmsghdr) \
+ ? (struct cmsghdr*) (msg)->msg_control : (struct cmsghdr*) NULL)
#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && (cmsg)->cmsg_len <= (unsigned long) ((mhdr)->msg_controllen - ((char*)(cmsg) - (char*)(mhdr)->msg_control)))
#ifdef __GNUC__
@@ -134,10 +134,6 @@
return __ptr;
}
-__KINLINE struct cmsghdr* cmsg_nxthdr (struct msghdr* __msg, struct cmsghdr* __cmsg) {
- return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
-}
-
#define SCM_RIGHTS 0x01
#define SCM_CREDENTIALS 0x02
#define SCM_SECURITY 0x03
@@ -302,6 +298,7 @@
__socketcall int shutdown(int, int);
__socketcall int socket(int, int, int);
__socketcall int socketpair(int, int, int, int*);
+__socketcall int accept4(int, struct sockaddr*, socklen_t*, int);
extern ssize_t send(int, const void*, size_t, int);
extern ssize_t recv(int, void*, size_t, int);
diff --git a/libc/include/sys/socketcalls.h b/libc/include/sys/socketcalls.h
index c74f463..09c079f 100644
--- a/libc/include/sys/socketcalls.h
+++ b/libc/include/sys/socketcalls.h
@@ -47,5 +47,6 @@
#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */
#define SYS_SENDMSG 16 /* sys_sendmsg(2) */
#define SYS_RECVMSG 17 /* sys_recvmsg(2) */
+#define SYS_ACCEPT4 18 /* sys_accept4(2) */
#endif /* _SYS_SOCKETCALLS_H_ */
diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c
index 0a19446..b39c90e 100644
--- a/libc/stdlib/strtod.c
+++ b/libc/stdlib/strtod.c
@@ -1332,13 +1332,14 @@
Bigint *bb1, *bd0;
Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
- CONST char decimal_point = '.';
-#if 0 /* BEGIN android-changed: no localeconv. */
+#if defined(__LP64__) /* BEGIN android-changed: no localeconv for ILP32. */
#ifndef KR_headers
CONST char decimal_point = localeconv()->decimal_point[0];
#else
CONST char decimal_point = '.';
#endif
+#else
+ CONST char decimal_point = '.';
#endif /* END android-changed */
sign = nz0 = nz = 0;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_messages.c b/libc/upstream-openbsd/lib/libc/locale/_def_messages.c
new file mode 100644
index 0000000..1ed653a
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_messages.c
@@ -0,0 +1,18 @@
+/* $OpenBSD: _def_messages.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _MessagesLocale _DefaultMessagesLocale =
+{
+ "^[Yy]",
+ "^[Nn]",
+ "yes",
+ "no"
+} ;
+
+const _MessagesLocale *_CurrentMessagesLocale = &_DefaultMessagesLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c b/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c
new file mode 100644
index 0000000..aa92c75
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_monetary.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: _def_monetary.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <limits.h>
+#include <locale.h>
+
+const _MonetaryLocale _DefaultMonetaryLocale =
+{
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX,
+ CHAR_MAX
+};
+
+const _MonetaryLocale *_CurrentMonetaryLocale = &_DefaultMonetaryLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c b/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c
new file mode 100644
index 0000000..6511254
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_numeric.c
@@ -0,0 +1,17 @@
+/* $OpenBSD: _def_numeric.c,v 1.4 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _NumericLocale _DefaultNumericLocale =
+{
+ ".",
+ "",
+ ""
+};
+
+const _NumericLocale *_CurrentNumericLocale = &_DefaultNumericLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/_def_time.c b/libc/upstream-openbsd/lib/libc/locale/_def_time.c
new file mode 100644
index 0000000..75179a6
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/_def_time.c
@@ -0,0 +1,36 @@
+/* $OpenBSD: _def_time.c,v 1.5 2011/10/09 06:39:53 ajacoutot Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+const _TimeLocale _DefaultTimeLocale =
+{
+ {
+ "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
+ },
+ {
+ "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+ "Friday", "Saturday"
+ },
+ {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ },
+ {
+ "January", "February", "March", "April", "May", "June", "July",
+ "August", "September", "October", "November", "December"
+ },
+ {
+ "AM", "PM"
+ },
+ "%a %b %e %H:%M:%S %Y",
+ "%m/%d/%y",
+ "%H:%M:%S",
+ "%I:%M:%S %p"
+};
+
+const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale;
diff --git a/libc/upstream-openbsd/lib/libc/locale/localeconv.c b/libc/upstream-openbsd/lib/libc/locale/localeconv.c
new file mode 100644
index 0000000..989eb4b
--- /dev/null
+++ b/libc/upstream-openbsd/lib/libc/locale/localeconv.c
@@ -0,0 +1,59 @@
+/* $OpenBSD: localeconv.c,v 1.5 2005/08/08 08:05:35 espie Exp $ */
+/*
+ * Written by J.T. Conklin <jtc@netbsd.org>.
+ * Public domain.
+ */
+
+#include <sys/localedef.h>
+#include <locale.h>
+
+/*
+ * The localeconv() function constructs a struct lconv from the current
+ * monetary and numeric locales.
+ *
+ * Because localeconv() may be called many times (especially by library
+ * routines like printf() & strtod()), the approprate members of the
+ * lconv structure are computed only when the monetary or numeric
+ * locale has been changed.
+ */
+int __mlocale_changed = 1;
+int __nlocale_changed = 1;
+
+/*
+ * Return the current locale conversion.
+ */
+struct lconv *
+localeconv(void)
+{
+ static struct lconv ret;
+
+ if (__mlocale_changed) {
+ /* LC_MONETARY */
+ ret.int_curr_symbol = _CurrentMonetaryLocale->int_curr_symbol;
+ ret.currency_symbol = _CurrentMonetaryLocale->currency_symbol;
+ ret.mon_decimal_point = _CurrentMonetaryLocale->mon_decimal_point;
+ ret.mon_thousands_sep = _CurrentMonetaryLocale->mon_thousands_sep;
+ ret.mon_grouping = _CurrentMonetaryLocale->mon_grouping;
+ ret.positive_sign = _CurrentMonetaryLocale->positive_sign;
+ ret.negative_sign = _CurrentMonetaryLocale->negative_sign;
+ ret.int_frac_digits = _CurrentMonetaryLocale->int_frac_digits;
+ ret.frac_digits = _CurrentMonetaryLocale->frac_digits;
+ ret.p_cs_precedes = _CurrentMonetaryLocale->p_cs_precedes;
+ ret.p_sep_by_space = _CurrentMonetaryLocale->p_sep_by_space;
+ ret.n_cs_precedes = _CurrentMonetaryLocale->n_cs_precedes;
+ ret.n_sep_by_space = _CurrentMonetaryLocale->n_sep_by_space;
+ ret.p_sign_posn = _CurrentMonetaryLocale->p_sign_posn;
+ ret.n_sign_posn = _CurrentMonetaryLocale->n_sign_posn;
+ __mlocale_changed = 0;
+ }
+
+ if (__nlocale_changed) {
+ /* LC_NUMERIC */
+ ret.decimal_point = (char *) _CurrentNumericLocale->decimal_point;
+ ret.thousands_sep = (char *) _CurrentNumericLocale->thousands_sep;
+ ret.grouping = (char *) _CurrentNumericLocale->grouping;
+ __nlocale_changed = 0;
+ }
+
+ return (&ret);
+}
diff --git a/linker/Android.mk b/linker/Android.mk
index 1d03a9c..c517a30 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -1,9 +1,70 @@
LOCAL_PATH:= $(call my-dir)
-linker_2nd_arch_var_prefix :=
-include $(LOCAL_PATH)/linker.mk
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES:= \
+ debugger.cpp \
+ dlfcn.cpp \
+ linker.cpp \
+ linker_environ.cpp \
+ linker_phdr.cpp \
+ rt.cpp \
+
+LOCAL_SRC_FILES_arm := arch/arm/begin.S
+LOCAL_SRC_FILES_arm64 := arch/arm64/begin.S
+LOCAL_SRC_FILES_x86 := arch/x86/begin.c
+LOCAL_SRC_FILES_x86_64 := arch/x86_64/begin.S
+LOCAL_SRC_FILES_mips := arch/mips/begin.S
+
+LOCAL_LDFLAGS := \
+ -shared \
+ -Wl,-Bsymbolic \
+ -Wl,--exclude-libs,ALL \
+
+LOCAL_CFLAGS += \
+ -fno-stack-protector \
+ -Wstrict-overflow=5 \
+ -fvisibility=hidden \
+ -Wall -Wextra -Werror \
+
+LOCAL_CONLYFLAGS += \
+ -std=gnu99 \
+
+LOCAL_CPPFLAGS += \
+ -std=gnu++11 \
+
+# We need to access Bionic private headers in the linker.
+LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/
+
+# we don't want crtbegin.o (because we have begin.o), so unset it
+# just for this module
+LOCAL_NO_CRT := true
+# TODO: split out the asflags.
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/linker_executable.mk
+
+LOCAL_STATIC_LIBRARIES := libc_nomalloc
+
+LOCAL_FORCE_STATIC_EXECUTABLE := true # not necessary when not including BUILD_EXECUTABLE
+
+LOCAL_2ND_ARCH_VAR_PREFIX := $(linker_2nd_arch_var_prefix)
+
+LOCAL_MODULE := linker
+LOCAL_MODULE_STEM_32 := linker
+LOCAL_MODULE_STEM_64 := linker64
+LOCAL_MULTILIB := both
+
+include $(LOCAL_PATH)/linker_executable.mk
ifdef TARGET_2ND_ARCH
-linker_2nd_arch_var_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
-include $(LOCAL_PATH)/linker.mk
+LOCAL_2ND_ARCH_VAR_PREFIX := $(TARGET_2ND_ARCH_VAR_PREFIX)
+OVERRIDE_BUILT_MODULE_PATH :=
+LOCAL_BUILT_MODULE :=
+LOCAL_INSTALLED_MODULE :=
+LOCAL_MODULE_STEM :=
+LOCAL_BUILT_MODULE_STEM :=
+LOCAL_INSTALLED_MODULE_STEM :=
+LOCAL_INTERMEDIATE_TARGETS :=
+include $(LOCAL_PATH)/linker_executable.mk
endif
diff --git a/linker/linker.mk b/linker/linker.mk
deleted file mode 100644
index 384435a..0000000
--- a/linker/linker.mk
+++ /dev/null
@@ -1,58 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- debugger.cpp \
- dlfcn.cpp \
- linker.cpp \
- linker_environ.cpp \
- linker_phdr.cpp \
- rt.cpp \
-
-LOCAL_SRC_FILES_arm := arch/arm/begin.S
-LOCAL_SRC_FILES_arm64 := arch/arm64/begin.S
-LOCAL_SRC_FILES_x86 := arch/x86/begin.c
-LOCAL_SRC_FILES_x86_64 := arch/x86_64/begin.S
-LOCAL_SRC_FILES_mips := arch/mips/begin.S
-
-LOCAL_LDFLAGS := \
- -shared \
- -Wl,-Bsymbolic \
- -Wl,--exclude-libs,ALL \
-
-LOCAL_CFLAGS += \
- -fno-stack-protector \
- -Wstrict-overflow=5 \
- -fvisibility=hidden \
- -Wall -Wextra -Werror \
-
-LOCAL_CONLYFLAGS += \
- -std=gnu99 \
-
-LOCAL_CPPFLAGS += \
- -std=gnu++11 \
-
-# We need to access Bionic private headers in the linker.
-LOCAL_CFLAGS += -I$(LOCAL_PATH)/../libc/
-
-# we don't want crtbegin.o (because we have begin.o), so unset it
-# just for this module
-LOCAL_NO_CRT := true
-# TODO: split out the asflags.
-LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk $(LOCAL_PATH)/linker.mk $(LOCAL_PATH)/linker_executable.mk
-
-LOCAL_STATIC_LIBRARIES := libc_nomalloc
-
-LOCAL_FORCE_STATIC_EXECUTABLE := true # not necessary when not including BUILD_EXECUTABLE
-
-LOCAL_2ND_ARCH_VAR_PREFIX := $(linker_2nd_arch_var_prefix)
-
-ifeq ($(TARGET_IS_64_BIT)|$(linker_2nd_arch_var_prefix),true|)
-LOCAL_MODULE := linker64
-else
-LOCAL_MODULE := linker
-endif
-
-include $(LOCAL_PATH)/linker_executable.mk
diff --git a/tests/Android.mk b/tests/Android.mk
index 8dffa2f..788dbcf 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -50,6 +50,7 @@
inttypes_test.cpp \
libc_logging_test.cpp \
libgen_test.cpp \
+ locale_test.cpp \
malloc_test.cpp \
math_test.cpp \
netdb_test.cpp \
@@ -81,6 +82,7 @@
system_properties_test.cpp \
time_test.cpp \
unistd_test.cpp \
+ accept4_test.cpp \
libBionicStandardTests_cflags := \
$(test_cflags) \
diff --git a/tests/accept4_test.cpp b/tests/accept4_test.cpp
new file mode 100644
index 0000000..2e6c808
--- /dev/null
+++ b/tests/accept4_test.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Contributed by: Intel Corporation, 2014
+ */
+
+#include <gtest/gtest.h>
+
+#if defined(__BIONIC__)
+ #define SOCK_CLOEXEC_SUPPORTED 1
+#elif defined(__GLIBC_PREREQ)
+ #if __GLIBC_PREREQ(2, 9)
+ #define SOCK_CLOEXEC_SUPPORTED 1
+ #endif
+#endif
+
+#if defined(SOCK_CLOEXEC_SUPPORTED)
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <fcntl.h>
+
+#define SOCK_PATH "test"
+
+static void* ConnectFn(void*) {
+ int fd = socket(PF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (fd < 0) {
+ GTEST_LOG_(ERROR) << "socket call failed: " << strerror(errno);
+ return reinterpret_cast<void*>(-1);
+ }
+
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ addr.sun_path[0] = '\0';
+ strcpy(addr.sun_path + 1, SOCK_PATH);
+
+ if (connect(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) {
+ GTEST_LOG_(ERROR) << "connect call failed: " << strerror(errno);
+ close(fd);
+ return reinterpret_cast<void*>(-1);
+ }
+
+ close(fd);
+
+ return NULL;
+}
+#endif
+
+TEST(accept4, smoke) {
+#if defined(SOCK_CLOEXEC_SUPPORTED)
+ int fd = socket(PF_UNIX, SOCK_SEQPACKET, 0);
+ ASSERT_NE(fd, -1) << strerror(errno);
+
+ struct sockaddr_un addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ addr.sun_path[0] = '\0';
+ strcpy(addr.sun_path + 1, SOCK_PATH);
+
+ ASSERT_NE(-1, bind(fd, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr))) << strerror(errno);
+
+ ASSERT_NE(-1, listen(fd, 1)) << strerror(errno);
+
+ pthread_t thread;
+ ASSERT_EQ(0, pthread_create(&thread, NULL, ConnectFn, NULL));
+
+ fd_set read_set;
+ FD_ZERO(&read_set);
+ FD_SET(fd, &read_set);
+ timeval tv;
+ tv.tv_sec = 5;
+ tv.tv_usec = 0;
+ ASSERT_LT(0, select(fd+1, &read_set, NULL, NULL, &tv));
+
+ socklen_t len = sizeof(addr);
+ int fd_acc = accept4(fd, reinterpret_cast<struct sockaddr*>(&addr), &len, SOCK_CLOEXEC);
+ ASSERT_NE(fd_acc, -1) << strerror(errno);
+
+ // Check that the flag was set properly.
+ ASSERT_EQ(FD_CLOEXEC, fcntl(fd_acc, F_GETFD) & FD_CLOEXEC);
+
+ void* ret_val;
+ pthread_join(thread, &ret_val);
+ ASSERT_EQ(NULL, ret_val);
+
+ close(fd_acc);
+ close(fd);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
diff --git a/tests/locale_test.cpp b/tests/locale_test.cpp
new file mode 100644
index 0000000..df58a70
--- /dev/null
+++ b/tests/locale_test.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include <locale.h>
+
+TEST(locale, localeconv) {
+#ifdef __LP64__
+ ASSERT_STREQ(".", localeconv()->decimal_point);
+ ASSERT_STREQ("", localeconv()->currency_symbol);
+#else
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif
+}
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index 26b7775..c055769 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -387,3 +387,51 @@
ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id));
#endif
}
+
+TEST(time, strtotimeval) {
+#if defined(__BIONIC__)
+ struct timeval tv1;
+ char* rest1 = strtotimeval("10.123456", &tv1);
+ ASSERT_EQ(10, tv1.tv_sec);
+ ASSERT_EQ(123456, tv1.tv_usec);
+ ASSERT_EQ('\0', *rest1);
+
+ // strtotimeval interprets the fractional part as microseconds and thus will
+ // only consider its first 6 digits. Even so it should consume all valid
+ // digits.
+ struct timeval tv2;
+ char* rest2 = strtotimeval(".1234567", &tv2);
+ ASSERT_EQ(0, tv2.tv_sec);
+ ASSERT_EQ(123456, tv2.tv_usec);
+ ASSERT_EQ('\0', *rest2);
+
+ struct timeval tv3;
+ char* rest3 = strtotimeval("1.1a", &tv3);
+ ASSERT_EQ(1, tv3.tv_sec);
+ ASSERT_EQ(100000, tv3.tv_usec);
+ ASSERT_EQ('a', *rest3);
+
+ struct timeval tv4;
+ char* rest4 = strtotimeval("a", &tv4);
+ ASSERT_EQ(0, tv4.tv_sec);
+ ASSERT_EQ(0, tv4.tv_usec);
+ ASSERT_EQ('a', *rest4);
+
+ struct timeval tv5;
+ char* rest5 = strtotimeval("0", &tv5);
+ ASSERT_EQ(0, tv5.tv_sec);
+ ASSERT_EQ(0, tv5.tv_usec);
+ ASSERT_EQ('\0', *rest5);
+
+ // TODO: should we reject this case and just return '.'?
+ struct timeval tv6;
+ char* rest6 = strtotimeval(".", &tv6);
+ ASSERT_EQ(0, tv6.tv_sec);
+ ASSERT_EQ(0, tv6.tv_usec);
+ ASSERT_EQ('\0', *rest6);
+
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
+