Merge "Proper MB_CUR_MAX." into lmp-dev
diff --git a/libc/Android.mk b/libc/Android.mk
index 46c9676..2007965 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -226,7 +226,6 @@
bionic/unlink.cpp \
bionic/utimes.cpp \
bionic/vdso.cpp \
- bionic/vfork.cpp \
bionic/wait.cpp \
bionic/wchar.cpp \
bionic/wctype.cpp \
diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT
index 128ec6b..38ae831 100644
--- a/libc/SYSCALLS.TXT
+++ b/libc/SYSCALLS.TXT
@@ -77,6 +77,7 @@
int setgroups:setgroups32(int, const gid_t*) arm,x86
int setgroups:setgroups(int, const gid_t*) arm64,mips,mips64,x86_64
int setpgid(pid_t, pid_t) all
+pid_t vfork(void) arm
int setregid:setregid32(gid_t, gid_t) arm,x86
int setregid:setregid(gid_t, gid_t) arm64,mips,mips64,x86_64
int chroot(const char*) all
diff --git a/libc/arch-arm/syscalls/vfork.S b/libc/arch-arm/syscalls/vfork.S
new file mode 100644
index 0000000..e12fba5
--- /dev/null
+++ b/libc/arch-arm/syscalls/vfork.S
@@ -0,0 +1,14 @@
+/* Generated by gensyscalls.py. Do not edit. */
+
+#include <private/bionic_asm.h>
+
+ENTRY(vfork)
+ mov ip, r7
+ ldr r7, =__NR_vfork
+ swi #0
+ mov r7, ip
+ cmn r0, #(MAX_ERRNO + 1)
+ bxls lr
+ neg r0, r0
+ b __set_errno
+END(vfork)
diff --git a/libc/arch-arm64/arm64.mk b/libc/arch-arm64/arm64.mk
index 314358e..ed991ce 100644
--- a/libc/arch-arm64/arm64.mk
+++ b/libc/arch-arm64/arm64.mk
@@ -36,6 +36,7 @@
arch-arm64/bionic/__set_tls.c \
arch-arm64/bionic/sigsetjmp.S \
arch-arm64/bionic/syscall.S \
+ arch-arm64/bionic/vfork.S \
libc_crt_target_cflags_arm64 := \
diff --git a/libc/bionic/vfork.cpp b/libc/arch-arm64/bionic/vfork.S
similarity index 75%
rename from libc/bionic/vfork.cpp
rename to libc/arch-arm64/bionic/vfork.S
index b706a7f..c700623 100644
--- a/libc/bionic/vfork.cpp
+++ b/libc/arch-arm64/bionic/vfork.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,10 +26,23 @@
* SUCH DAMAGE.
*/
-#include <unistd.h>
+#include <private/bionic_asm.h>
+#include <asm/signal.h>
+#include <linux/sched.h>
-// vfork(2) was removed from POSIX 2008, but it's common enough that we can't
-// actually remove it entirely.
-extern "C" pid_t vfork(void) {
- return fork();
-}
+ENTRY(vfork)
+ mov x0, #(CLONE_VM | CLONE_VFORK | SIGCHLD)
+ mov x1, xzr
+ mov x2, xzr
+ mov x3, xzr
+ mov x4, xzr
+
+ mov x8, __NR_clone
+ svc #0
+
+ cmn x0, #(MAX_ERRNO + 1)
+ cneg x0, x0, hi
+ b.hi __set_errno
+
+ ret
+END(vfork)
diff --git a/libc/bionic/vfork.cpp b/libc/arch-mips/bionic/vfork.S
similarity index 72%
copy from libc/bionic/vfork.cpp
copy to libc/arch-mips/bionic/vfork.S
index b706a7f..96de69e 100644
--- a/libc/bionic/vfork.cpp
+++ b/libc/arch-mips/bionic/vfork.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,10 +26,33 @@
* SUCH DAMAGE.
*/
-#include <unistd.h>
+#include <private/bionic_asm.h>
+#include <linux/sched.h>
-// vfork(2) was removed from POSIX 2008, but it's common enough that we can't
-// actually remove it entirely.
-extern "C" pid_t vfork(void) {
- return fork();
-}
+// TODO: mips' uapi signal.h is missing #ifndef __ASSEMBLY__.
+// #include <asm/signal.h>
+#define SIGCHLD 18
+
+ENTRY(vfork)
+ .set noreorder
+ .cpload t9
+
+ li a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
+ li a1, 0
+ li a2, 0
+ li a3, 0
+ subu sp, 8
+ sw $0, 16(sp)
+ li v0, __NR_clone
+ syscall
+ addu sp, 8
+ bnez a3, 1f
+ move a0, v0
+
+ j ra
+ nop
+1:
+ la t9, __set_errno
+ j t9
+ nop
+END(vfork)
diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk
index bf3b8ae..8e415f9 100644
--- a/libc/arch-mips/mips.mk
+++ b/libc/arch-mips/mips.mk
@@ -59,6 +59,7 @@
arch-mips/bionic/setjmp.S \
arch-mips/bionic/sigsetjmp.S \
arch-mips/bionic/syscall.S \
+ arch-mips/bionic/vfork.S \
ifndef ARCH_MIPS_REV6
libc_bionic_src_files_mips += \
diff --git a/libc/bionic/vfork.cpp b/libc/arch-mips64/bionic/vfork.S
similarity index 62%
copy from libc/bionic/vfork.cpp
copy to libc/arch-mips64/bionic/vfork.S
index b706a7f..911a264 100644
--- a/libc/bionic/vfork.cpp
+++ b/libc/arch-mips64/bionic/vfork.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,10 +26,46 @@
* SUCH DAMAGE.
*/
-#include <unistd.h>
+#include <private/bionic_asm.h>
+#include <linux/sched.h>
-// vfork(2) was removed from POSIX 2008, but it's common enough that we can't
-// actually remove it entirely.
-extern "C" pid_t vfork(void) {
- return fork();
-}
+// TODO: mips' uapi signal.h is missing #ifndef __ASSEMBLY__.
+// #include <asm/signal.h>
+#define SIGCHLD 18
+
+ .text
+
+#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
+FRAMESZ = MKFSIZ(5,0)
+#else
+FRAMESZ = MKFSIZ(0,0)
+#endif
+
+LEAF(vfork,FRAMESZ)
+#if FRAMESZ!=0
+ PTR_SUBU sp, FRAMESZ
+#endif
+ SETUP_GP64(a5, vfork)
+ LI a0, (CLONE_VM | CLONE_VFORK | SIGCHLD)
+ move a1, $0
+ move a2, $0
+ move a3, $0
+#if (_MIPS_SIM == _ABIO32) || (_MIPS_SIM == _ABI32)
+ REG_S $0, 4*REGSZ(sp)
+#else
+ move a4, $0
+#endif
+ LI v0, __NR_clone
+ syscall
+#if FRAMESZ!=0
+ PTR_ADDU sp,FRAMESZ
+#endif
+ move a0, v0
+ bnez a3, 1f
+ RESTORE_GP64
+ j ra
+1:
+ LA t9,__set_errno
+ RESTORE_GP64
+ j t9
+ END(vfork)
diff --git a/libc/arch-mips64/mips64.mk b/libc/arch-mips64/mips64.mk
index 6f7a928..230cb26 100644
--- a/libc/arch-mips64/mips64.mk
+++ b/libc/arch-mips64/mips64.mk
@@ -46,6 +46,7 @@
arch-mips64/bionic/setjmp.S \
arch-mips64/bionic/sigsetjmp.S \
arch-mips64/bionic/syscall.S \
+ arch-mips64/bionic/vfork.S \
# FIXME TODO
## libc_bionic_src_files_mips64 += arch-mips64/string/memcpy.S
diff --git a/libc/bionic/vfork.cpp b/libc/arch-x86/bionic/vfork.S
similarity index 75%
copy from libc/bionic/vfork.cpp
copy to libc/arch-x86/bionic/vfork.S
index b706a7f..ffa6b16 100644
--- a/libc/bionic/vfork.cpp
+++ b/libc/arch-x86/bionic/vfork.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2008 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,10 +26,19 @@
* SUCH DAMAGE.
*/
-#include <unistd.h>
+#include <private/bionic_asm.h>
-// vfork(2) was removed from POSIX 2008, but it's common enough that we can't
-// actually remove it entirely.
-extern "C" pid_t vfork(void) {
- return fork();
-}
+// This custom code preserves the return address across the system call.
+
+ENTRY(vfork)
+ popl %ecx // Grab the return address.
+ movl $__NR_vfork, %eax
+ int $0x80
+ cmpl $-MAX_ERRNO, %eax
+ jb 1f
+ negl %eax
+ pushl %eax
+ call __set_errno
+1:
+ jmp *%ecx // Jump to the stored return address.
+END(vfork)
diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk
index 8aa2645..019dc8e 100644
--- a/libc/arch-x86/x86.mk
+++ b/libc/arch-x86/x86.mk
@@ -31,6 +31,7 @@
arch-x86/bionic/__set_tls.c \
arch-x86/bionic/sigsetjmp.S \
arch-x86/bionic/syscall.S \
+ arch-x86/bionic/vfork.S \
## ARCH variant specific source files
arch_variant_mk := $(LOCAL_PATH)/arch-x86/$(TARGET_ARCH_VARIANT)/$(TARGET_ARCH_VARIANT).mk
diff --git a/libc/bionic/vfork.cpp b/libc/arch-x86_64/bionic/vfork.S
similarity index 75%
copy from libc/bionic/vfork.cpp
copy to libc/arch-x86_64/bionic/vfork.S
index b706a7f..7c14cc0 100644
--- a/libc/bionic/vfork.cpp
+++ b/libc/arch-x86_64/bionic/vfork.S
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (C) 2013 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,10 +26,20 @@
* SUCH DAMAGE.
*/
-#include <unistd.h>
+#include <private/bionic_asm.h>
-// vfork(2) was removed from POSIX 2008, but it's common enough that we can't
-// actually remove it entirely.
-extern "C" pid_t vfork(void) {
- return fork();
-}
+// This custom code preserves the return address across the system call.
+
+ENTRY(vfork)
+ popq %rdi // Grab the return address.
+ movl $__NR_vfork, %eax
+ syscall
+ pushq %rdi // Restore the return address.
+ cmpq $-MAX_ERRNO, %rax
+ jb 1f
+ negl %eax
+ movl %eax, %edi
+ call __set_errno
+1:
+ ret
+END(vfork)
diff --git a/libc/arch-x86_64/x86_64.mk b/libc/arch-x86_64/x86_64.mk
index 234cf67..7887c51 100644
--- a/libc/arch-x86_64/x86_64.mk
+++ b/libc/arch-x86_64/x86_64.mk
@@ -37,6 +37,7 @@
arch-x86_64/bionic/__set_tls.c \
arch-x86_64/bionic/sigsetjmp.S \
arch-x86_64/bionic/syscall.S \
+ arch-x86_64/bionic/vfork.S \
libc_bionic_src_files_x86_64 += \
arch-x86_64/string/sse2-memcpy-slm.S \
diff --git a/libc/bionic/wchar.cpp b/libc/bionic/wchar.cpp
index 438ce03..524ba07 100644
--- a/libc/bionic/wchar.cpp
+++ b/libc/bionic/wchar.cpp
@@ -84,6 +84,7 @@
if (static_cast<uint8_t>((*src)[i]) < 0x80) {
// Fast path for plain ASCII characters.
if ((*src)[i] == '\0') {
+ *src = nullptr;
return reset_and_return(o, state);
}
r = 1;
@@ -96,6 +97,7 @@
return reset_and_return_illegal(EILSEQ, state);
}
if (r == 0) {
+ *src = nullptr;
return reset_and_return(o, state);
}
}
@@ -118,7 +120,8 @@
dst[o] = (*src)[i];
r = 1;
if ((*src)[i] == '\0') {
- break;
+ *src = nullptr;
+ return reset_and_return(o, state);
}
} else {
r = mbrtowc(dst + o, *src + i, nmc - i, state);
diff --git a/tests/wchar_test.cpp b/tests/wchar_test.cpp
index f052ce6..d02c4bf 100644
--- a/tests/wchar_test.cpp
+++ b/tests/wchar_test.cpp
@@ -351,7 +351,7 @@
// Check that we didn't clobber the rest of out.
ASSERT_EQ(L'x', out[3]);
// Check that valid has advanced to the end of the string.
- ASSERT_EQ(L'\0', *valid);
+ ASSERT_EQ(nullptr, valid);
const char* invalid = "A" "\xc2\x20" "ef";
ASSERT_EQ(static_cast<size_t>(-1), mbsrtowcs(out, &invalid, 4, ps));