Merge "Get the full set of PRNG functions in <stdlib.h>"
diff --git a/benchmarks/benchmark_main.cpp b/benchmarks/benchmark_main.cpp
index cd80968..d60670b 100644
--- a/benchmarks/benchmark_main.cpp
+++ b/benchmarks/benchmark_main.cpp
@@ -32,7 +32,7 @@
typedef std::map<std::string, ::testing::Benchmark*> BenchmarkMap;
typedef BenchmarkMap::iterator BenchmarkMapIt;
static BenchmarkMap g_benchmarks;
-static size_t g_name_column_width = 20;
+static int g_name_column_width = 20;
static int Round(int n) {
int base = 1;
@@ -196,7 +196,8 @@
}
for (BenchmarkMapIt it = g_benchmarks.begin(); it != g_benchmarks.end(); ++it) {
- g_name_column_width = std::max(g_name_column_width, strlen(it->second->Name()));
+ int name_width = static_cast<int>(strlen(it->second->Name()));
+ g_name_column_width = std::max(g_name_column_width, name_width);
}
bool need_header = true;
diff --git a/libc/Android.mk b/libc/Android.mk
index 30e6419..e3fb2a1 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -421,7 +421,6 @@
upstream-openbsd/lib/libc/stdio/putc.c \
upstream-openbsd/lib/libc/stdio/putchar.c \
upstream-openbsd/lib/libc/stdio/puts.c \
- upstream-openbsd/lib/libc/stdio/putw.c \
upstream-openbsd/lib/libc/stdio/putwc.c \
upstream-openbsd/lib/libc/stdio/putwchar.c \
upstream-openbsd/lib/libc/stdio/refill.c \
diff --git a/libc/arch-arm/arm.mk b/libc/arch-arm/arm.mk
index 7c423ab..260d72e 100644
--- a/libc/arch-arm/arm.mk
+++ b/libc/arch-arm/arm.mk
@@ -5,6 +5,7 @@
bionic/legacy_32_bit_support.cpp \
bionic/ndk_cruft.cpp \
bionic/time64.c \
+ upstream-openbsd/lib/libc/stdio/putw.c \
# These are shared by all the 32-bit targets, but not the 64-bit ones.
libc_bionic_src_files_arm := \
diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk
index 64b0fb2..c964e67 100644
--- a/libc/arch-mips/mips.mk
+++ b/libc/arch-mips/mips.mk
@@ -5,6 +5,7 @@
bionic/legacy_32_bit_support.cpp \
bionic/ndk_cruft.cpp \
bionic/time64.c \
+ upstream-openbsd/lib/libc/stdio/putw.c \
# These are shared by all the 32-bit targets, but not the 64-bit ones.
libc_bionic_src_files_mips += \
diff --git a/libc/arch-x86/x86.mk b/libc/arch-x86/x86.mk
index 0f22169..3dc71d1 100644
--- a/libc/arch-x86/x86.mk
+++ b/libc/arch-x86/x86.mk
@@ -5,6 +5,7 @@
bionic/legacy_32_bit_support.cpp \
bionic/ndk_cruft.cpp \
bionic/time64.c \
+ upstream-openbsd/lib/libc/stdio/putw.c \
# Fortify implementations of libc functions.
libc_common_src_files_x86 += \
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index efc5492..62acb3a 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -337,8 +337,6 @@
__printflike(2, 3);
char *fgetln(FILE * __restrict, size_t * __restrict);
int fpurge(FILE *);
-int getw(FILE *);
-int putw(int, FILE *);
void setbuffer(FILE *, char *, int);
int setlinebuf(FILE *);
int vasprintf(char ** __restrict, const char * __restrict,
diff --git a/tests/TemporaryFile.h b/tests/TemporaryFile.h
index a7b13b0..c4ee2d5 100644
--- a/tests/TemporaryFile.h
+++ b/tests/TemporaryFile.h
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <fcntl.h>
#include <unistd.h>
template<int (*mk_fn)(char*)>
@@ -39,6 +40,11 @@
unlink(filename);
}
+ void reopen() {
+ close(fd);
+ fd = open(filename, O_RDWR);
+ }
+
int fd;
char filename[1024];
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index e291f52..18dae9c 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -532,10 +532,6 @@
#endif
errno = 0;
- EXPECT_EQ(EOF, putw(1234, fp));
- EXPECT_EQ(EBADF, errno);
-
- errno = 0;
EXPECT_EQ(0U, fwrite("hello", 1, 2, fp));
EXPECT_EQ(EBADF, errno);
diff --git a/tests/sys_mman_test.cpp b/tests/sys_mman_test.cpp
index 6ac279f..75ccfa3 100644
--- a/tests/sys_mman_test.cpp
+++ b/tests/sys_mman_test.cpp
@@ -17,14 +17,158 @@
#include <gtest/gtest.h>
#include <sys/mman.h>
+#include <sys/types.h>
#include <unistd.h>
-TEST(sys_mman, mmap_negative) {
- off_t off = -sysconf(_SC_PAGE_SIZE); // Aligned but negative.
- ASSERT_EQ(MAP_FAILED, mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, off));
+#include "TemporaryFile.h"
+
+TEST(sys_mman, mmap_std) {
+ void* map = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ ASSERT_NE(MAP_FAILED, map);
+ ASSERT_EQ(0, munmap(map, 4096));
}
-TEST(sys_mman, mmap64_negative) {
- off64_t off64 = -sysconf(_SC_PAGE_SIZE); // Aligned but negative.
- ASSERT_EQ(MAP_FAILED, mmap64(NULL, 4096, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, off64));
+TEST(sys_mman, mmap64_std) {
+ void* map = mmap64(NULL, 4096, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ ASSERT_NE(MAP_FAILED, map);
+ ASSERT_EQ(0, munmap(map, 4096));
+}
+
+TEST(sys_mman, mmap_file_bad_offset) {
+ TemporaryFile tf;
+
+ void* map = mmap(NULL, 100, PROT_READ, MAP_SHARED, tf.fd, 1);
+ ASSERT_EQ(MAP_FAILED, map);
+}
+
+TEST(sys_mman, mmap64_file_bad_offset) {
+ TemporaryFile tf;
+
+ void* map = mmap64(NULL, 100, PROT_READ, MAP_SHARED, tf.fd, 1);
+ ASSERT_EQ(MAP_FAILED, map);
+}
+
+#define STR_SSIZE(str) static_cast<ssize_t>(sizeof(str))
+
+#define STRING_MSG "012345678\nabcdefgh\n"
+#define INITIAL_MSG "000000000\n00000000\n"
+
+TEST(sys_mman, mmap_file_read) {
+ TemporaryFile tf;
+
+ ASSERT_EQ(STR_SSIZE(STRING_MSG), write(tf.fd, STRING_MSG, sizeof(STRING_MSG)));
+
+ void* map = mmap(NULL, sizeof(STRING_MSG), PROT_READ, MAP_SHARED, tf.fd, 0);
+ ASSERT_NE(MAP_FAILED, map);
+
+ char* data = reinterpret_cast<char*>(map);
+ ASSERT_STREQ(STRING_MSG, data);
+
+ ASSERT_EQ(0, munmap(map, sizeof(STRING_MSG)));
+}
+
+TEST(sys_mman, mmap_file_write) {
+ TemporaryFile tf;
+
+ ASSERT_EQ(STR_SSIZE(INITIAL_MSG), write(tf.fd, INITIAL_MSG, sizeof(INITIAL_MSG)));
+ lseek(tf.fd, 0, SEEK_SET);
+
+ void* map = mmap(NULL, sizeof(STRING_MSG), PROT_WRITE, MAP_SHARED, tf.fd, 0);
+ ASSERT_NE(MAP_FAILED, map);
+ close(tf.fd);
+
+ memcpy(map, STRING_MSG, sizeof(STRING_MSG));
+
+ ASSERT_EQ(0, munmap(map, sizeof(STRING_MSG)));
+
+ tf.reopen();
+ char buf[sizeof(STRING_MSG)];
+ memset(buf, 0, sizeof(STRING_MSG));
+ ASSERT_EQ(STR_SSIZE(STRING_MSG), read(tf.fd, buf, sizeof(STRING_MSG)));
+
+ ASSERT_STREQ(STRING_MSG, buf);
+}
+
+#define PAGE0_MSG "00PAGE00"
+#define PAGE1_MSG "111PAGE111"
+#define PAGE2_MSG "2222PAGE2222"
+#define END_MSG "E"
+
+TEST(sys_mman, mmap_file_read_at_offset) {
+ TemporaryFile tf;
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+
+ // Create the file with three pages worth of data.
+ ASSERT_EQ(STR_SSIZE(PAGE0_MSG), write(tf.fd, PAGE0_MSG, sizeof(PAGE0_MSG)));
+ ASSERT_NE(-1, lseek(tf.fd, pagesize, SEEK_SET));
+ ASSERT_EQ(STR_SSIZE(PAGE1_MSG), write(tf.fd, PAGE1_MSG, sizeof(PAGE1_MSG)));
+ ASSERT_NE(-1, lseek(tf.fd, 2 * pagesize, SEEK_SET));
+ ASSERT_EQ(STR_SSIZE(PAGE2_MSG), write(tf.fd, PAGE2_MSG, sizeof(PAGE2_MSG)));
+ ASSERT_NE(-1, lseek(tf.fd, 3 * pagesize - sizeof(END_MSG), SEEK_SET));
+ ASSERT_EQ(STR_SSIZE(END_MSG), write(tf.fd, END_MSG, sizeof(END_MSG)));
+
+ ASSERT_NE(-1, lseek(tf.fd, 0, SEEK_SET));
+
+ void* map = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, tf.fd, pagesize);
+ ASSERT_NE(MAP_FAILED, map);
+
+ char* data = reinterpret_cast<char*>(map);
+ ASSERT_STREQ(PAGE1_MSG, data);
+
+ ASSERT_EQ(0, munmap(map, pagesize));
+
+ map = mmap(NULL, pagesize, PROT_READ, MAP_SHARED, tf.fd, 2 * pagesize);
+ ASSERT_NE(MAP_FAILED, map);
+
+ data = reinterpret_cast<char*>(map);
+ ASSERT_STREQ(PAGE2_MSG, data);
+ ASSERT_STREQ(END_MSG, data+pagesize-sizeof(END_MSG));
+
+ ASSERT_EQ(0, munmap(map, pagesize));
+}
+
+#define NEWPAGE1_MSG "1NEW1PAGE1"
+#define NEWPAGE2_MSG "22NEW22PAGE22"
+
+TEST(sys_mman, mmap_file_write_at_offset) {
+ TemporaryFile tf;
+ size_t pagesize = sysconf(_SC_PAGESIZE);
+
+ // Create the file with three pages worth of data.
+ ASSERT_EQ(STR_SSIZE(PAGE0_MSG), write(tf.fd, PAGE0_MSG, sizeof(PAGE0_MSG)));
+ ASSERT_NE(-1, lseek(tf.fd, pagesize, SEEK_SET));
+ ASSERT_EQ(STR_SSIZE(PAGE1_MSG), write(tf.fd, PAGE1_MSG, sizeof(PAGE1_MSG)));
+ ASSERT_NE(-1, lseek(tf.fd, 2 * pagesize, SEEK_SET));
+ ASSERT_EQ(STR_SSIZE(PAGE2_MSG), write(tf.fd, PAGE2_MSG, sizeof(PAGE2_MSG)));
+ ASSERT_NE(-1, lseek(tf.fd, 3 * pagesize - sizeof(END_MSG), SEEK_SET));
+ ASSERT_EQ(STR_SSIZE(END_MSG), write(tf.fd, END_MSG, sizeof(END_MSG)));
+
+ ASSERT_NE(-1, lseek(tf.fd, 0, SEEK_SET));
+
+ void* map = mmap(NULL, pagesize, PROT_WRITE, MAP_SHARED, tf.fd, pagesize);
+ ASSERT_NE(MAP_FAILED, map);
+ close(tf.fd);
+
+ memcpy(map, NEWPAGE1_MSG, sizeof(NEWPAGE1_MSG));
+ ASSERT_EQ(0, munmap(map, pagesize));
+
+ tf.reopen();
+ map = mmap(NULL, pagesize, PROT_WRITE, MAP_SHARED, tf.fd, 2 * pagesize);
+ ASSERT_NE(MAP_FAILED, map);
+ close(tf.fd);
+
+ memcpy(map, NEWPAGE2_MSG, sizeof(NEWPAGE2_MSG));
+ ASSERT_EQ(0, munmap(map, pagesize));
+
+ tf.reopen();
+ char buf[pagesize];
+ ASSERT_EQ(static_cast<ssize_t>(pagesize), read(tf.fd, buf, pagesize));
+ ASSERT_STREQ(PAGE0_MSG, buf);
+ ASSERT_NE(-1, lseek(tf.fd, pagesize, SEEK_SET));
+ ASSERT_EQ(static_cast<ssize_t>(pagesize), read(tf.fd, buf, pagesize));
+ ASSERT_STREQ(NEWPAGE1_MSG, buf);
+ ASSERT_NE(-1, lseek(tf.fd, 2 * pagesize, SEEK_SET));
+ ASSERT_EQ(static_cast<ssize_t>(pagesize), read(tf.fd, buf, pagesize));
+ ASSERT_STREQ(NEWPAGE2_MSG, buf);
+ ASSERT_STREQ(END_MSG, buf+pagesize-sizeof(END_MSG));
}