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));
}
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);
}