Merge "Add cache related sysconf queries"
diff --git a/build/run-on-host.mk b/build/run-on-host.mk
index f016361..dc7e5d5 100644
--- a/build/run-on-host.mk
+++ b/build/run-on-host.mk
@@ -14,6 +14,10 @@
# limitations under the License.
#
+# Include once
+ifneq ($(bionic_run_on_host_mk_included),true)
+bionic_run_on_host_mk_included:=true
+
ifneq ($(TARGET_ARCH),$(filter $(TARGET_ARCH),arm mips x86))
LINKER = linker64
else
@@ -37,3 +41,4 @@
ln -fs `realpath $(TARGET_OUT)/lib64` /system/; \
fi
endif
+endif
diff --git a/libc/Android.mk b/libc/Android.mk
index 2270dc6..f04cf5c 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -153,6 +153,7 @@
bionic/poll.cpp \
bionic/posix_fadvise.cpp \
bionic/posix_fallocate.cpp \
+ bionic/posix_madvise.cpp \
bionic/posix_timers.cpp \
bionic/pthread_atfork.cpp \
bionic/pthread_attr.cpp \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 39ff37d..d9ede2f 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -101,7 +101,7 @@
void* mremap(void*, size_t, size_t, unsigned long) all
int msync(const void*, size_t, int) all
int mprotect(const void*, size_t, int) all
-int madvise(const void*, size_t, int) all
+int madvise(void*, size_t, int) all
int mlock(const void* addr, size_t len) all
int munlock(const void* addr, size_t len) all
int mlockall(int flags) all
diff --git a/libc/arch-arm/bionic/_setjmp.S b/libc/arch-arm/bionic/_setjmp.S
index 7d637fd..51dfc0a 100644
--- a/libc/arch-arm/bionic/_setjmp.S
+++ b/libc/arch-arm/bionic/_setjmp.S
@@ -59,14 +59,12 @@
add r1, r0, #(_JB_CORE_BASE * 4)
stmia r1, {r4-r14}
-#ifdef __ARM_HAVE_VFP
/* Store floating-point registers */
add r1, r0, #(_JB_FLOAT_BASE * 4)
vstmia r1, {d8-d15}
/* Store floating-point state */
fmrx r1, fpscr
str r1, [r0, #(_JB_FLOAT_STATE * 4)]
-#endif /* __ARM_HAVE_VFP */
mov r0, #0x00000000
bx lr
@@ -81,14 +79,12 @@
teq r2, r3
bne botch
-#ifdef __ARM_HAVE_VFP
/* Restore floating-point registers */
add r2, r0, #(_JB_FLOAT_BASE * 4)
vldmia r2, {d8-d15}
/* Restore floating-point state */
ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
fmxr fpscr, r2
-#endif /* __ARM_HAVE_VFP */
/* Restore core registers */
add r2, r0, #(_JB_CORE_BASE * 4)
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index 0c9082c..435ef86 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -72,14 +72,12 @@
add r1, r0, #(_JB_CORE_BASE * 4)
stmia r1, {r4-r14}
-#ifdef __ARM_HAVE_VFP
/* Store floating-point registers */
add r1, r0, #(_JB_FLOAT_BASE * 4)
vstmia r1, {d8-d15}
/* Store floating-point state */
fmrx r1, fpscr
str r1, [r0, #(_JB_FLOAT_STATE * 4)]
-#endif /* __ARM_HAVE_VFP */
mov r0, #0x00000000
bx lr
@@ -115,14 +113,12 @@
ldmfd sp!, {r0, r1, r14}
.cfi_def_cfa_offset 0
-#ifdef __ARM_HAVE_VFP
/* Restore floating-point registers */
add r2, r0, #(_JB_FLOAT_BASE * 4)
vldmia r2, {d8-d15}
/* Restore floating-point state */
ldr r2, [r0, #(_JB_FLOAT_STATE * 4)]
fmxr fpscr, r2
-#endif /* __ARM_HAVE_VFP */
/* Restore core registers */
add r2, r0, #(_JB_CORE_BASE * 4)
@@ -139,11 +135,7 @@
teq r0, #0x00000000
moveq r0, #0x00000001
bx lr
-#ifdef __ARM_26__
mov r15, r14
-#else
- mov r15, r14
-#endif
/* validation failed, die die die. */
botch:
diff --git a/libc/arch-arm/include/machine/cpu-features.h b/libc/arch-arm/include/machine/cpu-features.h
index 0725c74..fc8c80d 100644
--- a/libc/arch-arm/include/machine/cpu-features.h
+++ b/libc/arch-arm/include/machine/cpu-features.h
@@ -28,14 +28,6 @@
#ifndef _ARM_MACHINE_CPU_FEATURES_H
#define _ARM_MACHINE_CPU_FEATURES_H
-/* The purpose of this file is to define several macros corresponding
- * to CPU features that may or may not be available at build time on
- * on the target CPU.
- *
- * This is done to abstract us from the various ARM Architecture
- * quirks and alphabet soup.
- */
-
/* __ARM_ARCH__ is a number corresponding to the ARM revision
* we're going to support. Our toolchain doesn't define __ARM_ARCH__
* so try to guess it.
@@ -53,23 +45,4 @@
# endif
#endif
-/* define __ARM_HAVE_HALFWORD_MULTIPLY when half-word multiply instructions
- * this means variants of: smul, smulw, smla, smlaw, smlal
- */
-#define __ARM_HAVE_HALFWORD_MULTIPLY 1
-
-/* define _ARM_HAVE_VFP if we have VFPv3
- */
-#if __ARM_ARCH__ >= 7 && defined __VFP_FP__
-# define __ARM_HAVE_VFP
-#endif
-
-/* define _ARM_HAVE_NEON for ARMv7 architecture if we support the
- * Neon SIMD instruction set extensions. This also implies
- * that VFPv3-D32 is supported.
- */
-#if __ARM_ARCH__ >= 7 && defined __ARM_NEON__
-# define __ARM_HAVE_NEON
-#endif
-
#endif /* _ARM_MACHINE_CPU_FEATURES_H */
diff --git a/libc/arch-arm64/include/machine/endian.h b/libc/arch-arm64/include/machine/endian.h
index 4743733..b9544af 100644
--- a/libc/arch-arm64/include/machine/endian.h
+++ b/libc/arch-arm64/include/machine/endian.h
@@ -31,13 +31,8 @@
#ifdef __GNUC__
-#define __swap16md(x) ({ \
- register u_int16_t _x = (x); \
- __asm volatile ("rev16 %0, %0" : "+r" (_x)); \
- _x; \
-})
-
/* Use GCC builtins */
+#define __swap16md(x) __builtin_bswap16(x)
#define __swap32md(x) __builtin_bswap32(x)
#define __swap64md(x) __builtin_bswap64(x)
diff --git a/libc/arch-x86/include/machine/endian.h b/libc/arch-x86/include/machine/endian.h
index e1506b1..5feebd8 100644
--- a/libc/arch-x86/include/machine/endian.h
+++ b/libc/arch-x86/include/machine/endian.h
@@ -27,33 +27,14 @@
#ifndef _MACHINE_ENDIAN_H_
#define _MACHINE_ENDIAN_H_
-#ifdef __GNUC__
-
-#define __swap32md(x) __statement({ \
- uint32_t __swap32md_x = (x); \
- \
- __asm ("bswap %0" : "+r" (__swap32md_x)); \
- __swap32md_x; \
-})
-
-#define __swap64md(x) __statement({ \
- uint64_t __swap64md_x = (x); \
- \
- (uint64_t)__swap32md(__swap64md_x >> 32) | \
- (uint64_t)__swap32md(__swap64md_x & 0xffffffff) << 32; \
-})
-#define __swap16md(x) __statement({ \
- uint16_t __swap16md_x = (x); \
- \
- __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); \
- __swap16md_x; \
-})
+/* Use GCC builtins */
+#define __swap16md(x) __builtin_bswap16(x)
+#define __swap32md(x) __builtin_bswap32(x)
+#define __swap64md(x) __builtin_bswap64(x)
/* Tell sys/endian.h we have MD variants of the swap macros. */
#define MD_SWAP
-#endif /* __GNUC__ */
-
#define _BYTE_ORDER _LITTLE_ENDIAN
#include <sys/types.h>
#include <sys/endian.h>
diff --git a/libc/arch-x86_64/include/machine/endian.h b/libc/arch-x86_64/include/machine/endian.h
index 8a3b0c5..2c493b2 100644
--- a/libc/arch-x86_64/include/machine/endian.h
+++ b/libc/arch-x86_64/include/machine/endian.h
@@ -27,34 +27,14 @@
#ifndef _MACHINE_ENDIAN_H_
#define _MACHINE_ENDIAN_H_
-#ifdef __GNUC__
-
-#define __swap32md(x) __statement({ \
- u_int32_t __swap32md_x = (x); \
- \
- __asm ("bswap %0" : "+r" (__swap32md_x)); \
- __swap32md_x; \
-})
-
-#define __swap64md(x) __statement({ \
- u_int64_t __swap64md_x = (x); \
- \
- __asm ("bswapq %0" : "+r" (__swap64md_x)); \
- __swap64md_x; \
-})
-
-#define __swap16md(x) __statement({ \
- u_int16_t __swap16md_x = (x); \
- \
- __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); \
- __swap16md_x; \
-})
+/* Use GCC builtins */
+#define __swap16md(x) __builtin_bswap16(x)
+#define __swap32md(x) __builtin_bswap32(x)
+#define __swap64md(x) __builtin_bswap64(x)
/* Tell sys/endian.h we have MD variants of the swap macros. */
#define MD_SWAP
-#endif /* __GNUC__ */
-
#define _BYTE_ORDER _LITTLE_ENDIAN
#include <sys/types.h>
#include <sys/endian.h>
diff --git a/libc/bionic/posix_madvise.cpp b/libc/bionic/posix_madvise.cpp
new file mode 100644
index 0000000..d77be01
--- /dev/null
+++ b/libc/bionic/posix_madvise.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#include <errno.h>
+#include <sys/mman.h>
+
+#include "private/ErrnoRestorer.h"
+
+int posix_madvise(void* addr, size_t len, int advice) {
+ ErrnoRestorer errno_restorer;
+
+ // Don't call madvise() on POSIX_MADV_DONTNEED, it will make the space not available.
+ if (advice == POSIX_MADV_DONTNEED) {
+ return 0;
+ }
+ return (madvise(addr, len, advice) == 0 ? 0 : errno);
+}
diff --git a/libc/bionic/pty.cpp b/libc/bionic/pty.cpp
index 995e006..2c86180 100644
--- a/libc/bionic/pty.cpp
+++ b/libc/bionic/pty.cpp
@@ -28,13 +28,15 @@
#include <errno.h>
#include <fcntl.h>
+#include <pty.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <unistd.h>
+#include <utmp.h>
-int getpt(void) {
+int getpt() {
return posix_openpt(O_RDWR|O_NOCTTY);
}
@@ -47,7 +49,7 @@
}
char* ptsname(int fd) {
- static char buf[64];
+ static char buf[32];
return ptsname_r(fd, buf, sizeof(buf)) == 0 ? buf : NULL;
}
@@ -105,3 +107,83 @@
int unlock = 0;
return ioctl(fd, TIOCSPTLCK, &unlock);
}
+
+int openpty(int* master, int* slave, char* name, const termios* t, const winsize* ws) {
+ *master = getpt();
+ if (*master == -1) {
+ return -1;
+ }
+
+ if (grantpt(*master) == -1 || unlockpt(*master) == -1) {
+ close(*master);
+ return -1;
+ }
+
+ char buf[32];
+ if (name == NULL) {
+ name = buf;
+ }
+ if (ptsname_r(*master, name, sizeof(buf)) != 0) {
+ close(*master);
+ return -1;
+ }
+
+ *slave = open(name, O_RDWR|O_NOCTTY);
+ if (*slave == -1) {
+ close(*master);
+ return -1;
+ }
+
+ if (t != NULL) {
+ tcsetattr(*slave, TCSAFLUSH, t);
+ }
+ if (ws != NULL) {
+ ioctl(*slave, TIOCSWINSZ, ws);
+ }
+
+ return 0;
+}
+
+int forkpty(int* master, char* name, const termios* t, const winsize* ws) {
+ int slave;
+ if (openpty(master, &slave, name, t, ws) == -1) {
+ return -1;
+ }
+
+ pid_t pid = fork();
+ if (pid == -1) {
+ close(*master);
+ close(slave);
+ return -1;
+ }
+
+ if (pid == 0) {
+ // Child.
+ close(*master);
+ if (login_tty(slave) == -1) {
+ _exit(1);
+ }
+ return 0;
+ }
+
+ // Parent.
+ close(slave);
+ return pid;
+}
+
+int login_tty(int fd) {
+ setsid();
+
+ if (ioctl(fd, TIOCSCTTY, NULL) == -1) {
+ return -1;
+ }
+
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO) {
+ close(fd);
+ }
+
+ return 0;
+}
diff --git a/libc/include/arpa/nameser.h b/libc/include/arpa/nameser.h
index a87ac91..91561ce 100644
--- a/libc/include/arpa/nameser.h
+++ b/libc/include/arpa/nameser.h
@@ -518,9 +518,8 @@
(cp) += NS_INT32SZ; \
} while (/*CONSTCOND*/0)
-/*
- * ANSI C identifier hiding for bind's lib/nameser.
- */
+#if !defined(__LP64__)
+/* Annoyingly, LP32 shipped with __ names. */
#define ns_msg_getflag __ns_msg_getflag
#define ns_get16 __ns_get16
#define ns_get32 __ns_get32
@@ -564,101 +563,73 @@
#define ns_subdomain __ns_subdomain
#define ns_makecanon __ns_makecanon
#define ns_samename __ns_samename
-#define ns_newmsg_init __ns_newmsg_init
-#define ns_newmsg_copy __ns_newmsg_copy
-#define ns_newmsg_id __ns_newmsg_id
-#define ns_newmsg_flag __ns_newmsg_flag
-#define ns_newmsg_q __ns_newmsg_q
-#define ns_newmsg_rr __ns_newmsg_rr
-#define ns_newmsg_done __ns_newmsg_done
-#define ns_rdata_unpack __ns_rdata_unpack
-#define ns_rdata_equal __ns_rdata_equal
-#define ns_rdata_refers __ns_rdata_refers
+#endif
__BEGIN_DECLS
-int ns_msg_getflag(ns_msg, int);
-uint16_t ns_get16(const u_char *);
-uint32_t ns_get32(const u_char *);
-void ns_put16(uint16_t, u_char *);
-void ns_put32(uint32_t, u_char *);
-int ns_initparse(const u_char *, int, ns_msg *);
-int ns_skiprr(const u_char *, const u_char *, ns_sect, int);
-int ns_parserr(ns_msg *, ns_sect, int, ns_rr *);
-int ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *);
+int ns_msg_getflag(ns_msg, int) __LIBC_ABI_PUBLIC__;
+uint16_t ns_get16(const u_char *) __LIBC_ABI_PUBLIC__;
+uint32_t ns_get32(const u_char *) __LIBC_ABI_PUBLIC__;
+void ns_put16(uint16_t, u_char *) __LIBC_ABI_PUBLIC__;
+void ns_put32(uint32_t, u_char *) __LIBC_ABI_PUBLIC__;
+int ns_initparse(const u_char *, int, ns_msg *) __LIBC_ABI_PUBLIC__;
+int ns_skiprr(const u_char *, const u_char *, ns_sect, int) __LIBC_ABI_PUBLIC__;
+int ns_parserr(ns_msg *, ns_sect, int, ns_rr *) __LIBC_ABI_PUBLIC__;
+int ns_parserr2(ns_msg *, ns_sect, int, ns_rr2 *) __LIBC_HIDDEN__;
int ns_sprintrr(const ns_msg *, const ns_rr *,
- const char *, const char *, char *, size_t);
+ const char *, const char *, char *, size_t) __LIBC_ABI_PUBLIC__;
int ns_sprintrrf(const u_char *, size_t, const char *,
ns_class, ns_type, u_long, const u_char *,
size_t, const char *, const char *,
- char *, size_t);
-int ns_format_ttl(u_long, char *, size_t);
-int ns_parse_ttl(const char *, u_long *);
-uint32_t ns_datetosecs(const char *cp, int *errp);
-int ns_name_ntol(const u_char *, u_char *, size_t);
-int ns_name_ntop(const u_char *, char *, size_t);
-int ns_name_pton(const char *, u_char *, size_t);
-int ns_name_pton2(const char *, u_char *, size_t, size_t *);
+ char *, size_t) __LIBC_ABI_PUBLIC__;
+int ns_format_ttl(u_long, char *, size_t) __LIBC_ABI_PUBLIC__;
+int ns_parse_ttl(const char *, u_long *) __LIBC_ABI_PUBLIC__;
+uint32_t ns_datetosecs(const char *cp, int *errp) __LIBC_ABI_PUBLIC__;
+int ns_name_ntol(const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
+int ns_name_ntop(const u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;
+int ns_name_pton(const char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
+int ns_name_pton2(const char *, u_char *, size_t, size_t *) __LIBC_HIDDEN__;
int ns_name_unpack(const u_char *, const u_char *,
- const u_char *, u_char *, size_t);
+ const u_char *, u_char *, size_t) __LIBC_ABI_PUBLIC__;
int ns_name_unpack2(const u_char *, const u_char *,
const u_char *, u_char *, size_t,
- size_t *);
+ size_t *) __LIBC_HIDDEN__;
int ns_name_pack(const u_char *, u_char *, int,
- const u_char **, const u_char **);
+ const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;
int ns_name_uncompress(const u_char *, const u_char *,
- const u_char *, char *, size_t);
+ const u_char *, char *, size_t) __LIBC_ABI_PUBLIC__;
int ns_name_compress(const char *, u_char *, size_t,
- const u_char **, const u_char **);
-int ns_name_skip(const u_char **, const u_char *);
+ const u_char **, const u_char **) __LIBC_ABI_PUBLIC__;
+int ns_name_skip(const u_char **, const u_char *) __LIBC_ABI_PUBLIC__;
void ns_name_rollback(const u_char *, const u_char **,
- const u_char **);
+ const u_char **) __LIBC_ABI_PUBLIC__;
int ns_sign(u_char *, int *, int, int, void *,
- const u_char *, int, u_char *, int *, time_t);
+ const u_char *, int, u_char *, int *, time_t) __LIBC_ABI_PUBLIC__;
int ns_sign2(u_char *, int *, int, int, void *,
const u_char *, int, u_char *, int *, time_t,
- u_char **, u_char **);
-ssize_t ns_name_length(ns_nname_ct, size_t);
-int ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t);
-int ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int);
-int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int);
-int ns_name_labels(ns_nname_ct, size_t);
+ u_char **, u_char **) __LIBC_ABI_PUBLIC__;
+ssize_t ns_name_length(ns_nname_ct, size_t) __LIBC_HIDDEN__;
+int ns_name_eq(ns_nname_ct, size_t, ns_nname_ct, size_t) __LIBC_HIDDEN__;
+int ns_name_owned(ns_namemap_ct, int, ns_namemap_ct, int) __LIBC_HIDDEN__;
+int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int) __LIBC_HIDDEN__;
+int ns_name_labels(ns_nname_ct, size_t) __LIBC_HIDDEN__;
int ns_sign_tcp(u_char *, int *, int, int,
- ns_tcp_tsig_state *, int);
+ ns_tcp_tsig_state *, int) __LIBC_ABI_PUBLIC__;
int ns_sign_tcp2(u_char *, int *, int, int,
ns_tcp_tsig_state *, int,
- u_char **, u_char **);
+ u_char **, u_char **) __LIBC_ABI_PUBLIC__;
int ns_sign_tcp_init(void *, const u_char *, int,
- ns_tcp_tsig_state *);
-u_char *ns_find_tsig(u_char *, u_char *);
+ ns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;
+u_char *ns_find_tsig(u_char *, u_char *) __LIBC_ABI_PUBLIC__;
int ns_verify(u_char *, int *, void *,
const u_char *, int, u_char *, int *,
- time_t *, int);
+ time_t *, int) __LIBC_ABI_PUBLIC__;
int ns_verify_tcp(u_char *, int *, ns_tcp_tsig_state *, int);
int ns_verify_tcp_init(void *, const u_char *, int,
- ns_tcp_tsig_state *);
-int ns_samedomain(const char *, const char *);
-int ns_subdomain(const char *, const char *);
-int ns_makecanon(const char *, char *, size_t);
-int ns_samename(const char *, const char *);
-int ns_newmsg_init(u_char *buffer, size_t bufsiz, ns_newmsg *);
-int ns_newmsg_copy(ns_newmsg *, ns_msg *);
-void ns_newmsg_id(ns_newmsg *handle, uint16_t id);
-void ns_newmsg_flag(ns_newmsg *handle, ns_flag flag, u_int value);
-int ns_newmsg_q(ns_newmsg *handle, ns_nname_ct qname,
- ns_type qtype, ns_class qclass);
-int ns_newmsg_rr(ns_newmsg *handle, ns_sect sect,
- ns_nname_ct name, ns_type type,
- ns_class rr_class, uint32_t ttl,
- uint16_t rdlen, const u_char *rdata);
-size_t ns_newmsg_done(ns_newmsg *handle);
-ssize_t ns_rdata_unpack(const u_char *, const u_char *, ns_type,
- const u_char *, size_t, u_char *, size_t);
-int ns_rdata_equal(ns_type,
- const u_char *, size_t,
- const u_char *, size_t);
-int ns_rdata_refers(ns_type,
- const u_char *, size_t,
- const u_char *);
+ ns_tcp_tsig_state *) __LIBC_ABI_PUBLIC__;
+int ns_samedomain(const char *, const char *) __LIBC_ABI_PUBLIC__;
+int ns_subdomain(const char *, const char *) __LIBC_ABI_PUBLIC__;
+int ns_makecanon(const char *, char *, size_t) __LIBC_ABI_PUBLIC__;
+int ns_samename(const char *, const char *) __LIBC_ABI_PUBLIC__;
__END_DECLS
#ifdef BIND_4_COMPAT
diff --git a/libc/include/machine/posix_limits.h b/libc/include/machine/posix_limits.h
index 939a1de..25887be 100644
--- a/libc/include/machine/posix_limits.h
+++ b/libc/include/machine/posix_limits.h
@@ -32,7 +32,7 @@
/* Any constant values here other than -1 or 200809L are explicitly specified by POSIX.1-2008. */
/* Keep it sorted. */
-#define _POSIX_ADVISORY_INFO -1 /* posix_madvise() not implemented */
+#define _POSIX_ADVISORY_INFO 200809L
#define _POSIX_AIO_LISTIO_MAX 2
#define _POSIX_AIO_MAX 1
#define _POSIX_ARG_MAX 4096
diff --git a/libc/include/pty.h b/libc/include/pty.h
new file mode 100644
index 0000000..bca1137
--- /dev/null
+++ b/libc/include/pty.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2014 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 _PTY_H
+#define _PTY_H
+
+#include <sys/cdefs.h>
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+__BEGIN_DECLS
+
+int openpty(int*, int*, char*, const struct termios*, const struct winsize*);
+int forkpty(int*, char*, const struct termios*, const struct winsize*);
+
+__END_DECLS
+
+#endif /* _PTY_H */
diff --git a/libc/include/sys/mman.h b/libc/include/sys/mman.h
index 5a8c985..1663222 100644
--- a/libc/include/sys/mman.h
+++ b/libc/include/sys/mman.h
@@ -43,6 +43,12 @@
#define MREMAP_MAYMOVE 1
#define MREMAP_FIXED 2
+#define POSIX_MADV_NORMAL MADV_NORMAL
+#define POSIX_MADV_RANDOM MADV_RANDOM
+#define POSIX_MADV_SEQUENTIAL MADV_SEQUENTIAL
+#define POSIX_MADV_WILLNEED MADV_WILLNEED
+#define POSIX_MADV_DONTNEED MADV_DONTNEED
+
extern void* mmap(void*, size_t, int, int, int, off_t);
extern void* mmap64(void*, size_t, int, int, int, off64_t);
extern int munmap(void*, size_t);
@@ -54,13 +60,15 @@
extern int munlockall(void);
extern int mlock(const void*, size_t);
extern int munlock(const void*, size_t);
-extern int madvise(const void*, size_t, int);
+extern int madvise(void*, size_t, int);
extern int mlock(const void*, size_t);
extern int munlock(const void*, size_t);
extern int mincore(void*, size_t, unsigned char*);
+extern int posix_madvise(void*, size_t, int);
+
__END_DECLS
#endif /* _SYS_MMAN_H_ */
diff --git a/libc/include/utmp.h b/libc/include/utmp.h
index d764227..ebf2372 100644
--- a/libc/include/utmp.h
+++ b/libc/include/utmp.h
@@ -91,6 +91,8 @@
void setutent();
struct utmp* getutent();
+int login_tty(int);
+
__END_DECLS
#endif /* _UTMP_H_ */
diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py
index 0c7e28e..153b840 100755
--- a/libc/tools/check-symbols-glibc.py
+++ b/libc/tools/check-symbols-glibc.py
@@ -81,12 +81,12 @@
'__xpg_basename': '__gnu_basename',
}
-glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*')
+glibc = GetSymbolsFromSystemSo('libc.so.*', 'librt.so.*', 'libpthread.so.*', 'libresolv.so.*', 'libm.so.*', 'libutil.so.*')
bionic = GetSymbolsFromAndroidSo('libc.so', 'libm.so')
posix = GetSymbolsFromTxt(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'posix-2013.txt'))
ndk_ignored = GetNdkIgnored()
-glibc = map(MangleGlibcNameToBionic, glibc)
+glibc = set(map(MangleGlibcNameToBionic, glibc))
# bionic includes various BSD symbols to ease porting other BSD-licensed code.
bsd_stuff = set([
@@ -189,21 +189,26 @@
])
if not only_unwanted:
- print 'glibc:'
- for symbol in sorted(glibc):
- print symbol
+ #print 'glibc:'
+ #for symbol in sorted(glibc):
+ # print symbol
+ #print
- print
- print 'bionic:'
- for symbol in sorted(bionic):
- print symbol
+ #print 'bionic:'
+ #for symbol in sorted(bionic):
+ # print symbol
+ #print
- print
- print 'in posix but not bionic:'
- for symbol in sorted(posix.difference(bionic)):
+ print 'in glibc (but not posix) but not bionic:'
+ for symbol in sorted((glibc - posix).difference(bionic)):
print symbol
-
print
+
+ print 'in posix (and implemented in glibc) but not bionic:'
+ for symbol in sorted((posix.intersection(glibc)).difference(bionic)):
+ print symbol
+ print
+
print 'in bionic but not glibc:'
allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff |
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b2e7464..3409931 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -320,7 +320,7 @@
if (trav == nullptr) {
// si was not in solist
- DL_ERR("name \"%s\" is not in solist!", si->name);
+ DL_ERR("name \"%s\"@%p is not in solist!", si->name, si);
return;
}
@@ -1150,20 +1150,29 @@
soinfo* si = nullptr;
while ((si = depth_first_list.pop_front()) != nullptr) {
+ if (local_unload_list.contains(si)) {
+ continue;
+ }
+
local_unload_list.push_back(si);
+
if (si->has_min_version(0)) {
soinfo* child = nullptr;
while ((child = si->get_children().pop_front()) != nullptr) {
- TRACE("%s needs to unload %s", si->name, child->name);
+ TRACE("%s@%p needs to unload %s@%p", si->name, si, child->name, child);
if (local_unload_list.contains(child)) {
continue;
- } else if (child->get_local_group_root() != root) {
+ } else if (child->is_linked() && child->get_local_group_root() != root) {
external_unload_list.push_back(child);
} else {
depth_first_list.push_front(child);
}
}
} else {
+#ifdef __LP64__
+ __libc_fatal("soinfo for \"%s\"@%p has no version", si->name, si);
+#else
+ PRINT("warning: soinfo for \"%s\"@%p has no version", si->name, si);
for_each_dt_needed(si, [&] (const char* library_name) {
TRACE("deprecated (old format of soinfo): %s needs to unload %s", si->name, library_name);
soinfo* needed = find_library(library_name, RTLD_NOLOAD, nullptr);
@@ -1175,7 +1184,7 @@
} else if (local_unload_list.contains(needed)) {
// already visited
return;
- } else if (needed->get_local_group_root() != root) {
+ } else if (needed->is_linked() && needed->get_local_group_root() != root) {
// external group
external_unload_list.push_back(needed);
} else {
@@ -1183,6 +1192,7 @@
depth_first_list.push_front(needed);
}
});
+#endif
}
}
diff --git a/tests/Android.mk b/tests/Android.mk
index 93ab9bd..3f5a112 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -72,6 +72,7 @@
mntent_test.cpp \
netdb_test.cpp \
pthread_test.cpp \
+ pty_test.cpp \
regex_test.cpp \
sched_test.cpp \
search_test.cpp \
@@ -108,6 +109,7 @@
uchar_test.cpp \
uniqueptr_test.cpp \
unistd_test.cpp \
+ utmp_test.cpp \
wchar_test.cpp \
libBionicStandardTests_cflags := \
@@ -309,7 +311,7 @@
libBionicStandardTests \
bionic-unit-tests-glibc_ldlibs := \
- -lrt -ldl \
+ -lrt -ldl -lutil \
bionic-unit-tests-glibc_c_includes := \
bionic/libc \
diff --git a/tests/pty_test.cpp b/tests/pty_test.cpp
new file mode 100644
index 0000000..7fe97e9
--- /dev/null
+++ b/tests/pty_test.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 <pty.h>
+#include <sys/ioctl.h>
+
+TEST(pty, openpty) {
+ int master, slave;
+ char name[32];
+ struct winsize w = { 123, 456, 9999, 999 };
+ ASSERT_EQ(0, openpty(&master, &slave, name, NULL, &w));
+ ASSERT_NE(-1, master);
+ ASSERT_NE(-1, slave);
+ ASSERT_NE(master, slave);
+
+ char tty_name[32];
+ ASSERT_EQ(0, ttyname_r(slave, tty_name, sizeof(tty_name)));
+ ASSERT_STREQ(tty_name, name);
+
+ struct winsize w_actual;
+ ASSERT_EQ(0, ioctl(slave, TIOCGWINSZ, &w_actual));
+ ASSERT_EQ(w_actual.ws_row, w.ws_row);
+ ASSERT_EQ(w_actual.ws_col, w.ws_col);
+ ASSERT_EQ(w_actual.ws_xpixel, w.ws_xpixel);
+ ASSERT_EQ(w_actual.ws_ypixel, w.ws_ypixel);
+
+ close(master);
+ close(slave);
+}
+
+TEST(pty, forkpty) {
+ pid_t sid = getsid(0);
+
+ int master;
+ pid_t pid = forkpty(&master, NULL, NULL, NULL);
+ ASSERT_NE(-1, pid);
+
+ if (pid == 0) {
+ // We're the child.
+ ASSERT_NE(sid, getsid(0));
+ _exit(0);
+ }
+
+ ASSERT_EQ(sid, getsid(0));
+
+ int status;
+ ASSERT_EQ(pid, waitpid(pid, &status, 0));
+ ASSERT_TRUE(WIFEXITED(status));
+ ASSERT_EQ(0, WEXITSTATUS(status));
+
+ close(master);
+}
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index 75ccfa3..b0e40fd 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -172,3 +172,46 @@
ASSERT_STREQ(NEWPAGE2_MSG, buf);
ASSERT_STREQ(END_MSG, buf+pagesize-sizeof(END_MSG));
}
+
+TEST(sys_mman, posix_madvise) {
+ TemporaryFile tempfile;
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+ char buf[pagesize];
+
+ // Prepare environment.
+ ASSERT_EQ(static_cast<ssize_t>(pagesize), write(tempfile.fd, buf, pagesize));
+ void* map = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, tempfile.fd, 0);
+ ASSERT_NE(MAP_FAILED, map);
+
+ // Verify different options of posix_madvise.
+ ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_NORMAL));
+ ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_SEQUENTIAL));
+ ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_RANDOM));
+ ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_WILLNEED));
+
+ ASSERT_EQ(0, munmap(map, pagesize));
+}
+
+// Verify that memory can still access after posix_madvise(POSIX_MADV_DONTNEED).
+// We should test on MAP_ANONYMOUS memory to verify whether the memory is discarded,
+// because the content of non MAP_ANONYMOUS memory can be reread from file.
+TEST(sys_mman, posix_madvise_POSIX_MADV_DONTNEED) {
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+
+ void* map = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ ASSERT_NE(MAP_FAILED, map);
+
+ int* int_ptr = reinterpret_cast<int*>(map);
+ for (int i = 0; i < static_cast<int>(pagesize / sizeof(int)); ++i) {
+ *int_ptr++ = i;
+ }
+
+ ASSERT_EQ(0, posix_madvise(map, pagesize, POSIX_MADV_DONTNEED));
+
+ int_ptr = reinterpret_cast<int*>(map);
+ for (int i = 0; i < static_cast<int>(pagesize / sizeof(int)); ++i) {
+ ASSERT_EQ(i, *int_ptr++);
+ }
+
+ ASSERT_EQ(0, munmap(map, pagesize));
+}
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index 34b7bf3..b37687f 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -523,6 +523,7 @@
// Verify according to POSIX.1-2008.
EXPECT_EQ(200809L, _POSIX_VERSION);
+ EXPECT_EQ(_POSIX_VERSION, _POSIX_ADVISORY_INFO);
EXPECT_GT(_POSIX_AIO_LISTIO_MAX, 0);
EXPECT_GT(_POSIX_AIO_MAX, 0);
EXPECT_GT(_POSIX_ARG_MAX, 0);
@@ -611,8 +612,7 @@
#if defined(__BIONIC__)
// These tests only pass on bionic, as bionic and glibc has different support on these macros.
- // Macros like _POSIX_ADVISORY_INFO are not supported on bionic yet.
- EXPECT_EQ(-1, _POSIX_ADVISORY_INFO);
+ // Macros like _POSIX_ASYNCHRONOUS_IO are not supported on bionic yet.
EXPECT_EQ(-1, _POSIX_ASYNCHRONOUS_IO);
EXPECT_EQ(-1, _POSIX_BARRIERS);
EXPECT_EQ(-1, _POSIX_MESSAGE_PASSING);
@@ -658,6 +658,7 @@
}
TEST(unistd, sysconf) {
+ VERIFY_SYSCONF_POSIX_VERSION(_SC_ADVISORY_INFO);
VERIFY_SYSCONF_POSITIVE(_SC_ARG_MAX);
VERIFY_SYSCONF_POSITIVE(_SC_BC_BASE_MAX);
VERIFY_SYSCONF_POSITIVE(_SC_BC_DIM_MAX);
@@ -773,7 +774,6 @@
#if defined(__BIONIC__)
// Tests can only run on bionic, as bionic and glibc have different support for these options.
// Below options are not supported on bionic yet.
- VERIFY_SYSCONF_NOT_SUPPORT(_SC_ADVISORY_INFO);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_ASYNCHRONOUS_IO);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_BARRIERS);
VERIFY_SYSCONF_NOT_SUPPORT(_SC_MESSAGE_PASSING);
diff --git a/tests/utmp_test.cpp b/tests/utmp_test.cpp
new file mode 100644
index 0000000..b61110d
--- /dev/null
+++ b/tests/utmp_test.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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 <utmp.h>
+
+TEST(utmp, login_tty) {
+ // login_tty is tested indirectly by the openpty and forkpty tests.
+ // This test just checks that we're exporting the symbol independently.
+ ASSERT_EQ(-1, login_tty(-1));
+}