/* 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");
}
