aboutsummaryrefslogtreecommitdiffstats
path: root/src/tests/vm/mmap-clean.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/vm/mmap-clean.c')
-rw-r--r--src/tests/vm/mmap-clean.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/tests/vm/mmap-clean.c b/src/tests/vm/mmap-clean.c
new file mode 100644
index 0000000..ea1dc9c
--- /dev/null
+++ b/src/tests/vm/mmap-clean.c
@@ -0,0 +1,53 @@
+/* Verifies that mmap'd regions are only written back on munmap
+ if the data was actually modified in memory. */
+
+#include <string.h>
+#include <syscall.h>
+#include "tests/vm/sample.inc"
+#include "tests/lib.h"
+#include "tests/main.h"
+
+void
+test_main (void)
+{
+ static const char overwrite[] = "Now is the time for all good...";
+ static char buffer[sizeof sample - 1];
+ char *actual = (char *) 0x54321000;
+ int handle;
+ mapid_t map;
+
+ /* Open file, map, verify data. */
+ CHECK ((handle = open ("sample.txt")) > 1, "open \"sample.txt\"");
+ CHECK ((map = mmap (handle, actual)) != MAP_FAILED, "mmap \"sample.txt\"");
+ if (memcmp (actual, sample, strlen (sample)))
+ fail ("read of mmap'd file reported bad data");
+
+ /* Modify file. */
+ CHECK (write (handle, overwrite, strlen (overwrite))
+ == (int) strlen (overwrite),
+ "write \"sample.txt\"");
+
+ /* Close mapping. Data should not be written back, because we
+ didn't modify it via the mapping. */
+ msg ("munmap \"sample.txt\"");
+ munmap (map);
+
+ /* Read file back. */
+ msg ("seek \"sample.txt\"");
+ seek (handle, 0);
+ CHECK (read (handle, buffer, sizeof buffer) == sizeof buffer,
+ "read \"sample.txt\"");
+
+ /* Verify that file overwrite worked. */
+ if (memcmp (buffer, overwrite, strlen (overwrite))
+ || memcmp (buffer + strlen (overwrite), sample + strlen (overwrite),
+ strlen (sample) - strlen (overwrite)))
+ {
+ if (!memcmp (buffer, sample, strlen (sample)))
+ fail ("munmap wrote back clean page");
+ else
+ fail ("read surprising data from file");
+ }
+ else
+ msg ("file change was retained after munmap");
+}