Prevent the madvise(MADV_MERGEABLE) mmap hack from affecting errno.

Bug: 9889616
Change-Id: I4a7323e0ae5aeb5cbe0da1b2bc7501d83b3a2aa4
diff --git a/libc/Android.mk b/libc/Android.mk
index 0e93acd..38678f5 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -106,7 +106,6 @@
 	bionic/md5.c \
 	bionic/memmem.c \
 	bionic/memswap.c \
-	bionic/mmap.c \
 	bionic/openat.c \
 	bionic/open.c \
 	bionic/pathconf.c \
@@ -200,6 +199,7 @@
     bionic/__memcpy_chk.cpp \
     bionic/__memmove_chk.cpp \
     bionic/__memset_chk.cpp \
+    bionic/mmap.cpp \
     bionic/pthread_attr.cpp \
     bionic/pthread_detach.cpp \
     bionic/pthread_equal.cpp \
diff --git a/libc/bionic/mmap.c b/libc/bionic/mmap.cpp
similarity index 69%
rename from libc/bionic/mmap.c
rename to libc/bionic/mmap.cpp
index e097086..864dea2 100644
--- a/libc/bionic/mmap.c
+++ b/libc/bionic/mmap.cpp
@@ -25,26 +25,30 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
-#include <unistd.h>
+
 #include <errno.h>
 #include <sys/mman.h>
+#include <unistd.h>
 
-extern void*  __mmap2(void*, size_t, int, int, int, size_t);
+#include "private/ErrnoRestorer.h"
 
-#define  MMAP2_SHIFT  12
-void* mmap(void *addr, size_t size, int prot, int flags, int fd, long offset)
-{
-    void *ret;
+// mmap2(2) is like mmap(2), but the offset is in 4096-byte blocks, not bytes.
+extern "C" void*  __mmap2(void*, size_t, int, int, int, size_t);
 
-    if (offset & ((1UL << MMAP2_SHIFT)-1)) {
-        errno = EINVAL;
-        return MAP_FAILED;
-    }
+#define MMAP2_SHIFT 12 // 2**12 == 4096
 
-    ret = __mmap2(addr, size, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT);
+void* mmap(void* addr, size_t size, int prot, int flags, int fd, long offset) {
+  if (offset & ((1UL << MMAP2_SHIFT)-1)) {
+    errno = EINVAL;
+    return MAP_FAILED;
+  }
 
-    if (ret && (flags & (MAP_PRIVATE | MAP_ANONYMOUS)))
-	    madvise(ret, size, MADV_MERGEABLE);
+  void* result = __mmap2(addr, size, prot, flags, fd, offset >> MMAP2_SHIFT);
 
-    return ret;
+  if (result != MAP_FAILED && (flags & (MAP_PRIVATE | MAP_ANONYMOUS)) != 0) {
+    ErrnoRestorer errno_restorer;
+    madvise(result, size, MADV_MERGEABLE);
+  }
+
+  return result;
 }