#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#define PSIZE 4096

char obuf[] = "foo";
char obuf2[] = "bar";
char ebuf[PSIZE];
char ibuf[sizeof(obuf)];

int
main(int argc, char **argv)
{
    int fd;
    char *cp;

    if (argc != 2)
	errx(1, "<tmpfile>");

    /* setup test file */
    fd = open(argv[1], O_RDWR|O_CREAT|O_TRUNC, 0666);
    if (fd < 0)
	err(1, "open");
    if (write(fd, ebuf, sizeof(ebuf)) < 0)
	err(1, "write");

    /* write via vm */
    cp = mmap(0, sizeof(obuf), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if (cp == (caddr_t)-1)
	err(1, "mmap");
    strcpy(cp, obuf);
    printf("wrote: %s\n", obuf);

    /* read via vm */
    printf("mmap sez: %s\n", cp);

    /* read via buffer-cache */
    if (lseek(fd, 0, SEEK_SET) < 0)
	err(1, "lseek");
    if (read(fd, ibuf, sizeof(ibuf)) < 0)
	err(1, "read");
    printf("read before sync sez: %s\n", ibuf);

    /* sync */
    if (msync(cp, sizeof(obuf), MS_SYNC) < 0)
	err(1, "msync");

    /* read via buffer-cache again */
    if (lseek(fd, 0, SEEK_SET) < 0)
	err(1, "lseek");
    if (read(fd, ibuf, sizeof(ibuf)) < 0)
	err(1, "read");
    printf("read after sync sez: %s\n", ibuf);

    printf("\n");



    /* write via buffer-cache */
    if (lseek(fd, 0, SEEK_SET) < 0)
	err(1, "lseek");
    if (write(fd, obuf2, sizeof(obuf2)) < 0)
	err(1, "read");
    printf("wrote: %s\n", obuf2);

    /* read via buffer-cache */
    if (lseek(fd, 0, SEEK_SET) < 0)
	err(1, "lseek");
    if (read(fd, ibuf, sizeof(ibuf)) < 0)
	err(1, "read");
    printf("read sez: %s\n", ibuf);
    
    /* read via vm */
    printf("mmap before sync sez: %s\n", cp);

    /* sync */
    if (msync(cp, sizeof(obuf), MS_SYNC) < 0)
	err(1, "msync");

    /* read via vm again */
    printf("mmap after sync sez: %s\n", cp);


    /* cleanup */
    if (unlink(argv[1]) < 0)
	err(1, "unlink");
}
