#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>

int
main (void)
{
  char *data, *data2, *data3;
  int i, pagesize;
  int fd;

  pagesize = getpagesize ();

  /* First, make a file with some known garbage in it. */
printf("malloc data1\n"); (void)getchar();
  data = (char *) malloc (pagesize);
  if (!data)
    exit (1);
  for (i = 0; i < pagesize; ++i)
    *(data + i) = rand ();
  umask (0);
  fd = creat ("work", 0600);
  if (fd < 0)
    exit (1);
  if (write (fd, data, pagesize) != pagesize)
    exit (1);
  close (fd);

  /* Next, try to mmap the file at a fixed address which already has
     something else allocated at it.  If we can, also make sure that
     we see the same garbage.  */
  fd = open ("work", O_RDWR);
  if (fd < 0)
    exit (1);
printf("malloc data2\n"); (void)getchar();
  data2 = (char *) malloc (2 * pagesize);
  if (!data2)
    exit (1);
printf("data2: %p --> ", data2);
  data2 += (pagesize - ((long) data2 & (pagesize - 1))) & (pagesize - 1);
printf("%p\n", data2); (void)getchar();
printf("mmap to data2\n"); (void)getchar();
  if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
		     MAP_PRIVATE | MAP_FIXED, fd, 0L))
    exit (1);
printf("read from data2\n"); (void)getchar();
  for (i = 0; i < pagesize; ++i)
    if (*(data + i) != *(data2 + i))
      exit (1);

  /* Finally, make sure that changes to the mapped area do not
     percolate back to the file as seen by read().  (This is a bug on
     some variants of i386 svr4.0.)  */
printf("write to data2\n"); (void)getchar();
  for (i = 0; i < pagesize; ++i)
    *(data2 + i) = *(data2 + i) + 1;
printf("malloc data3\n"); (void)getchar();
  data3 = (char *) malloc (pagesize);
  if (!data3)
    exit (1);
printf("read from mapped file\n"); (void)getchar();
  if (read (fd, data3, pagesize) != pagesize)
    exit (1);
  for (i = 0; i < pagesize; ++i)
    if (*(data + i) != *(data3 + i))
      exit (1);
  close (fd);
  exit (0);
}